CircuitPython – The easiest way to program microcontrollers
circuitpython.org
circuitpython.org
Embedded programming is, unfortunately, only suitable to a handful of languages that can operate with high speed and low memory use. At this time, they're C, C++, Rust, Zig, and ADA.
For example, on my embedded projects, I use Python to handle the webite framework, and to generate filter coefficients using Scipy, and plot data with MPL. I use Rust for the firmware.
There are plenty of applications where the performance or resource needs aren't great and the number of units being produced aren't sufficient to justify the marginal savings on a microcontroller. Then there are situations where it may be desirable to make it easy for multiple people to go in and modify a program on a regular basis, where languages like Python tend to be clearer at communicating intent since the low level implementation is handled by the language. (While you may be able to provide high level abstraction in languages like C, you cannot abstract away all of those details in C.) Of course, Python also provides an REPL. That can remove the need for developing your own command language for managing the device.
For some reason this feels like the same argument I had to present for the opposite situation, pointing out that sometimes optimized C or assembly code were necessary since there were cases where it is more cost effective to use microcontrollers that offered bytes of RAM or non-volatile storage. This is especially true when something is developed once, widely deployed, never modified, and does not need to be managed.
As with anything, it depends upon your application.
Being able to run code at runtime with no compile step also opens up the possibility of micro-controllers that can load "apps" or other user code at run time.
Somehow I don't think people would be this snobby about the advantages of an interpreted language if it was running lisp^1 instead of python. Of course to be fair if it was javascript they'd be twice as snobby and I'd agree with them...
[1]: https://thenewstack.io/nasa-programmer-remembers-debugging-l...
Challenge: Come up with a set of project requirements for a practical electronics device, and evaluate if Python is the right tool for the job. I'm suspicious you'll run into headaches with interrupts, DMA, concurrent processes interfering with each other due to taking up too much CPU time, onboard peripherals beyond the most popular in the most popular configs won't work etc.
* Must be able to communicate with arbitrary 3D printers over USB, should be able to act as a USB host.
* Must be able to load user programs/extensions.
* Must be able to connect to wifi and host a rudimentary web interface.
* Must have a color display and user interface including graphs.
* Must have a BoM cost of less than 40 US dollars.
---
I'd argue micropython would be the best choice for that set of requirements, as opposed to something like a raspberry pi. Not sure you can get an RPI with a display in that price range, but you can definitely get microcontrollers that support USB host and have a screen in that price range, in bulk and able to be incorporated into an actual product.
For the user plugin loader, you might be better off using a lua interpreter? I think micropython would still be a good choice for it though. Any thoughts on how you'd want to put something like that together?
CircuitPython is special-built for this exact task -- to make microcontroller work more approachable and accessible for beginners and/or projects with a small scope.
Anecdote: I used it a few weeks ago for a project that was small and had a tight timeline. As a beginner to electrical engineering with microcontrollers it was nice to not have to struggle through language syntax as well. This solved my use case perfectly.
It's not really the Python that makes the difference, it's the fact that all the common peripherals and happy paths are pre-written for your board/mcu.
My impression about modern embedded devices is that it's much less about bit-banging together 14 barely-compatible components with high timing requirements than it is just getting a battery-powered, wifi-connected, USB-compatible handful of COTS sensors online and dumping to your dashboard. Circuit Python seems totally reasonable for that.
These software platforms are sort of like little operating systems - from a practical standpoint a lot of the value comes from the hardware support. How useful it is depends on whether there is support for the boards and devices you want to use.
It's a subset of common lisp, and seems to be able to do a fair bit. The Python interpreters probably have a lot more community traction though.
I've been in this position and all I'd say is a little more complicated than that. I'm happy to learn other languages (in fact I am learning Rust at the moment), however I opt for CircuitPython a lot of the time because theres a job I need doing. Expanding your toolbox is great, and often having a project to work on with whatever your learning is a great way to do that, but sometimes you just have a job that needs doing, and in that case a language thats both fast to work with and your familiar with seems like an ideal choice, as long as your aware of the drawbacks of it.
Here I am working on a widget, it takes some sensors and runs some output. Well, I can prototype basically the whole thing using adafruit boards, quic i2c connectors, and do it relatively cheap.
Chips are cheap!
If I wanted to actually mass produce this, we would make our own PCB, integrate all the sensors onto a single board, and so forth, but for playing around with a concept? Yeah, I'll take adafruit and some adapters any day.
(Currently doing this right now for a pressure sensor that predates standard MAP sensors but operates similarly). If the concept is right... then we can think about making it for real real
I use micropython for developing embedded applications for industrial sensors. It is much faster to develop and I am fine using microcontrollers with enough memory that I do not need to optimize every last byte. Cost of the hardware is not the priority.
There are applications where there is not enough memory and python isn't the right tool. But in a world where microcontrollers keep getting more advanced and packaging more memory, claiming that languages like Python have no place is just as wrong as when people claimed Python had no place against C/C++ back when PCs were more resource constrained.
The economics for this type of question typically center around volume shipments. If you're shipping lots of hardware, optimizing hardware cost (and therefore minimizing software resource requirements) is the priority. If you're not, developer time is the main cost. There are a lot of products in the latter category.
In addition, connectors like Qwiic/STEMMA QT[3] make it possible to connect to a large number of sensors without needing a breadboard or having to solder anything. I've built a few projects with microcontrollers like these and Adafruit sensor boards and never had to resort to low-level languages.
[1] https://esp32s3.com/feathers3.html
[2] https://docs.circuitpython.org/projects/bundle/en/latest/dri...
[3] https://learn.adafruit.com/introducing-adafruit-stemma-qt/wh...
So cool to type code on the C/L and have it execute on the microcontroller and return a result back to your terminal.
I suspect Python on a microcontroller gives a similar experience/thrill.
[1] So chunky: https://en.wikipedia.org/wiki/Handy_Board
It left me quite surprised that a similar progression in interactive development tools has been, at best, a novelty item in the microcontroller world. Most microcontrollers are more capable and include the requisite UART, yet the only way you're going to interact with most of them is with a much more powerful computer and a frequently costly[1] hardware interface for debugging. While those are fine in most cases, there are times when I would have (figuratively) killed to be able to go in and change a couple of bytes.
[1] Yes, I am cheap. Incidentally, I think one of the brilliant things about the introduction of the Raspberry Pi Pico was not just having MicroPython available on the day of introduction, but instructions on programming a second identically inexpensive Pico to be an SWD.
In any case, can be good for PoC or similar things where your microcontroller is largely oversized for the application, but in practice you hardly can exploit your microcontroller's power using such a non-compiled high-level language. For a hobby project you can get a microcontroller that has 10x the actual power you need and use Python on it, but on an industrial scale it's not justifiable. 8-bit microcontrollers are still around for some reason...
When a microcontroller board with CircuitPython is connected to a computer it appears as a USB drive. To install your code and any supporting files on the board you just drag and drop them on the drive vs having to upload them using something like Thonny with MicroPython. Also when you drop your code on the drive the board automatically resets and begins executing the code. It also has some changes to make code more portable across the different microcontroller boards it supports.
One advantage of CircuitPython is that your board gets mounted as a volume like a USB drive, and you can just copy code.py onto it to install your program; it's just a more user-friendly experience. For comparison MicroPython only exposes a file system through a tool called rshell[1], that you need to use to copy code over. CircuitPython also seems to have a lot more libraries due to Adafruit's investment in this ecosystem, although I suspect that most of them could easily be adapted to work with both.
One of the key features of mpremote is that it allows folders to be mounted on your device from your PC.
For me, this allows a workflow that's even more efficient than using USB since no copying is required at all. Work on your PC (often using the unix port in a container [2] to test), then mount the folder and execute on the device. Brilliant. :)
I should probably write up how I use this workflow..!
It would be good to also allow USB volume mounting on more MicroPython ports (stm32 only) as - I agree - it's more intuitive for beginners. But LittleFS [3] is a much more robust filesystem than FAT, which is required for USB mounting. LittleFS is preferred by the core team and has had more focus recently.
[1] https://docs.micropython.org/en/latest/reference/mpremote.ht... [2] https://hub.docker.com/u/micropython [3] https://github.com/littlefs-project/littlefs
>but in practice you hardly can exploit your microcontroller's power using such a non-compiled high-level language
With micropython you can mark a function to be compiled, or even write a function as inline-assembly. Like normal python develop quickly and optimize the expensive parts. Micropython makes it quite easy to optimize the expensive parts with the viper code emitter and inline-assembly options.
It's ok for prototyping, I would not use it on production. Still recommend using C++, and Platformio for most things.
But it helped me with quick hacks and proofs of concept.
For example, my company build a laser warning system that would be triggered when someone cut through the laser. I build a quick remote control to trigger the system without having to get on a ladder and put the hand in front of the laser to diagnose problems.
That is it in a nutshell. Its a Adafruit fork to conjoin the best of both worlds - adafruits simple boards and python as a easy language with which to get started. or to PoC something quickly.
I've not used a pico but other microcontrollers with c++ interfacing tools, and my thoughts are these things don't have interpreters onboard so the language choice is likely not that important. But I'm limited to TI boards.
So if you ever find that you need more performance you can drop into C, write a user module, and get the benefit of easier Python syntax and C performance.
The only reason some hardware features aren't supported is a lack of effort to expose those features. Come help us fill in the gaps! :P
[1] https://www.youtube.com/watch?v=437CZBnK8vI (Not my best presentation, I'm sorry; I was running on very little sleep and a high degree of stress!)
C++ is high level enough that I always assumed much of that work was already happening for microcontroller work.
Do you write embedded code professionally?
But I do as a side gig.
Me and a friend to small projecrts for smartcities like interative propaganda totens, wifi access points, smart traffic warnings. Things like that.
I also programed some small scale things in my last to job. One of them was a tamagotchi. I did not filmed the completed version, but I done a video testing the animations: https://youtu.be/fltoTmUJPBE
But it all depends of what you need to do with it. Like would I put python in something that someone can get hurt if it dosen't work ? Not. For things like just printing information in a OLED display? Sure, why not. Its easier to mess around with strings in python.
Wait, where have I heard this before, and with the capacity to expand your language to meet your needs at near close to the wire speed without the needs for all the resources needed by MicroPython... Forth any one?
Extremely impressive in that regard, although I might switch to C++ later if the response seems slow.
Altogether, I think CircuitPython (and MicroPython, of which I own the original development board) is an amazing achievement given the number of boards it currently runs on and the state of affairs we were in a decade ago…