Trouble reading from 9DOF sensor stick
Saravanan
Posts: 19
I just bought a 9DOF Sensor Stick from sparkfun last week(https://www.sparkfun.com/products/10724) . Since then I am trying to retrieve raw data from the sensors through the Propeller Activity Board. But I have been unsuccessful in my attempts.
I am wondering if propeller activity board could be not compatible with this sensor stick, as most of the experiments that I saw online uses Arduino micro-controller. Do kindly advice if there is any ways to interface propeller activity board with 9DOF sensor stick. If there is.... a sample code would be of great help . Thanks
I am wondering if propeller activity board could be not compatible with this sensor stick, as most of the experiments that I saw online uses Arduino micro-controller. Do kindly advice if there is any ways to interface propeller activity board with 9DOF sensor stick. If there is.... a sample code would be of great help . Thanks
Comments
#include "simpletools.h" // Include simple tools
#include "simplei2c.h"
#include "simpletools.h" // Include simple tools
#include "simplei2c.h"
#include "inttypes.h"
const char accread =0xA7;
const char accwrite =0xA6;
void Acc_setup(int ADCSbus, int Device_Addr)
{
unsigned char Read_back[]={0,0};
i2c_in(ADCSBus, Device_Addr,0x00,1,&Read_back,2);
print("Accel ID is: %x \n",Read_back[0]); //should be 0xE5
unsigned char regs[] = {0x00, 0x08};
i2c_out(ADCSbus,Device_Addr,0x2D,1,®s[0],2); //change from standby to measure mode
i2c_out(ADCSbus,Device_Addr,0x2D,1,®s[1],2); //write 0x2D
i2c_in(ADCSbus,Device_Addr,0x2D,1,&Read_back,2);
print("Read from reg 2d: %x \n",Read_back[0]); //to check if ox08 is written onto reg 0x2D
unsigned char reg2[] ={0x84};
i2c_out(ADCSbus,Device_Addr,0x38,1,®2[0],2); //change FIFO to stream and set D2 to 1
i2c_in(ADCSbus,Device_Addr,0x38,1,&Read_back,2); //0x84 should be written to reg0x38
print("Read from reg 38: %x \n",Read_back[0]);
}
int main() // Main function
{
i2c *ADCSbus = i2c_newbus(SCL, SDA, 0);
Acc_setup(ADCSbus,accAddr);
while(1)
{
uint16_t x16,y16,z16; //16 bit variables
uint8_t data[6];
int datReg =0x32;
i2c_in(ADCSBus, accread >>1 , datReg, 1, data, 6); // ******************************
x16 = (data[0] << 8) | data[1];
y16 = (data[2] << 8) | data[3];
z16 = (data[4] << 8) | data[5];
print("%cx=%d, y=%d, z=%d%c\n",HOME, x16, y16, z16, CLREOL);
}
}
This is the code that I used and I keep getting the same data when I run it on my propeller board.
The Output was : x=4096 y=48136 z=56839
Is there any error that I have made?
Might I suggest that you try and access each device one at a time until you know you are getting a good response from it? Also, at the beginning of your code you only need to include simpletools.h once which includes simplei2c.h within. Can you show us what is in inttypes.h?
#include "simpletools.h" // Include simple tools
const char accread =0x54;
const char accwrite =0x53;
i2c* ADCSBus;
const int SDA=4; // Chip SDA pin
const int SCL=3; // Chip SCL pin
void Acc_setup(int ADCSbus, int Device_Addr)
{
unsigned char Read_back[]={0,0};
i2c_in(ADCSBus, Device_Addr,0x00,1,&Read_back,2);
print("Accel ID is: %x \n",Read_back[0]); //should be 0xE5
unsigned char regs[] = {0x00, 0x08};
i2c_out(ADCSbus,Device_Addr,0x2D,1,®s[0],2); //change from standby to measure mode
i2c_out(ADCSbus,Device_Addr,0x2D,1,®s[1],2); //write 0x2D
i2c_in(ADCSbus,Device_Addr,0x2D,1,&Read_back,2);
print("Read from reg 2d: %x \n",Read_back[0]); //to check if ox08 is written onto reg 0x2D
unsigned char reg2[] ={0x84};
i2c_out(ADCSbus,Device_Addr,0x38,1,®2[0],2); //change FIFO to stream and set D2 to 1
i2c_in(ADCSbus,Device_Addr,0x38,1,&Read_back,2); //0x84 should be written to reg0x38
print("Read from reg 38: %x \n",Read_back[0]);
}
int main() // Main function
{
i2c *ADCSbus = i2c_newbus(SCL, SDA, 0);
Acc_setup(ADCSbus,accAddr);
while(1)
{
uint16_t x16,y16,z16; //16 bit variables
uint8_t data[6];
int datReg =0x32;
i2c_in(ADCSBus, accread , datReg, 1, data, 6); // ******************************
x16 = (data[0] << 8) | data[1];
y16 = (data[2] << 8) | data[3];
z16 = (data[4] << 8) | data[5];
print("%cx=%d, y=%d, z=%d%c\n",HOME, x16, y16, z16, CLREOL);
}
}
What should be the address that I should send in as a second parameter of Acc_setup. I got this setup function from another thread stating that the mode has to be changed so as to produce proper output. Is the setup function necessary at all? Do let me know if there is any other errors too.
My suggestion would be to eliminate the second parameter and use the defined global constants accread and accwrite directly in each i2c_xxx call. Replace Device_Addr in each i2c_out call with accwrite and in i2c_in call use accread.
Something like this, for instance:
I also split up the i2c declaration with i2c *ADCSbus; outside of Main, and ADCSbus = i2c_newbus(SCL, SDA, 0); inside Main.
The below listing compiles without errors or warnings on my Simpleide.
I did not change the number of bytes to transfer in the I2C calls, I'll leave that up to you in case that is your intention.
The final code that you posted compiles without any warnings when I compile it too. But however I am still getting the same output as before. Output: " x=4096 y=48136 z=56839 "
I am wondering if this might be related to the type of declarations of the variables as the output is a nice number(4096=2^12). Is there any overflow of data or something? I am just thinking at it in this angle because all this while I am getting the same data for about a week. There might be some other faults in the code too.
This is the code that I modified from your previous post.
// i2c_in(ADCSbus, accread >>1 , datReg, 1, data, 6); // ******************************
with
memset(data, 0, 6);
Now, if you continue to get the same output as before then you are communicating with the device but probably have a configuration problem with ADXL345. If the output now remains at zero then you may have communication as well as configuration issues. You also may want to look into OBEX and try some of the SPIN objects for this device.
Just so I get this right, you would write a variable out to the device and then read the device back to the same variable? If that was the case, then reading from a non-responsive device would not change the variable.
It looks like a basic communications failure, the device is simply not responding. How is the board being powered? Per the schematic there should be a blue led near the center to one side. Is it on? Can you measure the voltage at SCL and SDA, is it near 3.3 Volts?
I hope this one will work out for you...
I got the magnetometer working too. I am however stuck on getting the gyroscope reading. I am not sure of what I should include in the gyroscope's setup function.
The output that I got is:
"gyros ID is : 7fec
Read from DLPF is : 89 "
I'm not quite sure what to make of you getting a two byte response from reg 0, which is one byte and should contain the I2C device address. Going to have to dig deeper into the datasheet and see if there are any quirks in their I2C protocol. I do see a problem with the i2c_out statement. Parameter 5, 0x19 in this case, is being treated as a pointer, so 0x19 is not being written to reg 22, but whatever 0x19 is pointing to. (Aren't pointers fun?) Instead, place the 0x19 into Read_back[0] and then use &Read_back[0] as parameter 5.
When I compiled the above code I got a warning message; NineDOFgyro.c:16:3: warning: passing argument 5 of 'i2c_out' makes pointer from integer without a cast [enabled by default].
It still compiles without errors, which are showstoppers, but a warning usually means that something is not going to behave as you might expect.