Skip to main content
Visitor II
March 18, 2025
Question

LSM6DSV: Z acceleration values too high by 1g

  • March 18, 2025
  • 2 replies
  • 484 views

Hi,
I read the LSM6DSV on the STEVAL SMKI239AA using a Raspberry Pi Pico running Circuit Python. The CTRL1 register is set to 0x07 (240 Hz ODR, high performance). My output is converted to m/s^2 and looks like that when I move the sensor board slowly:

Xacc: -8.6479 | Yacc: -1.3192 | Zacc: 5.5958 | sum: 10.38456
Xacc: -8.6479 | Yacc: -1.3120 | Zacc: 5.6042 | sum: 10.38817
Xacc: -9.1219 | Yacc: -2.3511 | Zacc: 6.3375 | sum: 11.35342
[snip]
Xacc: -6.9216 | Yacc: -5.3630 | Zacc: 6.2219 | sum: 10.74166
Xacc: -9.1081 | Yacc: -6.2662 | Zacc: 6.7229 | sum: 12.93914
Xacc: -10.0293 | Yacc: -5.9400 | Zacc: 8.0236 | sum: 14.15091
Xacc: -6.5439 | Yacc: -4.0893 | Zacc: 9.1746 | sum: 11.98826
Xacc: -7.0288 | Yacc: -3.8098 | Zacc: 9.6672 | sum: 12.54482
Xacc: -7.5543 | Yacc: -3.9289 | Zacc: 10.4986 | sum: 13.51752
[snip]
Xacc: -5.1715 | Yacc: 5.1571 | Zacc: 14.4975 | sum: 16.23320
Xacc: -4.8076 | Yacc: 4.4610 | Zacc: 15.3564 | sum: 16.69827
Xacc: -3.3956 | Yacc: 3.4147 | Zacc: 17.1664 | sum: 17.82908
Xacc: -2.8964 | Yacc: 2.2152 | Zacc: 17.5279 | sum: 17.90321
Xacc: -2.0045 | Yacc: 4.5508 | Zacc: 18.0397 | sum: 18.71252

The fourth column is the vector sum of the three axes. As can be seen, X and Y look credible; Z, however, runs up to twice the gravitational acceleration all by itself. When the sensor is positioned horizontally, Z is about zero (but should be -1g / -9.81 m/s^2). When the sensor is inverted (upside down), Z grows to about 2g / 19.6 m/s^2 (but should be +1g / 9.81 m/s^2). I would like Z to behave like the two other axes. I can fake it by subtracting the 9.81 m/s^2, but I prefer to get correct values in the first place.

What setting did I screw up? I only set CTRL1 and leave all others with their default setting.

Regards,

