MicroPython And CircuitPython Are More Alike Than Different

I want to learn how to work with RP2040-based microcontrollers, and I like the idea of working in a high-level language like Python. Or at least, I would like to give it a shot. Reading about Python for microcontrollers quickly run into two names: MicroPython and CircuitPython. Looking around for information on why I might choose one or the other, I found a wonderful comparison guide published by Adafruit. Based on this information, I now feel more comfortable starting with CircuitPython.

For me, the most important piece of background is that CircuitPython is built as a fork of MicroPython, with enhancements focused on beginner friendliness (an Adafruit signature) versus full support for all features. For someone learning to blink a LED, CircuitPython aims to be the best solution. Beyond the basics, intermediate level projects (where I feel I fit) are likely to be served equally well by either platform. Advanced features like threading and PIO are where CircuitPython concedes to MicroPython, but speaking for myself I won’t have to worry about that for a while if ever. And even if I find myself in a situation where I need to switch, I’m comforted by the claim 95% of knowledge will transfer directly between the two platforms.

What will likely swing the decision for most people are software modules they want to pull into their project. And here I think CircuitPython will take the lead for my scenarios. I buy a lot of stuff from Adafruit, and they are likely to provide CircuitPython libraries for those components. So that covers a lot of hardware which also serves as example code to learn from if certain hardware is not explicitly supported. And following my earlier search for a MicroPython web server with WebSocket support, I found that CircuitPython offers a counterpart httpserver which should be sufficient for my rover project purposes. Looks good enough for me to dive on in.

Dusting Off Adafruit KB2040

My latest distraction is a Raspberry Pi Pico W, a promising alternative to ESP32 for a WiFi-capable microcontroller board. After a cursory experiment with a single LED, I’m ready to connect more components to the board to explore its capabilities. Since it’s new hardware, though, there’s always the chance I’ll goof up somewhere and destroy the microcontroller. I don’t want to take that risk because I’m borrowing this particular Pico W. It’s not mine to blow up! Thinking over my options, I remembered that I already had microcontrollers built around the same RP2040 chip: a pair of Adafruit KB2040.

I got my KB2040 as an Adafruit promotion. They typically have something set up to entice us to put a few more items in our shopping cart, and these were “Free KB2040 with $X dollar purchase” type of deal I got across two separate purchases. As the product page made clear, KB2040 was designed for people building their own custom keyboards. So it was built to be physically compatible with an existing board (Pro Micro) popular with that niche. I had no intention of building my own custom keyboard, but I thought the RP2040 chip was worth a look at some point in the future. That time is now.

There are a few tradeoffs of using a KB2040 to substitute a Pico W. The first and most obvious problem is the fact KB2040 doesn’t have the WiFi/Bluetooth chip, so I could only practice aspects of programming a RP2040 before I bring in wireless connectivity. Equally obvious is the different physical form factor, which means a different pinout. I didn’t think that was a huge deal because I’m not trying to install the board on anything that expects a specific pinout. I printed Adafruit’s pinout reference chart and I thought I was good to go, but I wasn’t. While the RP2040 chip lies at the heart of both a Pico W and a KB2040, they have different peripheral chips. This means I’d need a KB2040-specific build of software and it is not on MicroPython’s list of supported Adafruit boards. D’oh! Fortunately, Adafruit supports KB2040 for CircuitPython. Is it close enough for my purposes? I now have motivation to find out.

Notes on “Connecting to the Internet with Raspberry Pi Pico W” eBook

After getting my bearings with the “Raspberry Pi Pico Python SDK” eBook, I checked out the Pico W-specific “Connecting to the Internet with Raspberry Pi Pico W“. This volume is even smaller at 49 pages, fitting for an quick introduction to potential of Pico W connectivity. It felt to me like the word “Connecting” in the title is quite literal: this title covers how to establish a connection and not much else on what to do after you connect. Perhaps the authors believed that networking APIs are common with existing platforms. So maybe once we get a Pico W set up enough to connect, everything else will be the same as existing general resources out on the internet? That seems unlikely but maybe a valid stance for an introductory title.

