pimoroni / pmk-circuitpython

MIT License
88 stars 22 forks source link

suddenly unresponsive: I2C issues #8

Closed matteoferla closed 1 year ago

matteoferla commented 1 year ago

I have what appears to be an an electronic issue, but this does not make much sense. So I am hoping I am missing something obvious —although I have not done all obvious tests.

I soldered headers on a new pico and placed it on a new rgb keypad, it worked through the first example but then after a few other tests it is unresponsive colour-wise (it's bricked) because it returns*:

File "/lib/pmk/platform/rgbkeypadbase.py", line 22, in __init__
RuntimeError: No pull up found on SDA or SCL; check your wiring

This is the same result one gets if it's not slotted in. These are the tests I did, which if I fail to get it to work hopefully may help others. So I'll write this as much of a walkthough as I can be bothered doing.

Tests done

*) Print output is seen in Mu editor's Serial or in PyCharm w/ MicroPython plugin and COM assigned. In the former there's a picture of a chip in the bottom left, which when unplugged has a red x on it.

Okay. The issue may be:

  1. pico: code
  2. pico: physical fault
  3. keypad: physical fault

Unfortunately, I don't have a second pico to swap in, so I cannot rule out 2.

Code?

I have nuked the pico's flash a few times and tried both 7.3.3 and 8.0.6 uf2 firmwares and reinstalled the correct libraries for the version I have.

Pico fault?

As the pico is naked, I assumed I blew the power management chip (or fuse I believe for a pico?), which at least with regular Raspberries is very easy (3.3V-5V shorting) —down the line I might add a thin layer of neutral-cure silicone to the top of the pins. So I simply tested the pins with a multimeter with hook leads and everything is fine (3.3V).

import busio, board, digitalio, time

for pin in (board.GP3, board.GP4, board.GP5, board.GP17, board.GP18, board.GP19):
    print(pin)
    test = digitalio.DigitalInOut(pin)
    test.direction = digitalio.Direction.OUTPUT
    test.value = 1
    time.sleep(5)
    test.value = 0

I have done plenty of soldering before, so it's not a poor quality soldering.

keypad fault?

Now, scanning for I2C on GP4 and GP5 powered by GP3, gives an I2C at address 0x20 sometimes.

import board, busio, digitalio
import time

# ## 3.3V
powered = digitalio.DigitalInOut(board.GP3)
powered.direction = digitalio.Direction.OUTPUT
powered.value = 1

# ## init the I2C bus.
# in other Pis it's `i2c = board.I2C()`
# This is circuit-python stuff, `bus = SMBus(1)` is the other way
i2c = busio.I2C(scl=board.GP5, sda=board.GP4)  

while not i2c.try_lock():
    pass
print("I2C addresses found:", [hex(i) for i in i2c.scan()])
powered.value = 0
print('complete')

Occasional different errors

In the above test I recently started getting when doing i2c.scan() or keybow = PMK(Hardware()) a TimeoutError: Clock stretch too long error occurs (i.e. something is glitching). While other times (after a wiggle) keybow = PMK(Hardware()) is fine, but keybow.update() raises the error:

File "/lib/pmk/platform/switches/tca9555.py", line 19, in switch_state
OSError: [Errno 19] No such device

This makes me suspect it's a hardware issue. I should test a different I2C device (eg. BME280). But for now, I'll buy a new Pico and see if anyone else has had this issue.

matteoferla commented 1 year ago

I switched picos and it worked: Things made in Yorkshire (i.e. Pimoroni keypad) outperform things made in Cambridge (pi foundation HQ). (Okay, the Pico is made in Japan and when I tried my old pico it started working again... but 🤫 )