Skip to main content
Visitor II
February 8, 2025
Question

LSM6DSO not reading 1G at rest

  • February 8, 2025
  • 1 reply
  • 1877 views

I  am writing my own library in C++ to operate the LSM6DSO and when the sensor is at rest it reads 0.5 G on the z-axis, I've tried the code with 2 ICs, one in an Adafruit breakout board, and another one in an old PCB that had the sensor soldered one and both got the same error, so I believe that the issue might be in the code, but I can't identify where is the problem. Btw, I am using the dev kit NUH7AZIQ$ATZ3A140012 (STM32H7A3ZIT6Q). Also, when i turn the sensor 90 deg the 0.5g moves to the other axis, and regardless of the range scale I choose, the readings adjust themselves so that it still gives the 0.5 G after applying the conversion factor .

Diogo_Goto_0-1739051739233.png
The first line shows the reading from the CTRL1_XL register and breaks it down into the configurations in that register (which in this picture is set up to +-2G range and sampling of Hz)
the second lines show the reading from the OUTZ_L_A (2Ch) and OUTZ_H_A (2Dh) registers, then it combines that into the raw data and multiply by the sensitivity factor suggested in the data sheet for each range ( in this case 0.0061) 

Diogo_Goto_1-1739054006872.png

Small programs that plots the lsm6dso outputs, as I turned the imu, the 0.5 g readings moved to the other axis

Diogo_Goto_2-1739054522593.png

Here is the part of the code, in this section I its not exactly the library i am writing but it has follows the same procedures and gets the same numbers.




    This topic has been closed for replies.

    1 reply

    Technical Moderator
    February 20, 2025

    Hi @Diogo_Goto ,

    Is it possible you are using a wrong sensitivity for your FS? Can you check it?

    FedericaBossi_0-1740066140770.png

    In addition, can you try to implement our official drivers and let me know if you still have the problem? 

    Thanks.

    Visitor II
    February 20, 2025

    Hello Federica Bossi,

    Thanks for the reply.


    @Federica Bossi wrote:

    Is it possible you are using a wrong sensitivity for your FS? Can you check it?


    If you look at the first picture on the original post i am reading the data directly from the registers. I am reading CTRL1_XL, which contains the FS. On that picture is set to 0x0 so the conversion factor is 0.061 and if you multiply that number  by the value read by the 2 registers for the z axis you still get 0.5G. I also tried different FS ranges, the number changes but after multiplying everything I still get the 0.5 G.


    In addition, can you try to implement our official drivers and let me know if you still have the problem? 


    Yeah, I tried that as well the code is below, i think the setup is correct, at least i got no error in initialization and it was still reading 0.5 G.

    Diogo_Goto_0-1740080843888.pngDiogo_Goto_1-1740080871486.png

    Diogo_Goto_2-1740080900579.png

     

     



    ST Employee
    February 20, 2025

    A quick look at the screenshot of your C code seems to point to a data conversion problem: you read two uint8 and then make up a uint16 value out of it. But the accelerometer output is a SIGNED int16.

    Have a look at how lsm6dso_acceleration_raw_get() is implemented in the official C driver on GitHub: 

    lsm6dso-pid/lsm6dso_reg.c at 7cd1aae6017ca386b09f1814994e085bf6519344 · STMicroelectronics/lsm6dso-pid · GitHub

    int32_t lsm6dso_acceleration_raw_get(const stmdev_ctx_t *ctx, int16_t *val)
    {
    uint8_t buff[6];
    int32_t ret;

    ret = lsm6dso_read_reg(ctx, LSM6DSO_OUTX_L_A, buff, 6);
    val[0] = (int16_t)buff[1];
    val[0] = (val[0] * 256) + (int16_t)buff[0];
    val[1] = (int16_t)buff[3];
    val[1] = (val[1] * 256) + (int16_t)buff[2];
    val[2] = (int16_t)buff[5];
    val[2] = (val[2] * 256) + (int16_t)buff[4];

    return ret;
    }

    One could also use a C union to make the conversion faster but the code would be less portable as one would have to take into account the endianness of the memory representation (big-endian or little-endian)