But while the word “Connecting” might be literal, the word “Internet” is not. This book actually goes beyond Pico W’s WiFi connectivity and also covers its Bluetooth LE capability. BLE is not typically used to connect to the internet. It appears the Pico W is also capable of Classic Bluetooth, but this book doesn’t spend much time on that beyond mentioning it was possible.

This book also covers each concept twice: once with the C/C++ SDK, then again with the MicroPython SDK. Seeing them side by side really brought home the fact MicroPython code is generally easier to read. But sadly, the language can only do so much. Bluetooth LE is full of esoteric overhead that needs to be configured no matter the language. An uninformative barrier against beginners trying to learn the technology. While reading one particular example’s MicroPython code in the PDF, I got tired trying to parse BLE minutiae and it occurred to me… I don’t remember reading anything equally dry in the C section. I scrolled back up and that’s when I realized the book authors gave up: there was no C section. Instead of cluttering the book with a bunch of code dealing with C overhead plus BLE overhead, they just said the example code is on their GitHub repository. With a URL for the C developers who care to go wading through it all.

This book tried to cover WiFi, Bluetooth Classic, and Bluetooth LE connectivity enabled by a Pico W over its non-W counterpart. And cover those topics via both C and MicroPython languages. That’s a lot of ground to cover in 49 pages, resulting in a book that feels more like a Getting Started pamphlet. Which is a valuable resource! It was just less than what I had hoped.

Notes on “Raspberry Pi Pico Python SDK” eBook

I’m playing with a borrowed Raspberry Pi Pico W, and thought I’d play with MicroPython on it. That software platform seems to have support direct from Raspberry Pi, which is always promising. I thought perhaps it might even get equal billing with the traditional C-based platform! Well, as soon as I opened up Raspberry Pi Pico Python SDK ebook I knew they were not equal. Despite the usual warning not to judge a book by its cover or length, the fact is there are 54 pages in the Python SDK ebook which is barely 10% of its counterpart C SDK ebook‘s 523 pages.

But I don’t necessarily see that as a bad thing. The advantage of a smaller book is that it’s easier for people to read through and absorb, which aligns with the goal of having Python on a microcontroller to begin with. The book frequently refers the reader to the C book for details not specific to the language, such as details on working with the programmable input/output (PIO) blocks. Writing PIO code is little different from writing in assembly language, and a challenge I intend to tackle sometime in the future.

I was happy to see the prebuilt MicroPython distribution binary for Raspberry Pi Pico W was generated by MicroPython organization, instead of a separate fork maintained by Raspberry Pi. This should mean features are introduced in step with the rest of the MicroPython ecosystem and not lagging behind waiting for someone else to integrate upstream changes.

Another item I was happy to see was a Visual Studio Code extension to ease working with MicroPython. MicroPico, formerly Pico-W-Go, promises a lot of convenience over using a serial terminal like PuTTY, which was what I did before. I’ve become familiar with VSCode so I’ll use the extension first, but people without such affinity have other options like the popular Python IDE “Thonny” and a command-line based “rshell” tool that should be useful for scripting.

Trying MicroPython Again This Time On Raspberry Pi Pico W

I’ve borrowed a Raspberry Pi Pico W for experimentation. I’ve verified it could easily integrate into Home Assistant via ESPHome. (Which is now somewhat misnamed as it works for more than just Espressif ESP chips…) For my next set of Pico W experiments I decided to give MicroPython another try. I tried MicroPython earlier on an ESP8266 and it was not all smooth sailing. Looking for an existing solution to my problem was actually the reason I stopped my MicroPython experiment and found Home Assistant and ESPHome! So this is sort of coming full circle.

The main reason I wanted to give MicroPython another try was the fact Raspberry Pi foundation listed C and MicroPython SDKs side by side as software development platforms for Pico and Pico W boards. This implies MicroPython is treated as a first-class citizen and supported directly from the source. Will actual reality live up to this implication? I don’t know yet but I’m willing to find out. This is also why I’m trying MicroPython before investigating Adafruit’s CircuitPython for the board. As much as I love Adafruit, direct manufacturer support is very compelling.

