No accelerometer data from LSM6DSO, is it my setup

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*** :wink:

__delay_ms(10);

//reset SW Registers in LSM6DSL, AN5040 Section 5.7, *** SEE Setup_Writes.png ***:slight_smile:

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 *** :frowning:

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 *** :frowning:

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;

}

SOLVED!

It’s always the simple stuff… I was reading the gyro registers, not the accelerometer registers.

ThreedB