Trouble reading from 9DOF sensor stick
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:
#include "simpletools.h" // Include simple tools // #include "inttypes.h" // What is in here????? const char accread =0x54; const char accwrite =0x53; void Acc_setup(int ADCSbus) { unsigned char Read_back[]={0,0}; // place var definitions at top of function unsigned char regs[] = {0x00, 0x08}; unsigned char reg2[] = {0x84}; i2c_in(ADCSBus, accread, 0x00, 1, &Read_back, 2); print("Accel ID is: %x \n", Read_back[0]); //should be 0xE5 i2c_out(ADCSbus, accwrite, 0x2D, 1, ®s[0], 2); //change from standby to measure mode i2c_out(ADCSbus, accwrite, 0x2D, 1, ®s[1], 2); //write 0x2D i2c_in(ADCSbus, accread, 0x2D, 1, &Read_back, 2); print("Read from reg 2d: %x \n", Read_back[0]); //to check if ox08 is written onto reg 0x2D i2c_out(ADCSbus, accwrite, 0x38, 1, ®2[0], 2); //change FIFO to stream and set D2 to 1 i2c_in(ADCSbus, accread, 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 { uint16_t x16, y16, z16; // 16 bit variables uint8_t data[6]; int datReg = 0x32; i2c *ADCSbus = i2c_newbus(SCL, SDA, 0); Acc_setup(ADCSbus); while(1) { // i2c_in(ADCSBus, accread >>1 , datReg, 1, data, 6); // ****************************** i2c_in(ADCSBus, accread, datReg, 1, data, 6); // don't right shift accread if it is 7 bit 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); } }#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) { unsigned char Read_back[]={0,0}; // place var definitions at top of function unsigned char regs[] = {0x00, 0x08}; unsigned char reg2[] = {0x84}; i2c_in(ADCSBus, accread, 0x00, 1, &Read_back, 2); print("Accel ID is: %x \n", Read_back[0]); //should be 0xE5 i2c_out(ADCSbus, accwrite, 0x2D, 1, ®s[0], 2); //change from standby to measure mode i2c_out(ADCSbus, accwrite, 0x2D, 1, ®s[1], 2); //write 0x2D i2c_in(ADCSbus, accread, 0x2D, 1, &Read_back, 2); print("Read from reg 2d: %x \n", Read_back[0]); //to check if ox08 is written onto reg 0x2D i2c_out(ADCSbus, accwrite, 0x38, 1, ®2[0], 2); //change FIFO to stream and set D2 to 1 i2c_in(ADCSbus, accread, 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 { uint16_t x16, y16, z16; // 16 bit variables uint8_t data[6]; int datReg = 0x32; i2c *ADCSbus = i2c_newbus(SCL, SDA, 0); Acc_setup(ADCSbus); while(1) { // i2c_in(ADCSBus, accread >>1 , datReg, 1, data, 6); // ****************************** i2c_in(ADCSBus, accread, datReg, 1, data, 6); // don't right shift accread if it is 7 bit 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); } }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.
#include "simpletools.h" const char accread =0x54; const char accwrite =0x53; const char SCL = 0; // change to reflect actual pin used const char SDA = 1; // change to reflect actual pin used i2c *ADCSbus; void Acc_setup() { unsigned char Read_back[]={0,0}; // place var definitions at top of function unsigned char regs[] = {0x00, 0x08}; unsigned char reg2[] = {0x84}; i2c_in(ADCSbus, accread, 0x00, 1, Read_back, 2); // device register 0x00 is one byte, why read two? print("Accel ID is: %x \n", Read_back[0]); //should be 0xE5 // i2c_out(ADCSbus, accwrite, 0x2D, 1, ®s[0], 2); //change from standby to measure mode // Above statement writes 0x00 to 2D and 0x08 to 2E and changes nothing in 2D since it starts at 0x00 i2c_out(ADCSbus, accwrite, 0x2D, 1, ®s[1], 2); //write 0x2D i2c_in(ADCSbus, accread, 0x2D, 1, Read_back, 2); print("Read from reg 2d: %x \n", Read_back[0]); //to check if ox08 is written onto reg 0x2D i2c_out(ADCSbus, accwrite, 0x38, 1, ®2[0], 2); //change FIFO to stream and set D2 to 1 i2c_in(ADCSbus, accread, 0x38, 1, Read_back, 2); //0x84 should be written to reg0x38 print("Read from reg 38: %x \n", Read_back[0]); } /* * Is there a particular reason why you are writing two bytes to one byte registers in the device? This causes unintended data to be written to the register following the one you want to change! * The last parameter in the i2c statements is the number of bytes to transfer. */ int main() // Main function { uint16_t x16, y16, z16; //16 bit variables uint8_t data[6]; int datReg = 0x32; ADCSbus = i2c_newbus(SCL, SDA, 0); Acc_setup(); while(1) { // i2c_in(ADCSbus, accread >>1 , datReg, 1, data, 6); // ****************************** i2c_in(ADCSbus, accread, datReg, 1, data, 6); // don't right shift accread if it is 7 bit 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); } }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.
#include "simpletools.h" const char accread =0x54; const char accwrite =0x53; const char SCL = 3; // change to reflect actual pin used const char SDA = 4; // change to reflect actual pin used i2c *ADCSbus; void Acc_setup() { unsigned char Read_back[]={0,0}; // place var definitions at top of function unsigned char regs[] = {0x00, 0x08}; unsigned char reg2[] = {0x84}; i2c_in(ADCSbus, accread, 0x00, 1, Read_back, 1); // device register 0x00 is one byte, why read two? print("Accel ID is: %x \n", Read_back[0]); //should be 0xE5 // i2c_out(ADCSbus, accwrite, 0x2D, 1, ®s[0], 2); //change from standby to measure mode // Above statement writes 0x00 to 2D and 0x08 to 2E and changes nothing in 2D since it starts at 0x00 i2c_out(ADCSbus, accwrite, 0x2D, 1, ®s[1], 1); //write 0x2D i2c_in(ADCSbus, accread, 0x2D, 1, Read_back, 1); print("Read from reg 2d: %x \n", Read_back[0]); //to check if ox08 is written onto reg 0x2D i2c_out(ADCSbus, accwrite, 0x38, 1, ®2[0], 1); //change FIFO to stream and set D2 to 1 i2c_in(ADCSbus, accread, 0x38, 1, Read_back, 1); //0x84 should be written to reg0x38 print("Read from reg 38: %x \n", Read_back[0]); } int main() // Main function { uint16_t x16, y16, z16; //16 bit variables uint8_t data[6]; int datReg = 0x32; ADCSbus = i2c_newbus(SCL, SDA, 0); Acc_setup(ADCSbus); while(1) { // i2c_in(ADCSbus, accread >>1 , datReg, 1, data, 6); // ****************************** i2c_in(ADCSbus, accread, datReg, 1, data, 6); // don't right shift accread if it is 7 bit 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); } }// 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...
#include "simpletools.h" const char acc_addr = 0x53; const char SCL = 3; // change to reflect actual pin used const char SDA = 4; // change to reflect actual pin used i2c *ADCSbus; void Acc_setup() { unsigned char Read_back[]={0,0}; // place var definitions at top of function unsigned char regs[] = {0x00, 0x08}; unsigned char reg2[] = {0x84}; i2c_in(ADCSbus, acc_addr, 0x00, 1, Read_back, 1); // device register 0x00 is one byte, why read two? print("Accel ID is: %x \n", Read_back[0]); //should be 0xE5 i2c_out(ADCSbus, acc_addr, 0x2D, 1, ®s[1], 1); //write 0x2D i2c_in(ADCSbus, acc_addr, 0x2D, 1, Read_back, 1); print("Read from reg 2d: %x \n", Read_back[0]); //to check if ox08 is written onto reg 0x2D i2c_out(ADCSbus, acc_addr, 0x38, 1, ®2[0], 1); //change FIFO to stream and set D2 to 1 i2c_in(ADCSbus, acc_addr, 0x38, 1, Read_back, 1); //0x84 should be written to reg0x38 print("Read from reg 38: %x \n", Read_back[0]); } int main() // Main function { uint16_t x16, y16, z16; //16 bit variables uint8_t data[6]; int datReg = 0x32; ADCSbus = i2c_newbus(SCL, SDA, 0); Acc_setup(); while(1) { memset(data, 0, 6); i2c_in(ADCSbus, acc_addr, 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); } }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 "
#include "simpletools.h" // Include simple tools const char gyrosAddr = 0x68; const char SCL = 3; const char SDA = 4; i2c *ADCSbus; void Gyro_setup() { unsigned char Read_back[]={0,0}; unsigned char DLPF = 0x16; //Register 22- DLPF,FullScale i2c_in(ADCSbus,gyrosAddr,0x00,1,Read_back,1); //Test Device ID print("gyros ID is : %x \n",Read_back); i2c_out(ADCSbus,gyrosAddr,DLPF,1,0x19,1); //0x19 is written to set FS_SEL to proper opperation // DLPF_CFG to a random mode(1 in this case-I dono about this) i2c_in(ADCSbus,gyrosAddr,DLPF,1,Read_back,1); print("Read from DLPF is : %x \n",Read_back[0]); } int main() // Main function { uint16_t x16, y16, z16; //16 bit variables uint8_t data[6]; int datReg = 0x1D; ADCSbus = i2c_newbus(SCL, SDA, 0); Gyro_setup(); while(1) { memset(data, 0, 6); i2c_in(ADCSbus,gyrosAddr,datReg,1,data,6); x16 = (data[0] << 8) | data[1]; y16 = (data[2] << 8) | data[3]; z16 = (data[4] << 8) | data[5]; pause(100); print("%cx=%d, y=%d, z=%d%c\n",HOME, x16, y16, z16,CLREOL); } }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.