pimoroni / icm20948-python

Python library for the Pimoroni ICM20948 breakout
https://shop.pimoroni.com/products/icm20948
MIT License
50 stars 22 forks source link

Sparkfun SEN-15335 (icm-20948 board) Getting IOError: [Errno 121] Remote I/O error #8

Closed rob-meiner closed 4 years ago

rob-meiner commented 4 years ago

Dear Colleagues:

I just hooked up a Sparkfun SEN-15335, which uses the ICM-20948 IMU. I am using Raspberry Buster on a raspberry pi 4b.

I am replacing a working MPU-9250 setup with the ICM-20948, since the MPU-9250 has been EOL'd.

Vin on the board is 3.3 Volts, SDA from the Sparkfun board is connected to physical pin 3 (SDA1) on the Pi and SCL from the Sparkfun board is connected directly to physical pin 5 (SCL1) on the Pi. i2c is enabled on the Pi and works (I have tested it with other i2c devices, including the mentioned MPU9250 IMU. Then I disconnected everything but the ICM-20948 to troubleshoot). Lead length is 21cm.

I am attempting to run read-all.py from the examples in this repository. I have not modified the code.

Here's what I get:

pi@antonio:~/icm20948-python/examples $ python read-all.py
read-all.py

Reads all ranges of movement: accelerometer, gyroscope and

compass heading.

Press Ctrl+C to exit!

Traceback (most recent call last):
  File "read-all.py", line 16, in <module>
    imu = ICM20948()
  File "build/bdist.linux-armv7l/egg/icm20948/__init__.py", line 254, in __init__
  File "build/bdist.linux-armv7l/egg/icm20948/__init__.py", line 89, in bank
  File "build/bdist.linux-armv7l/egg/icm20948/__init__.py", line 69, in write
IOError: [Errno 121] Remote I/O error

I am already aware that Errno 121 usually has to do with the I/O on the device. When I've had to fix this in the past, it has been a matter of the device not being detected. In this case, the device is detected:

pi@antonio:~/icm20948-python/examples $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- 69 -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --  

more tests:

pi@antonio:~/icm20948-python/examples $ i2cget -y 1 0x69 0
0xea
pi@antonio:~/icm20948-python/examples $ i2cget -y 1 0x69 4
0x00

The SEN-15335 has onboard logic level translation, to match the 3.3V to the new 1.9 max input voltage of the ICM-20948, without needing an external board for this.

I have no working hypotheses yet on what is going wrong.

Does anyone have any ideas how to make this work? Thanks, Mark

sandyjmacdonald commented 4 years ago

The Sparkfun breakout you’re using uses the 0x69 I2C address while the Pimoroni breakout that this library was written for uses a default I2C address of 0x68. You’ll need to edit the script to change the I2C address to 0x69 when the sensor is instantiated.

rob-meiner commented 4 years ago

@sandyjmacdonald Thanks for the quick reply. Makes sense that the addresses may have been changed. I made the following change in __init__.py and found that this error may have been anticipated:

pi@antonio:~/icm20948-python/library/icm20948 $ sudo nano -l __init__.py
  5 I2C_ADDR = 0x69  #Mark change from I2C_ADDR =  0x68
  6 I2C_ADDR_ALT = 0x69

We do see that it had 0x69 as an alternative address. I'm still getting the same error after making that change.

pi@antonio:~/icm20948-python/examples $ python read-all.py
read-all.py

Reads all ranges of movement: accelerometer, gyroscope and

compass heading.

Press Ctrl+C to exit!

Traceback (most recent call last):
  File "read-all.py", line 16, in <module>
    imu = ICM20948()
  File "build/bdist.linux-armv7l/egg/icm20948/__init__.py", line 254, in __init__
  File "build/bdist.linux-armv7l/egg/icm20948/__init__.py", line 89, in bank
  File "build/bdist.linux-armv7l/egg/icm20948/__init__.py", line 69, in write
IOError: [Errno 121] Remote I/O error

Is it the case that the other changes have also been made? It says that an error happens in bank on line 89

 86     def bank(self, value):
 87         """Switch register self.bank."""
 88         if not self._bank == value:
 89             self.write(ICM20948_BANK_SEL, value << 4)
 90             self._bank = value

another in writeon line 69:

 67     def write(self, reg, value):
 68         """Write byte to the sensor."""
 69         self._bus.write_byte_data(self._addr, reg, value)
 70         time.sleep(0.0001)
 71

and the last on line 254

254         self.bank(0)
255         if not self.read(ICM20948_WHO_AM_I) == CHIP_ID:
256             raise RuntimeError("Unable to find ICM20948")

Thanks, Mark

rob-meiner commented 4 years ago

@sandyjmacdonald Ayayay! I forgot to rebuild the package after making the change.

Make the following change to line 5 of __init__.py using nano:

pi@antonio:~/icm20948-python/library/icm20948 $ sudo nano -l __init__.py
  5 I2C_ADDR = 0x69  #Mark change from I2C_ADDR =  0x68

Save and exit. Then rebuild the package:

sudo ./install.sh

Thanks again, Mark