Python Optimized for Microcontrollers

MicroPython Optimizes Python for Microcontrollers

By Jeff Tranter

Python is one of the most popular and fastest growing programming languages. It is the recommended language on the Raspberry Pi platform (where Pi is a reference to Python Interpreter) and is increasingly used on desktop applications. The Qt Framework, for example, has an officially supported Qt for Python that allows developing Qt-based applications entirely in Python.

For hardware platforms with limited resources, like a microcontroller, you would think that a language like Python would not be a viable option — but that is exactly what MicroPython is for. In this post I'll take a brief look at MicroPython and discuss its capabilities, pros and cons.

What is MicroPython?

MicroPython is an implementation of the Python 3 programming language that is optimized to run on microcontrollers. It includes a small subset of the Python standard library. With only a few exceptions, it is a full implementation of Python 3 but can run on "bare metal" (i.e. a platform with no underlying operating system) within as little as 256K of storage and 16K of RAM.

It was initially offered on the STM32-based pyboard platform but has since been ported to a number of microcontrollers, including those based on the STM32, Teensy, ESP32 and ESP8266, and BBC Micro Bit. Most recently, it has been officially supported by the $4 Raspberry Pi Pico board.

It is open-source software, released under an MIT license.

Pros and Cons

A term you will often see referenced in relation to MicroPython is REPL. It stands for Read Evaluate Print Loop. An interactive programming environment like MicroPython (or standard Python) provides the programmer with an interpreter that can read a line of user input, evaluate it as Python code, print the results, and loop back for more input.

One of the advantages of such an environment is being able to experiment with and prototype code without going through the typical edit/compile/upload/run cycle of a fully compiled language. Thus, a major strength of MicroPython is being able to quickly test new code either interactively or by simply uploading or copying the commands to the embedded board. This can significantly reduce development time.

Another advantage of MicroPython is that it is a higher-level language than alternatives like C or C++. Unlike these languages, you don't have to deal with language constructs like pointers or worry about memory management, and you have access to features like high-level container classes. Python is a much easier language to learn than C or C++ and allows developers to be more productive.

The main downsides of MicroPython are performance and resource requirements. You need to include the MicroPython code itself and you can't achieve the same level of performance that you can with native C or C++ code.

In many applications, the performance of MicroPython is acceptable as functions like GPIO, SPI and I2C are implemented as libraries in native code, and the benefits in reduced development time outweigh the other drawbacks.

Development and IDE Options

In the simplest case, you can do development over a serial interface, but typically you will want to use some kind of integrated development environment (IDE). There are numerous options, including Thonny, Visual Studio Code and PyCharm.

The Thonny IDE

The latest version of the Thonny IDE on the Raspberry Pi has seamless support for the Raspberry Pi Pico and will even download and install MicroPython on the Pico for you.

A Code Example

Below is a simple MIcroPython example of toggling a GPIO pin on the Raspberry Pi Pico, in this case the GPIO line connected to the on-board LED:

import utime
import machine
led = machine.Pin(25, machine.Pin.OUT)
while True:

The same code written in C would be significantly longer.

Regarding performance, I found that I could toggle the LED at a rate of up to about 56 kHz from MicroPython, whereas with code using the C APIs I could toggle them up to about an 18 MHz rate. However, there are more efficient ways to do this on the Raspberry Pi Pi in MicroPython, such as using PWM support (which let me achieve a 9 MHz rate) or making use of the PIO (Programmable Input/Output) hardware, which can be controlled from MicroPython.

An Alternative: CircuitPython

An alternative fork of MicroPython called CircuitPython was created by Adafruit. With a focus on education and ease of use, it runs on several microcontroller boards offered by Adafruit.

Closing Thoughts

The idea of a high-level language for microcontrollers is not entirely new. While early 8-bit microcontrollers were often programmed in assembly language, devices such as the BASIC Stamp series from Parallax offered a Basic language interpreter on-board, but were aimed more at education and hobbyists. Modern 32-bit microcontrollers with more memory and storage have made it feasible to run a more powerful language like MicroPython.

In my experience using MicroPython on a Raspberry Pi Pico, I found it very easy to set up, easy to program and highly compatible with the full Python 3 language. You even have access to a filesystem, something you would not otherwise have when programming on bare metal.

While I don't see MicroPython becoming the dominant programming language for microcontrollers, it can be a viable option for education, initial prototyping, and development of small on-off projects where performance is not as important as development time.

I expect its popularity to increase now with the support of the Raspberry Pi Pico. Several million Pico boards quickly sold in the first few months after release, and the high-quality, user-friendly documentation on MicroPython for this platform is attracting a new generation of developers who want to use the language and hardware for physical computing applications where a microcontroller is well-suited.

For more on developing with microcontrollers, check out our series The Smart Revolution.