Peter

    This topic has been closed for replies.

    2 replies

    Technical Moderator
    March 21, 2025

    Hi @PeterK ,

    That's very strange.

    Are you reading the outputs correctly? I mean are you implementing the 2's complement correctly? Are you also using the STEVAL-MKI109V3?

    PeterKAuthor
    Visitor II
    March 24, 2025

    Hi Federica,

    I should add that I now also set the offset registers (X_OFS_USR, Y_OFS_USR, Z_OFS_USR) actively to zero before reading values and still see the offset in the Z channel, but not the X and Y channel. Also the filtering is reduced as much as possible:

    write(i2c, devDSV, 0x18, 0x00)
    write(i2c, devDSV, 0x73, 0x00)
    write(i2c, devDSV, 0x74, 0x00)
    write(i2c, devDSV, 0x75, 0x00)

    The syntax of the command should be obvious: First parameter is the I2C instance, second the instance of the I2C device with the bus address 107, the third parameter is the register to be written to and the last parameter is the value.

    I also should add that the offset is creeping down with time. Here are the first 36 measurements with the sensor in an upright position (where Z should read -9.8):

    Xacc: 0.2029 | Yacc: 0.5531 | Zacc: -3.7014 | Sum: 3.74802
    Xacc: 0.2077 | Yacc: 0.5441 | Zacc: -3.6278 | Sum: 3.67426
    Xacc: 0.1987 | Yacc: 0.5578 | Zacc: -3.6512 | Sum: 3.69887
    Xacc: 0.1556 | Yacc: 0.5465 | Zacc: -4.1468 | Sum: 4.18550
    Xacc: 0.1413 | Yacc: 0.5118 | Zacc: -4.3975 | Sum: 4.42948
    Xacc: 0.1562 | Yacc: 0.4950 | Zacc: -4.3072 | Sum: 4.33833
    Xacc: 0.1586 | Yacc: 0.5004 | Zacc: -4.2455 | Sum: 4.27784
    Xacc: 0.1269 | Yacc: 0.4986 | Zacc: -4.6549 | Sum: 4.68327
    Xacc: 0.1149 | Yacc: 0.4735 | Zacc: -4.8794 | Sum: 4.90364
    Xacc: 0.1251 | Yacc: 0.4639 | Zacc: -4.7501 | Sum: 4.77433
    Xacc: 0.1197 | Yacc: 0.4717 | Zacc: -4.8626 | Sum: 4.88691
    Xacc: 0.1125 | Yacc: 0.4435 | Zacc: -5.0105 | Sum: 5.03131
    Xacc: 0.1293 | Yacc: 0.4435 | Zacc: -4.8530 | Sum: 4.87498
    Xacc: 0.1323 | Yacc: 0.4555 | Zacc: -4.7525 | Sum: 4.77610
    Xacc: 0.1095 | Yacc: 0.4663 | Zacc: -5.0476 | Sum: 5.07025
    Xacc: 0.0886 | Yacc: 0.4375 | Zacc: -5.2744 | Sum: 5.29328
    Xacc: 0.1006 | Yacc: 0.4166 | Zacc: -5.1284 | Sum: 5.14625
    Xacc: 0.0976 | Yacc: 0.4381 | Zacc: -5.1170 | Sum: 5.13666
    Xacc: 0.0796 | Yacc: 0.4310 | Zacc: -5.3534 | Sum: 5.37134
    Xacc: 0.0718 | Yacc: 0.4022 | Zacc: -5.5522 | Sum: 5.56717
    Xacc: 0.0820 | Yacc: 0.3861 | Zacc: -5.4277 | Sum: 5.44198
    Xacc: 0.0790 | Yacc: 0.4112 | Zacc: -5.4917 | Sum: 5.50764
    Xacc: 0.0748 | Yacc: 0.3759 | Zacc: -5.6425 | Sum: 5.65553
    Xacc: 0.0916 | Yacc: 0.3735 | Zacc: -5.4588 | Sum: 5.47231
    Xacc: 0.0700 | Yacc: 0.4022 | Zacc: -5.6126 | Sum: 5.62744
    Xacc: 0.0742 | Yacc: 0.3717 | Zacc: -5.7694 | Sum: 5.78186
    Xacc: 0.0868 | Yacc: 0.3711 | Zacc: -5.5809 | Sum: 5.59388
    Xacc: 0.0808 | Yacc: 0.3879 | Zacc: -5.5803 | Sum: 5.59433
    Xacc: 0.0700 | Yacc: 0.3639 | Zacc: -5.6928 | Sum: 5.70486
    Xacc: 0.1030 | Yacc: 0.3663 | Zacc: -5.4881 | Sum: 5.50128
    Xacc: 0.1071 | Yacc: 0.3849 | Zacc: -5.4366 | Sum: 5.45129
    Xacc: 0.0742 | Yacc: 0.3909 | Zacc: -5.6258 | Sum: 5.63982
    Xacc: 0.0784 | Yacc: 0.3663 | Zacc: -5.8053 | Sum: 5.81741
    Xacc: 0.0856 | Yacc: 0.3663 | Zacc: -5.6425 | Sum: 5.65506
    Xacc: 0.0766 | Yacc: 0.3807 | Zacc: -5.6695 | Sum: 5.68275
    Xacc: 0.0718 | Yacc: 0.3807 | Zacc: -5.8107 | Sum: 5.82362

    PeterKAuthor
    Visitor II
    March 21, 2025

    Hi Federica,
    thank you for answering! Yes, I agree, that is strange. Since I treat all three channels equally, and only Z is looking wrong, I doubt that have a mistake when reading the values. And no, I do not use the MKI109V3. I connect the pins for GND, VDD, VDDIO, SCL and SDA directly to the corresponding Pico pins and have no problem to initialize the I2C connection, inquire 0x0F (WhoAmI) or with any other I2C-related stuff. All other pins are left floating. Since I also read the rotations in the same way, and they look fine to me, I very much doubt that my implementation is wrong.
    Here is the code (in Python, not C!):

    dataGyr = read(i2c, devDSV, 0x22, 6)    # 6 Bytes, starting with Reg. 22
    dataAcc = read(i2c, devDSV, 0x28, 6)    # 6 Bytes, starting with Reg. 28

    gyr_x = struct.unpack_from("<h", dataGyr, 0)[0] - xrotSum
    gyr_y = struct.unpack_from("<h", dataGyr, 2)[0] - yrotSum
    gyr_z = struct.unpack_from("<h", dataGyr, 4)[0] - zrotSum

    acc_x = struct.unpack_from("<h", dataAcc, 0)[0]
    acc_y = struct.unpack_from("<h", dataAcc, 2)[0]
    acc_z = struct.unpack_from("<h", dataAcc, 4)[0]

    As you can see, I first collect the rotation values at rest and subtract them from the measurements for gyro bias calibration. The acceleration numbers are the raw sensor values.