0

I'm having trouble reading and writing to my Adafruit LSM6DSOX IMU from my Raspberry Pi 4 running Ubuntu 20.04. I need to do it via SPI since I require the bandwidth, but I can only seem to read the WHO_AM_I register successfully. Reading/writing to any other register only returns 0x00. I have verified that I can read data off the IMU from an Arduino via SPI, but if I try to read a register other than 0x0F (the IMU_ID) I get 0x0 as a response. Any insight/ideas what could be causing this would be greatly appreciated!

EDIT: It turns out I can read the following registers:

0x0f : 0x6c
0x13 : 0x1c
0x33 : 0x1c
0x53 : 0x1c
0x73 : 0x1c

These are all random registers however, and the value 0x1C doesn't seem to correspond with anything.

This is my main.py:

import LSM6DSOX

def main():
    imu=LSM6DSOX.LSM6DSOX()
    imu.initSPI()
    whoamI=imu.read_reg(0x0F)
    while(whoamI != imu.LSM6DSOX_ID):
        imu.ms_sleep(200)
        print('searching for IMU')
        whoamI=imu.get_id()
        print(hex(whoamI))
    print('found lsm6dsox IMU')

    imu.spi.close()
    imu.spi = None

if __name__=="__main__":
    main()

This is an excerpt from my LSM6DSOX.py:

    def initSPI(self):
        # Setup communication SPI
        self.spi = spidev.SpiDev()
        self.spi.open(0, 0)
        self.spi.mode=0b11 #mode 3, (mode 0 is also fine)
        self.spi.max_speed_hz = 500000
        return self.spi

    def read_reg(self, reg, len=1):
        # Set up message 
        buf = bytearray(len+1)
        buf[0] = 0b10000000 | reg # MSB bit must be 1 to indicate a read operation. this is OR'd with the register address you want to read

        resp =self.spi.xfer2(buf) #send (and recieve) data to the imu
        if len==1:
            return resp[1]
        else:
            return resp[1:] #display recieved data

    def write_reg(self, reg, data, len=1):
        # Set up message 
        buf = bytearray(len+1)
        buf[0] = 0b00000000 | reg # MSB bit must be 0 to indicate a read operation. this is OR'd with the register address you want to read
        buf[1:] =bytes(data)
        resp =self.spi.xfer2(buf) #send (and recieve) data to the imu
        return resp[1:] #display recieved data
0andriy
  • 4,183
  • 1
  • 24
  • 37
  • My gosh, just enable driver in the kernel and use it with help of `libiio` — it has Python bindings. – 0andriy Jul 09 '22 at 01:20
  • The issue is that I will need to interface with >10 of them, so I will have to bitbang the SPI. I don't see how that should work via linux drivers/modules. – clemfandango Jul 14 '22 at 14:22
  • I don’t understand what the problem do you see. It is by a definition the kernel drivers written in C are way more flexible and faster than some custom solutions in the user space (yes, there are exceptions, but general observation stays unchanged). – 0andriy Jul 14 '22 at 20:18
  • And how bit banging solves anything? You can use one SPI controller for many sensors. Anyway host CPU is much faster than uC inside the sensor. – 0andriy Jul 14 '22 at 20:20
  • You'll have to excuse me, I've never used iio/device drivers before. As I understand it you have to name each device on the SPI bus in the device tree, which would limit me to only 2 IMUs, since the raspberry pi's hardware SPI only has 2 Chip select pins. – clemfandango Jul 15 '22 at 20:47
  • Read this: https://gist.github.com/mcbridejc/d060602e892f6879e7bc8b93aa3f85be – 0andriy Jul 16 '22 at 15:07

0 Answers0