Sparkfun guys,
Similar to another post, I get only 0x00 from all the accelerometers. Initially, I used my existing setup with a Mikroe LSM6DSL Click and was able to get data from all three axes of accelerometers. I think I ESD’ed that part because all Accels quit responding, but the part kept talking. While troubleshooting the Mikroe part, I wrote C code for an accelerometer test found in ST’s AN5040 (Fig 36), I enabled ST’s rounding (cool) so I could do a block read. Replaced it with the Sparkfun LSM6DSO. I have three logic analyzer I2C protocol pics to prove I talk to the LSM6DSO at 100kHz, but it just sends back 0x00’s; I’m thinking I might have ESD’ed the Sparkfun board now(?). OR I must have a setup issue, I need a good C programmer or wise LSM6DSO user to square me away (Code below). See, I get the same behavior now with both parts (Sparkfun and Mikroe).
ThreedB
Techno stuff- Using Microchip PIC24F Curiosity board, using MPLAB 6 IDE, XC16 compiler, ESD mat, wrist strap, Saleae Logic 4 I2C protocol analyzer
Code*
int main(void)
{
// initialize the device
SYSTEM_Initialize();
int RX_dataL = 0x00; //temp value location for returned L byte register value
int RX_dataH = 0x00; //temp value location for returned H byte register value
int RX_data_Accel_raw[6];//init array for rounding read with readNBytes
int XLtemp=0x00;
int indx;
int XLword=0x0000; //temp 16 bit accelerometer word
int OUTX_NOST=0x00; //average register
int OUTX_ST=0x00; //average register
int MaxX_ST=0x00; //Maximum ST value
int stat=0x0; //status register temp
i2c2_driver_driver_open();
LED1_Off();
//Set chip select on LMS6DSL CS=1 (=>I2C enabled, SPI disabled) *** RIGHT? *** :shock:
_TRISC3=0;
_LATC3=1; //LSM6DSL, CS=1
__delay_ms(70); //POR delay while LSM6DSL wakes up
stat=i2c_read1ByteRegister(LSM6DSL_CHECK_ID ,LSM6DSL_WHO_AM_I_REG); //*** SEE Who_a_I.png → comm works***
__delay_ms(10);
//reset SW Registers in LSM6DSL, AN5040 Section 5.7, *** SEE Setup_Writes.png ***
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL2_G,0x00); //gyros in power down mode
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL1_XL,0x20); //26 Hz
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL6_G,0x10); //Accel in high performance mode
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL3_C,0x80); //Set BOOT bit
__delay_ms(16); //wait while part resets
//INIT LMS6DSL
//Accel ODR=26Hz, FS=+/-2g, Digital LPF=0
//Init Code from ST AN5040 pg 97 ***Do any of these f-up the part? *** :?
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL1_XL,0x38);//Reg 0x10
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL2_G,0x00);
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL3_C,0x44);
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL4_C,0x00);
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL5_C,0x20);//enable rounding, AN5040 says 0x00
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL6_G,0x00);
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL7_G,0x00);
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL8_XL,0x00);
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL9_XL,0x00);
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL10_C,0x00);//Reg 0x19
__delay_ms(100);
//read one junk byte from LSM6DSL, i2c_readDataBlock WORKS when rounding enabled in CTRL5_C=0x20
while (!(stat & 0x1)) {
stat=i2c_read1ByteRegister(LSM6DSL_CHECK_ID ,LSM6DSL_STATUS_REG);
}
i2c_readDataBlock(LSM6DSL_CHECK_ID, LSM6DSL_OUTX_L_G, RX_data_Accel_raw, 6);//make Rounding[2:0]=0x001
//Read and average five XL readings, per AN5040 *** SEE Rounding_reads.png all 0x00 reads from all six Accel bytes ***
stat=0x0;
for (indx=0; indx<4; indx=indx+1) {
stat=i2c_read1ByteRegister(LSM6DSL_CHECK_ID ,LSM6DSL_STATUS_REG);
while (!(stat & 0x1)) {
stat=i2c_read1ByteRegister(LSM6DSL_CHECK_ID ,LSM6DSL_STATUS_REG);
}
i2c_readDataBlock(LSM6DSL_CHECK_ID, LSM6DSL_OUTX_L_G, RX_data_Accel_raw, 6);//make Rounding[2:0]=0x001
XLword=(RX_dataH<<8 | XLtemp) | RX_dataL;
OUTX_NOST=XLword/5 + OUTX_NOST;
}
//Enable Accelerometer Self Test
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL5_C,0x01);
__delay_ms(100);
//read one junk byte from LSM6DSL
stat=0;
while (!(stat & 0x1)) {
stat=i2c_read1ByteRegister(LSM6DSL_CHECK_ID ,LSM6DSL_STATUS_REG);
}
RX_dataL=i2c_read1ByteRegister(LSM6DSL_CHECK_ID ,LSM6DSL_OUTX_L_G); //Reads Accel Register value
RX_dataH=i2c_read1ByteRegister(LSM6DSL_CHECK_ID ,LSM6DSL_OUTX_H_G); //Reads Accel Register value
//Read and average five XL readings, per AN5040
stat=0;
for (indx=1; indx<5; indx=indx+1) {
while (!(stat & 0x1)) {
stat=i2c_read1ByteRegister(LSM6DSL_CHECK_ID ,LSM6DSL_STATUS_REG);
}
stat=0;
RX_dataL=i2c_read1ByteRegister(LSM6DSL_CHECK_ID ,LSM6DSL_OUTX_L_G); //Reads Accel Register L value
RX_dataH=i2c_read1ByteRegister(LSM6DSL_CHECK_ID ,LSM6DSL_OUTX_H_G); //Reads Accel Register H value
XLword=(RX_dataH<<8 | XLtemp) | RX_dataL;
OUTX_ST=XLword/5+OUTX_ST;
if (abs(OUTX_ST)>abs(MaxX_ST)) {MaxX_ST=OUTX_ST; }
}
//Final test, if it passed LED1 stays on for 2s *** code gets to this point and sets the LED because they were ALL 0x00s ***
if (abs(OUTX_ST-OUTX_NOST) <= abs(MaxX_ST)) {
LED1_On();
__delay_ms(2000);
}
LED1_Off();
//Turn Accel test OFF
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL1_XL,0x00);
i2c_write1ByteRegister(LSM6DSL_CHECK_ID,LSM6DSL_CTRL5_C,0x00);
while (1)
{
LED1_On();
__delay_ms(100);
LED1_Off();
__delay_ms(100);
}
return 1;
}