Moving from MicroPython to CircuitPython

A project log for Picoth - 2FA Auth with Pi Pico

An easy to use yet secure 2FA gadget, using a Raspberry Pi Pico and RGB Keypad, MicroPython.

AngainorAngainor 03/22/2021 at 09:370 Comments

Micro python had almost everything we needed...

I had a prototype running and fully working. Just... no USB HID!

Since I saw no move on that front, was not capable enough to add USB_HID support to MicroPython, I had to choose:

- No USB HID, the user has to retype the code

- Move to Circuit Python

However CircuitPython (CP) is based on an older branch of Micropython (MP) , and comes with different features and architecture. USB_HID is supported on all boards however.

Whereas with MP you are likely to need to compile your extra libs and features yourself, with CP you can use the precompiled default firmware, since almost all extra libs are provided as .MPY, python bytecode.

This comes at the expanse of some performance loss, but makes it way easier for fresh users to experiment, since you don't have to compile anything.

Another strong feature of CP is the default "CIRCUITPY" USB disk that gives R/W access to the board flash.

For safety reasons however, it's likely we'll have to disable that - as well as the default REPL - for production release.

Now, for the migration part:

Pimoroni provided libs for MP, not for CP.

Also, CP has no support for interrupts nor threads (the Pico has 2 cores)

Hopefully, many Python devs experimented and gave snippets.

For instance, the adafruit "DotStar" lib can be used to drive the RGB leds of the keypad,

SandyJMcDonald wrote an awesome lib for another pimoroni keyboard, supporting decorators and making use of the keyboard very straightforward.

With that already done, I was able to assemble a working CP library for the Pimoroni RGB Keypad.

One major difference though: With MP I used interrupts, so the main loop was sleeping by default (most of the time) until a key was pressed. With CP, the main loop is constantly polling the keypad as fast as possible to catch key presses. I don't like that but there is currently no workaround.

Then came the screen part, Pico Display. CP has a ST7789 library, working with its Displayio abstraction layer. DisplayIO is a quite evolve library, allowing use of groups, scaling, layers, sprites, text....

On the other hand, it is way slower than the Pimoroni C library.

I still need to find out if this is due to python vs C alone, or an overhead due to the Display IO layer.

In the later case, use of lower level framebuffer objects could make it closer to the MP version.

Keeping the display fast is especially important in our case for several reasons:

- The OTP code is time sensitive. If it takes 1 sec to display it, this is significant (can be solved by drifting the time by as much as the latency)

- Since the main loop polls the keypad, anything taking significant time impacts the feeling of the keypad and needs prolonged press on the keys

As for now, I did remove the live rectangle that was showing the time left before the current code is no more valid to maintain the device responsive.

Current step is now to reasonably clean up the code, then I could release a first fully working repo!