It would not be at all original to declare that Python is the new BASIC. Like BASIC, it has been the first programming language for a whole generation of coders, and its main advantage is that it’s quick and easy to write in. Like BASIC it is an interpreted language, and thus rather slow to execute.
Thus while CircuitPython can be very useful for beginners and quick projects, it hits the limitations of the hardware far sooner than it needs to — unless you can pre-compile critical parts of the code, which you now can, thanks to CircuitPython Turbo by [Mikey Sklar] with some help from Anthropic’s Claude LLM.
Now if that sounds a lot like MicroPython’s ‘Viper’ and machine-code compiler, that’s because it is. CircuitPython is a fork of MicroPython with some handy extras on Adafruit boards, but Viper wasn’t one of them until now. Before the Turbo version, CircuitPython only ran in interpreted mode.
Like MicroPython, using CircuitPython Turbo you can flag sections to run as ‘native’, where instructions are compiled but values stay as python objects, which gets you about a 3X speedup. A little more rewriting to declare your variables and pointers and you can use ‘viper’ mode, which can — depending on what you’re up to — result in a 20x to 70x speedup. In Adafruit’s documentation, they demonstrate a Metro RP2040 calculating the Mandelbrot set 3x faster in Native and 19.7 times faster with Viper than normal Python bytecode.
The one thing that we miss from BASIC that CircuitPython Turbo doesn’t give is inline assembly– though interestingly enough, that is in the upstream MicroPython implementation, so perhaps its day will come here too. Not every job is suited to the use of Python on microcontrollers, but we’ve seen it used for everything from e-bikes to a Winamp-inspired music player.

It’s about as interpreted as Java and C# are. Please don’t apply Ousterhout’s False Dichotomy to modern programming languages, it doesn’t work here.
This. Python has been compiled to bytecode run by an optimized interpreter for over a decade now. And for those who don’t know, a bytecode interpreter is just a less pretentious term for a virtual machine that executes bytecode (rather than emulating an actual real world machine architecture), which is what Java and C# call exactly the same thing.
Python used to be an “interpreted language” the same way Basic was (by the mid-1990s, most practical versions of Basic came with a native compiler, so you could run programs in interpreted mode or you could compile to native). Modern Python is only actually interpreted on a handful of old, 3rd party implementations, of which CP and MP are not. (And you can see this by writing a Python module, and then importing it into your main program. With desktop Python, you’ll find a CPY file, which the compiled bytecode. The main program is generally compiled to memory and run directly from there, so it doesn’t save the CPY file.)
But yeah, Python hasn’t been an “interpreted language” in a long time.
Insert
“look what they need to mimic a fraction of our power”
Meme with C-programmers
I wonder why CircuitPython still exists. The small differences (autorun, some libraries) seem like they could be just add-ons on top of regular MicroPython.
Cause if you stay in the lanes a 7 year old can make a finished project well before one could find out micropython is kind of a pain in the dick
lol, just like everyone in the python forum moderation pool.
It is a commercial gimmick oriented towards selling Adafruit boards. They’ve build for example a consistent display driver that can use different TFT chipsets, at the price of an ugly chain of deps.
I avoid it like plague, and find the Adafruit attempts to lock in an ecosystem at best nefarious for Micropython. Instead of contributing, they forked, this is the original sin.
The “upload by copying to a drive” workflow is miles better. No messing with editors in a browser, just write code in your preferred editor, then copy it however you like (I have some shell functions to sync code.py and the rest), along with circup to keep libraries updated, the workflow is just so much more “normal” and less painful.
Granted, it’s not on every board supported by CP, but since nothing supports it for MP…
BS. That´s what mpremote is for.
i found mpremote to be tedious and slow. rather just use the tools that already exist for file management. not to mention being to able to bypass copying at all and directly edit for really quick (& dirty) tweaks.
Not sure how open-source frameworks and drivers, with a consistent API across a large variety of devices (a large amount of which, perhaps the majority by now, are not even adafruit products) is really a poweful “lock-in”
Not sure which OS you’re using that has mpremote installed by default.
Nothing is more universal than USB file access and nano (or notepad, or whatever). Open file, save file, done.
Any project can be edited anywhere.
It’s not installed by default but is literally only
uv tool install mpremote. Not exactly challenging. Or you can use ViperIDE and have most of the features baked-in to the browser without installing anything (useful on Chrombooks for example).USB mass storage is supported on many of the MicroPython ports – and was implemented on the original PyBoard over a decade ago. But it necessitates using FAT FS which is easily corruptible – try pulling the power after copying a file. So MicroPython defaults to Little FS and discourages FAT FS use.
In any case, even when I’ve had USB MS, the workflow using mpremote is faster and more convenient. Particularly using
mpremote mountwhich just mounts your PC filesystem on your device.I agree with the sentiments of the others, but want to add that micro python has syntax differences with standard python, whereas circuitpython is identical, allowing you to move code to and from python/circuitpython without modification.
The differences in Python syntax between MicroPython and CircuitPython are minimal. Do you have any examples?
I tried using viper for a project. I had made a custom compression protocol for sensor data. I had no problem writing the code in normal Python and in C. But Viper is this super limited version of Python where you don’t even get arrays. Everything is pointer arithmetic. But things like integer promotion, casting, pointer types, etc. don’t really work very well. It’s more like a limited and hard to use version of C than it is Python.
And since you can call the normal easy version of C from micropython, I just did that instead. And it’s faster.
Micropython has had inline assembly from fairly early. Damian George demonstrated 4 ways to improve performance in 2018. I have tried them in comparing ESP32 and STM32F407 and they were nearly identical. Some processes were 200 times faster. https://www.youtube.com/watch?v=hHec4qL00x0
This is a superb talk. I’ve watched it a few times.
His informal mpremote tricks video is equally must-watch: https://www.youtube.com/watch?v=EVJA01W9ArI
(I mean, he would know. He’s the guy who developed Micropython after all…)