Arduino vs CircuitPython for Microcontroller Programming
August 14, 2024
Blog
If you’re starting out in the world of microcontrollers and dev boards, you may find yourself faced with a fundamental question: Arduino or CircuitPython? Some of the same considerations will also apply to MicroPython–which you can read about here–but I’ll table that discussion to keep the scope reasonable.
The CircuitPython language can run numerous development boards, which generally need to be flashed with a UF2 file found here. Arduino can refer to development boards made by Arduino (or many others, depending on your definition), and/or that are programmed with Arduino’s derivative of C (Arduino C), often using the Arduino IDE. This article will focus on the languages themselves.
Article TL;DR: Arduino C computing performance is better. CircuitPython is easier to program and modify. Which is actually better and depends on the situation and the person doing the coding.
Compiled Language (Arduino C) Vs. Interpreted Language (CircuitPython)
Arduino C is a compiled language, meaning that when you write a program, your computer then compiles it, AKA turns it into machine code for the microcontroller to use. CircuitPython is an interpreted language, meaning that it stores the actual human–or even AI–written code on the microcontroller. It then interprets this human code at runtime. This runtime interpretation requires significant computing resources.
Arduino C can run on more devices than CircuitPython per CircuitPython’s greater resource needs. If you specifically need to work with a certain device, first check to see what language(s) it uses. If it’s Arduino C-only the choice may already be made for you.
Arduino C Programming
Caption: Arduino C programming in the Arduino IDE / Image Credit: Jeremy Cook
With machine code loaded directly onto the microcontroller, it doesn’t have to figure out–interpret–the C programming at runtime. This allows for fast and efficient microcontroller usage. If you’re familiar with C, Arduino C should be easy to learn, but starting from scratch can be challenging.
The other big challenge with using Arduino C is that the IDE needs information on each board/microcontroller to interpret code for that individual system. It also needs the required libraries to concoct a compiled mass of 1s and 0s. While setting up an Arduino programming environment won’t be a huge challenge for experienced programmers, it can represent a significant learning curve for beginners.
Additionally, since a board programmed in Arduino C doesn’t have the original code stored onboard (only machine code) you’ll need to find a copy of this elsewhere to make changes. That’s a lot of work if you just want to change a value or two.
CircuitPython Programming
Caption: CircuitPython programming in the Mu editor / Image Credit: Jeremy Cook
CircuitPython takes a different approach, in that your actual code is loaded onto the microcontroller, which it then interprets at runtime. Naturally, this adds a significant amount of overhead. As seen here, it can take CircuitPython code around three times as long to do a calculation as its Arduino C equivalent. So, if computing resources are limited, CircuitPython may not be your answer.
The advantage of CircuitPython is its ease of programming and modification. CircuitPython is generally considered easier to learn than Arduino C–though to be fair there are more learning resources available for the Arduino ecosystem as it is much older. Perhaps more importantly, since code is stored directly on the CircuitPython board–and since it shows up as USB storage when connected to a computer–it can be read and modified directly. Just open the program’s text file (generally code.py) with the Mu editor, or even a generic text editor*, make changes, save, and it reboots running the new code.
So, changing variable X doesn’t require tracking down the original code, libraries, and board definition. Just make the changes and save. If you need an additional library or other files, you can drag them onto the CircuitPython drive as you would with a USB thumb drive. To program a board from scratch, you will first need to load the appropriate UF2 file.
Should You Use Arduino C or CircuitPython? It depends. I’m personally more comfortable with Arduino C as I’ve used it for longer, but I tend to drift back and forth depending on my focus at the time.
For instance, my MIDI Spoon Piano, seen in the video below, uses a Raspberry Pi Pico. Here I could use my Pico Touch 2 PCB with it, along with unmodified code from todbot, making coding a matter of flashing and copying everything correctly. Of course, this drop-in coding did take some careful hardware consideration.
On the other hand, when I decided to make the world’s smallest MIDI controller, which runs on an ATtiny85 and is powered by a CR2016 battery, CircuitPython was out of the question. In this case I wrote my own code, and included the excellent TinySnore library to keep it running on its minuscule power source.
All that being said, the best choice for your system depends on the situation. If fast development time is a priority and computing/power resources are plentiful, then CircuitPython is worth consideration. If actual computing performance is a bigger issue, Arduino C is probably the better choice. You’ll also need to consider your particular programming strengths. If you’re starting from absolute scratch, CircuitPython would generally be considered easier to learn, however, there is a massive amount of learning resources available for Arduino C.
If I had to choose just one, I’d probably go with Arduino C. Given that I do a monthly Developing With Arduino class, it would be hard not to. However, I like both programming methodologies, and wouldn’t be too happy about limiting my choices!
Note:*This has been problematic on my MacOS system, YRMV