adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.07k stars 1.2k forks source link

Weird i2c issues with Pi Pico and SparkFun SerLCD #4621

Open ajs256 opened 3 years ago

ajs256 commented 3 years ago

Firmware

Adafruit CircuitPython 6.2.0 on 2021-04-05; Raspberry Pi Pico with rp2040

Code/REPL

import board
import busio
import bitbangio
from adafruit_bus_device.i2c_device import I2CDevice

i2c = busio.I2C(board.GP17, board.GP16)
# i2c = bitbangio.I2C(board.GP17, board.GP16)

addr = 0x40

while not i2c.try_lock():
    print("i2c not locked, retrying...")

print("i2c initted")

dev = I2CDevice(i2c, addr)  # if we try to probe, it infinitely hangs
print("i2c device created")

Behavior

It infinitely hangs unless I pass in probe=False to the I2CDevice call.

Description

I have confirmed this with a SparkFun SerLCD (ATmega328-based) and an HTU21D breakout. It seems to happen both with busio and bitbangio.

EDIT: New things have cropped up, see my later comment

dhalbert commented 3 years ago

Are both devices physically connected when you are trying this probe, or are you connecting one at a time?

ajs256 commented 3 years ago

One at a time.

ajs256 commented 3 years ago

And... just when I thought I was done with them, I am getting OSError: [Errno 19] Unsupported operation on i2c writes. Here is the code I am using: gist link Here's the traceback:

Traceback (most recent call last):
  File "code.py", line 25, in <module>
  File "adafruit_bus_device/i2c_device.py", line 84, in write
OSError: [Errno 19] Unsupported operation

It rarely happens, so I can't make a minimal example.

Neradoc commented 3 years ago

It infinitely hangs unless I pass in probe=False to the I2CDevice call.

I believe that's because you lock the device with your try_lock() loop. If you do that, use the I2C object directly. One of the roles of I2CDevice is to manage the locks. You use it like this:

with dev as bus_device:
    bus_device.write(...)

(Note that here bus_device == dev, but I'd call it an implementation detail I think)

Now on the other issue, I do encounter random OSError: [Errno 19] Unsupported operation with the SerLCD. It tends to happen cumulatively after a series of writes, but seems to go away if I add a 1 ms sleep between each write.

Here is my test code (running on QT Py 2040 + SparkFun 16x2 SerLCD - RGB Backlight)

ajs256 commented 3 years ago

Thank you so much @Neradoc, those fixes worked!

Leaving this open so someone can figure out why the delay is needed at all.