1

I have a problem while reading the my lsm9ds1 acceleratorsensor registers . It always displays the same values.

My setup is a raspberry pi 4 and the sense HAT which has this sensor integrated. I dont want to use the sense hat library but use the python3-smbus library to better understand I2C.

The registers i want to read from are OUT_X_XL, OUT_Y_XL and OUT_Z_XL which return linear values expressed as a 16-bit word in two's complement. Here is the Datasheet. I tried to convert them with two different functions i found, but got both times an error so i just wanted to see if there just would be a change if i move the sensor around.

Here is my output:

Complements Register 1 X: 221 Y: 59  Z: 254
Complements Register 2 X: 104 Y: 146  Z: 112
Complements Register 1 X: 221 Y: 59  Z: 254
Complements Register 2 X: 104 Y: 146  Z: 112

Do i have to do something different with the values or should i read the register differently? Preferably i would also like the values to be something close to float values what you would expect from an acceleration sensor. Any help is very appreciated

Here is my code:

from smbus import SMBus
import time

i2c_adress = 0x1c # DEVICE ACCELEROMETER

#DEFINITION OF REGISTERS
OUT_X_XL1 = 0x28   # linear acceleration sensor output registers
OUT_X_XL2 = 0x29
OUT_Y_XL1 = 0x2A
OUT_Y_XL2 = 0x2B
OUT_Z_XL1 = 0x2C 
OUT_Z_XL2 = 0x2D



def main():
    i2cbus = SMBus(1) # Create new I2C bus
    
    
    while (True):
        comp_acc_x2 = i2cbus.read_byte_data(i2c_adress, OUT_X_XL2)
        comp_acc_y2 = i2cbus.read_byte_data(i2c_adress, OUT_Y_XL2)
        comp_acc_z2 = i2cbus.read_byte_data(i2c_adress, OUT_Z_XL2)
        
        comp_acc_x1 = i2cbus.read_byte_data(i2c_adress, OUT_X_XL1)
        comp_acc_y1 = i2cbus.read_byte_data(i2c_adress, OUT_Y_XL1)
        comp_acc_z1 = i2cbus.read_byte_data(i2c_adress, OUT_Z_XL1)
        
        print(f" Complements Register 1 X: {comp_acc_x1} Y: {comp_acc_y1}  Z: {comp_acc_z1}")
        print(f" Complements Register 2 X: {comp_acc_x2} Y: {comp_acc_y2}  Z: {comp_acc_z2}")
        
        
        time.sleep(0.5)
          

if __name__ == "__main__":
    main()

New Code using pigpio:

import pigpio
import time

i2c_adress = 0x1c # DEVICE ACCELEROMETER

#DEFINITION OF REGISTERS
OUT_X_XL1 = 0x28   # linear acceleration sensor output registers
OUT_X_XL2 = 0x29
OUT_Y_XL1 = 0x2A
OUT_Y_XL2 = 0x2B
OUT_Z_XL1 = 0x2C
OUT_Z_XL2 = 0x2D

def main():
    pi = pigpio.pi()
    acc_sensor = pi.i2c_open(1, i2c_adress)
    
    
    while(True):
        pi.i2c_write_device(acc_sensor, OUT_X_XL1)
        comp_acc_x1 = pi.i2c_read_device(acc_sensor, OUT_X_XL1)
        print(f" Complements Register 1 X: {comp_acc_x1} ")
        time.sleep(0.5)
        
    
if __name__ == "__main__":
    main()

New Error Message:

    Traceback (most recent call last):   
File "/home/.../mix/pigpio_sense_hat.py", line 52, in <module>
        main()   
File "/home/.../mix/pigpio_sense_hat.py", line 36, in main
        pi.i2c_write_device(acc_sensor, OUT_X_XL1)   
File "/usr/lib/python3/dist-packages/pigpio.py", line 3185, in i2c_write_device
        if len(data): TypeError: object of type 'int' has no len()
9
  • The sensehat library presumably uses the smbus library. Why not see how the sensehat library uses smbus?
    – joan
    Jul 1, 2022 at 12:25
  • That was a good idea @joan sadly i am not very good at reading all this code with no comments. I found some i2c snippets but no clear indication how they communicate. If you want to try your luck, [here ist the link] (github.com/RPi-Distro/RTIMULib/tree/master/Linux)
    – Xenoshell
    Jul 1, 2022 at 13:11
  • i just tried to use the pigpio library and i ran into the same problem.
    – Xenoshell
    Jul 1, 2022 at 14:20
  • If you use pigpio use i2c_write_device(handle, 0x28) then i2c_read_device(handle, 6) to read all 6 bytes at once.
    – joan
    Jul 1, 2022 at 15:34
  • @joan why would i use i2c_write_device()? Honest question, because i never used that library, but it just makes sense to use i2c_read_byte or however its called
    – Xenoshell
    Jul 1, 2022 at 23:35

1 Answer 1

0

I dont know how, but the solution was very simple. Here is the while loop for both libraries.

Pigpio:

while(True):
        comp_acc_x2 = pi.i2c_read_byte_data(acc_sensor, OUT_X_XL2)
        comp_acc_y2 = pi.i2c_read_byte_data(acc_sensor, OUT_Y_XL2)
        comp_acc_z2 = pi.i2c_read_byte_data(acc_sensor, OUT_Z_XL2)
        
        comp_acc_x1 = pi.i2c_read_byte_data(acc_sensor, OUT_X_XL1)
        comp_acc_y1 = pi.i2c_read_byte_data(acc_sensor, OUT_Y_XL1)
        comp_acc_z1 = pi.i2c_read_byte_data(acc_sensor, OUT_Z_XL1)
        
        print(f" Complements Register 1 X: {comp_acc_x1} Y: {comp_acc_y1}  Z: {comp_acc_z1}")
        print(f" Complements Register 2 X: {comp_acc_x2} Y: {comp_acc_y2}  Z: {comp_acc_z2}") 
        
        time.sleep(0.5)

SMBus (here i just had to put the SMBus object into the loop):

while (True):
        i2cbus = SMBus(1) # Create new I2C bus
        comp_acc_x2 = i2cbus.read_byte_data(i2c_adress, OUT_X_XL2)
        comp_acc_y2 = i2cbus.read_byte_data(i2c_adress, OUT_Y_XL2)
        comp_acc_z2 = i2cbus.read_byte_data(i2c_adress, OUT_Z_XL2)
        
        comp_acc_x1 = i2cbus.read_byte_data(i2c_adress, OUT_X_XL1)
        comp_acc_y1 = i2cbus.read_byte_data(i2c_adress, OUT_Y_XL1)
        comp_acc_z1 = i2cbus.read_byte_data(i2c_adress, OUT_Z_XL1)

        print(f" Complements Register 1 X: {comp_acc_x1} Y: {comp_acc_y1}  Z: {comp_acc_z1}")
        print(f" Complements Register 2 X: {comp_acc_x2} Y: {comp_acc_y2}  Z: {comp_acc_z2}")
        
        time.sleep(1.5)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.