If you use this, do have a close look at your output files and test carefully – there is always potential for disaster and I won’t be responsible for damage or injury.
Wrote a library for Circuitpython that tries to do most of what the OneButton Arduino library does. It handles one or more buttons – debouncing, single click, long presses, and holding. Written to be non-blocking so that it plays nice with the rest of your code, and easy to implement with just a couple lines.
I’ve been having some fun with the Raspberry Pi Pico and Circuitpython thanks to Mark Hughes and the Teach Me PCB course that he’s putting on at the moment. For whatever reason, I decided it would be cool to iterate on my word clock design. I’m not done yet, but I am making sure to struggle along the way. Here’s a problem I had with the Pico I wanted to share in case someone else does what I did:
TLDR: Don’t pull some? pins high without first configuring them as input or output in your code. Go to fix
This is what I did:
Wire the clock up – 3v to VCC, GND to GND, GP16 to SDA, GP17 to SCL (just like this guy did).
Power it back up – immediately windows says there is something wrong with my device.
Symptoms:
Windows makes a sad dingle noise and says there is something wrong with the device
Device manager shows a device with “device descriptor request failed”
Replacing the driver doesn’t help
Same problem if you plug the Pico into another computer
Your code doesn’t run
No serial port (naturally, USB isn’t working)
Power up with the BOOTSEL button held down does work, and allows loading UF2 files
Re-loading a circuitpython or micropython UF2 doesn’t change the behavior
Undoing the wiring doesn’t make the problem go away
Flashing the Pico with the Arduino framework and using C++ still works
It was a struggle to troubleshoot (I bricked 4 Picos before I found out how to recover them), although I admit I didn’t read the entire datasheet before embarking on this quest. I narrowed in on the cause by removing variables until I had only the RTC and Pico connected directly with wires. I found:
With only GND and VCC connected, there are no issues
If you plug the SCL and SDA in while the Pico is running, it is not interrupted, no problem
If you boot the Pico with SCL and SDA connected, all the bad things happen
Note at this point I have not added any code to configure GP16 and GP17, I am assembling the circuit first
What is the cause?
I noticed that the DS3231 module I’m using pulls SCL and SDA high when it is powered, this seems to be a key part of my problem. Initially I thought the flash was somehow being corrupted, but after making lots of guesses with help from the folks on the TMPCB Discord, on a hunch I tried setting my pins as inputs and bingo, no more problems. This could be correct, or could be a red herring, more important is how to recover.
What I think is happening is that during boot, if you leave these pins undefined and pull them high, it interrupts things after your code has started running but before the USB is initialized. In this state you don’t have a USB disk to update the code with, nor a serial port to figure out what’s up. Even switching to bootloader mode and replacing the Circuitpython UF2 file doesn’t help. It’s possible that this is a code-only problem, but it suspicious that it was reproducible by connecting the GPIOs.
I think this page and the note on line 28 here explain a similar problem, but I am using different pins.
I found a reference to this “nuke” file in a forum post, here’s the description in the FAQ sheet and a link to the file:
Here’s what to do:
Hope that you saved a copy of your code and libraries on your computer (you did, right?)
Download the flash_nuke.uf2 file
Connect the Pico to USB, hold the BOOTSEL switch while doing this to enter bootloader mode
Copy the nuke file to the Pico drive
Pico should reboot into bootloader mode again
Copy the Circuitpython or Micropython or whatever UF2 to the Pico drive
Pico should reboot in the usual mode now, copy your code and libraries
Next time configure the pins before building and powering the circuit
Testing out some time lapses while machining this motorcycle part. It’s a clamp to hold springer forks onto a CB750. Still learning feeds and speeds, but already an expert at making sharp things go dull!