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.
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.
In general with the the embedded Pythons, they are 2 or 3 orders of magnitude slower than C (big surprise) and they don't support all the hardware features. By necessity, they have a one-size-fits all approach that works fine for hobbyists but might not be sufficient for production. That all said, I love to bang out a prototype or one-off project with CircuitPython or MicroPython. Or Arduino if it makes sense.
I never had to do something that could not be done with python. Probably some libs for more exotic hardware, but depending of how you program you can loose events like button presses if you do not consider the slow response time in python.
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
They're slower if you spend cpu-intensive time in the interpreter. If you're calling wrappers for C functions then there's little difference. For example, sending SPI or I2C data are effectively identical. Same too if you want to render a QR code using a C library for example [1].
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
I haven't really needed much added to MicroPython or CircuitPython for my use cases, but I see people on r/python or r/iot or wherever gripe occasionally. Thanks for the video link!
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.
On the website: "CircuitPython is a programming language designed to simplify experimenting and learning to code on low-cost microcontroller boards."
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.
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...
Being able to load extensions at run-time could be a pretty big advantage. Have "apps" you can install on the micro-controller.
>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.
From the top of the webpage, "CircuitPython is a programming language designed to simplify experimenting and learning to code on low-cost microcontroller boards." It targets beginner hobbyists and the lower grade education market. The changes from MicroPython are designed to make getting code on to the board and executing easier for those users.
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.
On the other hand, with a Raspberry Pi Pico board selling for $4 and the chip going for <$1 in bulk, I'm guessing that for small-scale manufacturing, going cheaper isn't worth the hassle? It depends what the market is.
CircuitPython is a fork of MicroPython, and they periodically bring in commits from MicroPython to stay up to date.
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.
Various MicroPython implementations, specifically the STM32 port (which runs the PyBoard), expose their filesystem as a USB mass storage device that you can copy files into directly. So I wouldn't say that it's exclusive to CircuitPython by any stretch.
RShell is a nice tool but the 'official' way to interact with a MicroPython device is with mpremote [1].
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.
My suspicion is that this, and MicroPython, which it's based off, are designed for people who know Python, and are hesitant to learn another language, or expand their toolbox. Python is a great language in some domains. For example, numerical computing, web servers, and scripting.
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.
It's really quite nice to be able to telnet into a running micro-controller (over wifi even!), play around with pins directly, all that.
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...
It's not about being snobby - it's about choosing the right tool for the job.
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?
Having just used it to interactively play around with PWM settings controlling some motors and solenoids for a music project, I found it much more useful than compiling a new firmware and flashing the microcontroller for every tweak I'm making. I don't have a very compelling reason to port it to anything else at this point, for doing control-rate (in other words: slow) updates to PWM outputs on a microcontroller, it works perfectly.
If you're doing any serious amount of work in any situation then I agree with you, but sometimes the best tool for the job is the one that gets the job done.
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.
We're getting lost in the weeds a bit. All the examples and "fast prototyping" mentioned in these threads are possible because someone wrote _C_ code to handle the 80% of common use cases then wrote python bindings to make it easier to write.
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.
Yes, and using C++ based systems like Arduino and PlatformIO seems similar. Those of us who use them are hoping not to have to write our own device drivers, though it's certainly possible when needed.
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.
Requirement: when someone opens your front door, closing the contacts of a magnetic reed switch, send a (hard-coded) http message to a serverless function.
I remember the "Handy Board" [1], a 68HC11-based micro-board (that came out of MIT?) that had an amazing "Interactive-C" language. C code was compiled to a byte-code that was interpreted in real-time on the Handy Board.
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.
I've recently been watching some videos of people resurrecting mid-1970's vintage computers based upon the then new microprocessor. Even though the base configuration of these machines came with about a kilobyte of RAM and a similar amount of ROM, they managed a degree of interactivity through a machine language monitor. Of course, upgrading the memories allowed for more sophisticated interactive languages like BASIC.
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.
> designed for people who know Python, and are hesitant to learn another language, or expand their toolbox
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
> Embedded programming is, unfortunately, only suitable to a handful of languages that can operate with high speed and low memory use.
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.
A broad statement such as this inevitably gets it wrong.
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.
As others have mentioned, you don't always need the full performance of these microcontrollers, and many are pretty powerful to start with. An ESP32-S3 has two cores running at 240 MHz, and boards that ship with 8 MB of RAM and 16 MB of flash for $22[1]. They also have WiFi, BLE, and tons of pins. This is more than enough to run many programs with CircuitPython, and the number of libraries available for it[2] makes it incredibly easy to get started building small projects.
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.
Hi, what is really cool about micropython is, rapid prototyping on the CU, which allows for real time interactivity with the HW, see what you are doing on the board. All this without and IDE, just a shell command!
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…
45 comments
[ 4.4 ms ] story [ 111 ms ] threadIt'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.
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.
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
C++ is high level enough that I always assumed much of that work was already happening for microcontroller work.
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!)
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.
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.
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...
>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.
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.
[1] https://github.com/dhylands/rshell
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
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.
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.
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.
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
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.
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...
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…