The obvious criticism of MicroPython is runtime performance. I will have to see how much of a problem it would actually cause for my projects. I’m cautiously optimistic runtime performance will not be a hindrance for two reasons. One, hardware peripherals can handle most performance-critical tasks asked of a microcontroller, and that will largely be the same whether overarching high level application code is in C or in MicroPython. What if there isn’t an applicable hardware peripheral on the RP2040 chip? That leads to the second reason: RP2040’s programmable input-output (PIO) capability. Proven to be adept handling tasks that would otherwise need to be written in low-level interrupt handler code, if it can be implemented that way at all. Sounds like a potentially fun playground to see if reality lives up to theory. I’ll start with the PDF published by Raspberry Pi to guide curious Python developers to Pico W.

Easy To Get ESPHome On Pi Pico W

After borrowing a Raspberry Pi Pico W board to play with, I had many ideas I wanted to try out. The first test was Home Assistant support via ESPHome, and this was a success. In fact, I think getting ESPHome started on a Pico W is even easier than doing the same on their namesake Espressif boards.

A tremendously useful feature of ESPHome is the ability to perform updates over WiFi. This over-the-air (OTA) capability means every ESPHome-powered node in a Home Assistant network can be updated wherever they are around the house, no need to bring them back to a computer with a USB cable (or bring a laptop with USB cable out to them). However, this only works after ESPHome is already running on board, which means initial ESPHome setup on a microcontroller still require a USB connection to install a compiled binary file.

For ESP8266 and ESP32 board, this means connecting it directly to the computer running Home Assistant which can get complicated depending on how Home Assistant is set up and whether its ESPHome plug-in can access USB ports. Alternatively, it can be installed by an ESPHome web tool. Or we can install Espressif’s esptool flash utility on a computer. So this is a solvable problem.

But a Pico W has an even easier way: do it on any modern computer, no software installation required. Because when we hold down the “BOOTSEL” button upon powerup, the Pico W presents itself as a generic USB storage device, to which we can copy the compiled binary file (it has a *.uf2 extension) and the Pico W is off and running. Very nice!

As is typical microcontroller practice, my “Hello World” is to connect a LED to my Pico W and toggle it on/off from Home Assistant. I saw an onboard LED, labeled GPIO25 on a pinout chart, and thought I would use that. When that didn’t work, I looked closer and realized I had mistakenly referenced the pinout chart for a Pico (not W) and Pico W’s onboard LED is actually connected to its WiFi chip instead of 25. Oops! It’s not clear to me where pin 25 was routed on a Pico W, so I switched gears: I connected an external LED with current-limiting resistor to pin 15. And since the board was already running ESPHome firmware, I could do an OTA update to use pin 15 instead.

New Toy: Raspberry Pi Pico W

For the past few years, an ESP32 has been my microcontroller of choice for wireless network-connected projects. Its extensive list of hardware peripherals attract attention from those curious what they can do with such a flexible tool, so now we enjoy a huge online community providing reference support for hobbyist projects like mine. It’s a good situation! People have managed to do some pretty amazing things with ESP32 peripherals, pushing them beyond their original design intent. Espressif has been riding the wave, releasing many chips under the ESP32 umbrella with different peripherals and sometimes even different core CPU architecture. (RISC-V in addition to Tensilica.) To maintain software compatibility throughout their product line, they kept a single SDK (ESP-IDF) for all their different ESP32 variations. Unfortunately, maintaining that commonality meant certain wild features had to be deprecated or removed because they would work on some chips but not others. This has the side effect of crippling certain creative off-the-beaten-path hacks.

With confusion rising between ESP32 variations and restricted/deprecated ESP-IDF features, people started looking at alternatives. While discussing ESP32 projects with a few other local makers, the topic switched to one of the new hotness: Pico and its WiFi capable counterpart Pico W by the Raspberry Pi foundation. In addition to a lot of good (if relatively standard) features, it has a novel feature of programmable input-output (PIO) state machines. I understand it as way to create custom digital logic at a lower level than C code running on the main CPU but at a higher level than FPGAs. I’ve read about some pretty interesting ways people have applied PIO to solve problems otherwise tricky to do on a microcontroller.

I agreed that a Pico W sounded interesting to investigate at some point, and one of the people present offered to lend me one they are not currently using. Well, it’s tough to turn down such an opportunity! With a unit in hand, learning how to work with this microcontroller has been vaulted to the top of my project to-do list. My first test: connect it to my Home Assistant.