cancel
Showing results for 
Search instead for 
Did you mean: 

not getting accelerator axis values

eyal.gal
Associate II

Hi.

We have a board based on nordik nrf52840 chip with lis3dh accelerator sensor connected.

i took the driver code for lis3dh from STM github and wrote the context functions using nordic sdk 15.2 (I2C bus).

First of all i must say that the ADDRESS in the code is no correct, my device response to 0x18 address and not 0x31. Second i'm able to read registers (like who am i register, status registers etc...) and to write to them, also i was able to get the orientation 6D sensor output. what i was unable to do is get a proper reading for x,y,z. the raw reading always returns the same.

i tried changing the scale from 2_g to 4_g and still different value but remains the same between readings. of course i'm shifting and tilting, rotating the board to check it, nothing.

When i compared the STM example code (read_data_simple) to Adafruit's i did see that adafruit turn register1 lower 3 bits which are "axis enable bits" did that too, still nothing.

Anyone has the example code running properly and returning values ?

Am i missing something to get acceleration axis reading ?

8 REPLIES 8
Ozone
Lead

> First of all i must say that the ADDRESS in the code is no correct, my device response to 0x18 address and not 0x31.

You need to discern what is meant with address - either the 7-bit address, excluding the R/W bit (LSB) or the full address. Every I2C device occupies two (consecutive) addresses.

The named 0x18 and 0x31 values do not match even with shift. 0x18 is a write address, 0x30 a read address.

If the address does not match, the device does not respond, and the master reads back 0xFF because of the pull-up resistors. If you code ignores the supposedly missing ACKs from the slave, you get unexpected values.

Use a scope or logic analyzer to see what's going on.

eyal.gal
Associate II

it does not make any sense. the code from STM is :

#define LIS3DH_I2C_ADD_L   0x31U
#define LIS3DH_I2C_ADD_H   0x33U

while the code from adafruit\RAKWireless is:

/** I2C ADDRESS/BITS **/
#define LIS3DH_DEFAULT_ADDRESS (0x18) // if SDO/SA0 is 3V, its 0x19

i tested both and the accelerometer response nicely to 0x18 but not to 0x31.

The device DOES response to 0x18, as i said verifying the ID (0x33) works, also setting and getting status registers, also the 6D orientation works.

to be honest i do get values while reason the axis:

lis3dh_xl_data_ready_get(&dev_ctx, &reg.byte);
    if (reg.byte)
    {
      /* Read accelerometer data */
      memset(data_raw_acceleration.u8bit, 0x00, 3*sizeof(int16_t));
      lis3dh_acceleration_raw_get(&dev_ctx, data_raw_acceleration.u8bit);
      acceleration_mg[0] =
        lis3dh_from_fs2_hr_to_mg(data_raw_acceleration.i16bit[0]);
      acceleration_mg[1] =
        lis3dh_from_fs2_hr_to_mg(data_raw_acceleration.i16bit[1]);
      acceleration_mg[2] =
        lis3dh_from_fs2_hr_to_mg(data_raw_acceleration.i16bit[2]);
     
      sprintf((char*)tx_buffer, "Acceleration [mg]:%4.2f\t%4.2f\t%4.2f\r\n",
              acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]);
    SEGGER_RTT_writeString(0, tx_buffer);
   }

but it never changes no matter how fast i'll tilt\shift\move the unit.

> it does not make any sense. the code from STM is :

  1. #define LIS3DH_I2C_ADD_L 0x31U
  2. #define LIS3DH_I2C_ADD_H 0x33U

Not sure what that is supposed to be. Many things within ST's Cube code are hardly comprehensible, though.

> while the code from adafruit\RAKWireless is: ...

Not sure what adafruit does, and how it defines an I2C address.

Some vendors define it as (right adjusted) 7-bit value, others as left-shifted 8-bit value where the R/W bit is masked(ORed in.

If I remember correctly, the STM32 I2C peripheral has a 7-bit address field which is automatically left-shifted for bus accesses.

> The device DOES response to 0x18, as i said verifying the ID (0x33) works, also setting and getting status registers, also the 6D orientation works.

As mentioned, the best way to validate would be to scope a successful transfer with you adafruit code, and "decode" the address value from the wave form.

eyal.gal
Associate II

you suggest to test with a scope the retrieval of the axis (bulk retrieval with MSB turned on for auto increment)?

Cause the addressing works as i said and yes we did test with a scope once and the data passed in and out fine, the sensor responds to the 0x18 address.

> Cause the addressing works as i said and yes we did test with a scope once and the data passed in and out fine, the sensor responds to the 0x18 address.

So, did you observe 0x18 / 0x19 as device addresses on the bus, i.e. as ACK-nowledged address value (first transferred byte) ?

> ... you suggest to test with a scope the retrieval of the axis (bulk retrieval with MSB turned on for auto increment)?

Not sure if we talk about the same thing.

Auto increment relates to internal register addresses of the I2C slave (LIS3DH), which are only data values from the I2C standard view point.

> So, did you observe 0x18 / 0x19 as device addresses on the bus, i.e. as ACK-nowledged address value (first transferred byte) ?

yes we did.

> Not sure if we talk about the same thing.

Auto increment relates to internal register addresses of the I2C slave (LIS3DH), which are only data values from the I2C standard view point.

it's true , i just pointed it out as it's not exactly standard i2c addressing and the rest of the readings that worked like orientation i did using non bulk (i.e with MSB 0) and got proper response.

> it's true , i just pointed it out as it's not exactly standard i2c addressing and the rest of the readings that worked like orientation i did using non bulk (i.e with MSB 0) and got proper response.

Yes, this is where it gets difficult, especially with the STM32's botched I2C peripheral.

Features like auto-increment are often based on things like repeated start conditions. You would need to check the datasheet carefully, and (or) compare with the working adafruit solution.

agreed it might get tricky however the STM code also does the same things, IE reading a bulk data. i can of course try to read the data byte by byte or more like two by two bytes (each accelerometer value is two bytes), but i'm pretty sure it wont matter.