More troubleshooting with help from Gemini. Using this code:
from machine import Pin
import time
Pin assignments for SparkFun XRP RP2350 Motor L Encoders
ENC_A_PIN = 30
ENC_B_PIN = 31
Global pulse counter and state tracking
pulse_count_a = 0
pulse_count_b = 0
def handle_encoder_a(pin):
global pulse_count_a
pulse_count_a += 1
def handle_encoder_b(pin):
global pulse_count_b
pulse_count_b += 1
Configure pins with internal pull-ups (required for open-drain Hall sensors)
enc_a = Pin(ENC_A_PIN, Pin.IN, Pin.PULL_UP)
enc_b = Pin(ENC_B_PIN, Pin.IN, Pin.PULL_UP)
Attach interrupts on falling/rising edges
enc_a.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=handle_encoder_a)
enc_b.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=handle_encoder_b)
print(f"Monitoring Motor L Encoders on GPIO {ENC_A_PIN} (A) and GPIO {ENC_B_PIN} (B)…")
print(“Spin the left wheel manually by hand.”)
last_a = -1
last_b = -1
while True:
val_a = enc_a.value()
val_b = enc_b.value()
print(f"RAW STATES -> Pin {ENC_A_PIN} (A): {val_a} | Pin {ENC_B_PIN} (B): {val_b} | Counts -> A: {pulse_count_a}, B: {pulse_count_b}")
time.sleep(0.25)
Result is:
RAW STATES → Pin 30 (A): 1 | Pin 31 (B): 0 | Counts → A: 895, B: 0
RAW STATES → Pin 30 (A): 1 | Pin 31 (B): 0 | Counts → A: 895, B: 0
Gemini says:
The test output isolates the problem to GPIO 31 (Motor L Encoder Channel B).
-
GPIO 30 (Channel A): Functioning normally (logic level toggled/held high at 1, counter accumulated 895 pulses).
-
GPIO 31 (Channel B): Completely dead/stuck. The state is permanently locked at 0, and count is 0.
Since you already swapped known-working motors/cables, the issue is a hard short to Ground (GND) or a damaged RP2350 GPIO pin on the board.
I’m waiting for batteries to charge, before conducting more suggested tests, and potential workaround:
Physical Troubleshooting Sequence
Step through this process with power off to identify the precise fault point on GPIO 31:
1.Disconnect Motor Connector:Power OFF.
Unplug the Motor L JST cable from the board completely so the Motor L header pins are exposed with no external cable attached. Run the MicroPython script again.
- Verification: If Pin 31 switches from
0 to 1 (due to the internal PULL_UP), the short was inside the board’s female header socket contacts. If it stays 0, the short is on the PCB or inside the RP2350.
2.Check Resistance to Ground:Multimeter Continuity Mode.
With power disconnected, place one DMM probe on board GND and the other probe directly on the GPIO 31 pin at the Motor L header.
- Verification: A reading near $0\,\Omega$ confirms a physical short circuit to GND on the PCB trace (e.g., solder bridge or shorted ESD protection diode). A high resistance reading indicates an internal RP2350 failure.
3.Inspect Board Solder Joints:Visual / Magnification.
Examine the JST header solder pads for Motor L and the corresponding RP2350 pin trace for GPIO 31 under a microscope or magnifying glass.
- Verification: Check for tiny solder bridges between the GPIO 31 pin pad and adjacent ground planes or adjacent grounded pins.
GPIO Pin Damage Risk
If GPIO 31 measures near $0\,\Omega$ directly at the RP2350 IC pin even with no external connections, the internal input buffer transistor for GPIO 31 on the RP2350 silicon has shorted internally to GND (often caused by an ESD event or an over-voltage spike on the encoder line).
Software Workaround (If Pin 31 Silicon is Blown)
If GPIO 31 is permanently damaged in silicon, you can bypass it by jumpering the Channel B signal line on the PCB to an unused GPIO pin (e.g., an available expansion header pin) and updating the pin configuration in MicroPython:
Python
# Change Channel B from dead GPIO 31 to an alternate free pin (e.g., GPIO 16 or free QWIIC/expansion pin)
ENC_B_PIN = 16