Recent from talks
Contribute something
Nothing was collected or created yet.
CircuitPython
View on Wikipedia| CircuitPython | |
|---|---|
Logo of the Blinka library, a compatibility layer for CircuitPython | |
| Original author | Adafruit Industries |
| Initial release | July 19, 2017[1] |
| Stable release | 10.0.3[2] |
| Repository | https://github.com/adafruit/circuitpython |
| Written in | C[3] |
| Platform | Supported microcontrollers and single-board computers |
| Type | Python implementation |
| License | MIT license[4] |
| Website | circuitpython |
CircuitPython[5] is an open-source derivative of the MicroPython programming language targeted toward students and beginners. Development of CircuitPython is supported by Adafruit Industries. It is a software implementation of the Python 3 programming language, written in C.[3] It has been ported to run on several modern microcontrollers.
CircuitPython consists of a Python compiler to bytecode and a runtime interpreter of that bytecode that runs on the microcontroller hardware. The user is presented with an interactive prompt (the REPL) to execute supported commands immediately. Included are a selection of core Python libraries. CircuitPython includes modules which give the programmer access to the low-level hardware of supported products as well as higher-level libraries for beginners.[6]
CircuitPython is a fork of MicroPython, originally created by Damien George.[7] The MicroPython community continues to discuss[8] forks of MicroPython into variants such as CircuitPython.
CircuitPython is targeted to be compatible with CPython, the reference implementation of the Python programming language.[9] Programs written for CircuitPython-compatible boards may not run unmodified on other platforms such as the Raspberry Pi.[10]
Usage
[edit]CircuitPython is being used as an emerging alternative solution for microcontroller programming, which is usually done in C, C++, or assembly. The language has also seen uptake in making small, handheld video game devices.[11][better source needed] Developer Chris Young has ported his infrared transmit-and-receive software to CircuitPython to provide interactivity and to aid those with accessibility issues.[12]
Community
[edit]The user community support includes a Discord chat room and product support forums.[13] A Twitter account dedicated to CircuitPython news was established in 2018.[14] A newsletter, Python on Microcontrollers, is published weekly since 15 November, 2016 by Adafruit to provide news and information on CircuitPython, MicroPython, and Python on single board computers.[15] A Reddit subreddit, r/CircuitPython, provides news on CircuitPython and related news and projects and has about 4,300 members.[16]
Hardware support
[edit]As of July 6, 2025 version 9.2.8 supports over 608 different micro controller boards[17]
The version 9.1.0 supports a range of platforms, called "ports":[18]
- atmel-samd: Microchip SAMD21, SAMx5x
- cxd56: Sony Spresense
- espressif: Espressif ESP32, ESP32-S2, ESP32-S3, ESP32-C2, ESP32-C3, ESP32-C6
- nordic: Nordic nRF52840, nRF52833
- raspberrypi: Raspberry Pi RP2040, RP2350
- stm: ST STM32F4 chip family
These ports are considered alpha and will have bugs and missing functionality:
- broadcom: Raspberry Pi boards such as RPi 4, RPi Zero 2W (bare metal)
- litex: fomu
- mimxrt10xx: NXP i.MX RT10xxx
- renode: hardware simulator
- silabs: Silicon Labs MG24 family
- stm: ST non-STM32F4 chip families
Previous versions supported the ESP8266 microcontroller, but its support was dropped in version 4.[19]
Blinka Software Abstraction Layer
[edit]CircuitPython code may run on MicroPython or CPython using the Adafruit written Blinka compatibility layer.[20] It acts as a translation layer between CircuitPython code and underlying code. This allows CircuitPython code to run on many more devices including a wide range of single-board computers which are listed on circuitpython.org.[21] It is a pip installable Python library. The CircuitPython runtime is not used, as documented in the guide CircuitPython Libraries on Linux and Raspberry Pi.[22]
Modules (Libraries)
[edit]Adafruit has fostered a community which has contributed software libraries for more than 488 sensors and drivers.[23][24]
References
[edit]- ^ Shawcroft, Scott (19 July 2017). "CircuitPython 1.0.0!". Adafruit Blog. Adafruit Industries. Retrieved 1 May 2018.
- ^ "Release 10.0.3". 17 October 2025. Retrieved 11 November 2025.
- ^ a b "adafruit/circuitpython". GitHub. Adafruit Industries. Retrieved 2 May 2018.
- ^ George, Damien P. (4 May 2014). "circuitpython/LICENSE". GitHub. Retrieved 1 May 2018.
- ^ "CircuitPython is an education friendly open-source derivative of MicroPython". GitHub. Retrieved 30 April 2018.
- ^ "CircuitPython". Read the Docs. Adafruit Industries. Retrieved 1 May 2018.
- ^ George, Damien (20 May 2016). "Damien P. George". Damien P. George. Retrieved 1 May 2018.
- ^ "Adafruit CircuitPython". MicroPython Forum. MicroPython.org. Retrieved 2 May 2018.
- ^ Lewis, James (14 February 2018). "Circuit Python adds Python to Microcontrollers". The Bald Engineer. Retrieved 2 May 2018.
- ^ Ganne, Simon. "Can I use circuitPython code on my raspberry?". Element 14 Community. Element 14.
- ^ Dopieralski, Radomir. "CircuitPython LAMEBOY". BitBucket. Retrieved 2 May 2018.
- ^ Young, Chris (6 June 2018). "Announcing IRLibCP — a Circuit Python Module for Infrared Transmitting and Receiving". CY's Tech Talk. Chris Young. Retrieved 2 May 2018.
- ^ "Adafruit CircuitPython and MicroPython". Adafruit Support Forums. Adafruit Industries. Retrieved 1 May 2018.
- ^ "CircuitPython". Twitter. Adfafruit Industries. Retrieved 1 May 2018.
- ^ "The Python on Microcontrollers Newsletter". Adafruit Daily. Adafruit Industries. Retrieved 17 July 2024.
- ^ "r/CircuitPython". Reddit.com. Adafruit Industries. Retrieved 17 July 2024.
- ^ "Circuitpython.org downloads".
- ^ "CircuitPython 9.1.0". GitHub. 17 July 2024.
- ^ "Why are we dropping support for ESP8266?". Adafruit.com. Adafruit Industries. Retrieved 15 April 2019.
- ^ "Blinka". CircuitPython. Adafruit Industries. Retrieved 17 July 2024.
- ^ "Blinka". CircuitPython. Adafruit Industries. Retrieved 17 July 2024.
- ^ "CircuitPython Libraries on Linux and Raspberry Pi". Adafruit Learning System. Adafruit Industries Industries. Retrieved 17 July 2024.
- ^ "Python on Microcontrollers Newsletter". Retrieved 17 July 2024.
- ^ "CircuitPython Libraries". Retrieved 17 July 2024.
External links
[edit]- CircuitPython on GitHub
- MicroPython playlist on YouTube • Tutorials by Tony DiCola / Adafruit
CircuitPython
View on GrokipediaOverview
Introduction
CircuitPython is an open-source derivative of MicroPython, developed by Adafruit Industries as a beginner-friendly implementation of Python for microcontrollers.[1][6] It was initially released on July 19, 2017, under the MIT license, enabling accessible programming on low-cost hardware without requiring advanced technical knowledge.[6][7] The primary goals of CircuitPython focus on targeting beginners, students, and makers in microcontroller programming, prioritizing ease of use and rapid prototyping over low-level efficiency optimizations.[8] This approach lowers barriers to entry by providing an intuitive environment for learning embedded systems concepts through familiar Python syntax. At its core, CircuitPython includes a Python 3-compatible bytecode compiler, a lightweight runtime interpreter, a Read-Eval-Print Loop (REPL) for interactive sessions, built-in libraries for hardware peripherals like sensors and displays, and file-based code deployment that mounts the microcontroller as a USB mass storage device for simple editing. Its unique selling points emphasize beginner-friendly features, such as immediate code execution without traditional compilation steps, support for interactive debugging via the REPL, and seamless integration with educational hardware like the Circuit Playground Express for hands-on projects. CircuitPython runs on microcontrollers with at least 256 KB of flash memory and 32 KB of RAM, ensuring compatibility with affordable boards while supporting a wide range of interactive and data-driven applications.[9]History
CircuitPython originated as a fork of MicroPython, developed by Adafruit Industries in 2017 to address the needs of educational programming and provide hardware-specific optimizations, particularly for boards like the Circuit Playground Express. This initiative was preceded by Adafruit's launch of the Python on Microcontrollers newsletter on November 15, 2016, which built community momentum around using Python in embedded systems and served as a precursor to the project's formal announcement. The fork aimed to simplify experimentation for beginners while enhancing compatibility with low-cost microcontrollers, responding to the growing demand for accessible Python-based tools in IoT and embedded education.[10] The first stable release, version 1.0.0, arrived on July 19, 2017, initially focusing on support for Adafruit's Circuit Playground hardware and establishing a file-system-based workflow that mounted the device as a USB drive for easy code editing. Subsequent milestones included version 4.0.0 on May 20, 2019, which dropped support for the resource-constrained ESP8266 to prioritize more capable ARM-based boards and improve overall stability. By version 8.0.0, released on February 6, 2023, CircuitPython introduced significant USB device stack improvements, enabling better host integration and reducing common connectivity issues. Version 9.0.0 followed on March 18, 2024, enhancing multimodal I/O capabilities through expanded support for audio processing, display interfaces, and sensor abstractions, alongside optimizations for memory efficiency and real-time performance that addressed early limitations in resource usage.[6][11][12][13] Development has increasingly incorporated community-driven ports, transitioning many ARM-based board supports from alpha to stable status, which broadened hardware compatibility to over 622 ports by late 2025. The latest stable release, version 10.0.3 on October 17, 2025, includes bug fixes and refinements to these ports, reflecting iterative resolutions to performance challenges like memory management and interrupt handling. By 2025, the ecosystem had grown to over 500 libraries, underscoring CircuitPython's evolution into a robust platform for educational and hobbyist embedded projects.[14][15]Technical Foundations
Core Architecture
CircuitPython's core architecture is built primarily in C, leveraging a portable Python virtual machine derived from MicroPython for bytecode interpretation and execution. This VM handles Python 3 compatibility on resource-constrained microcontrollers, with minimal modifications for ARM-based platforms. The system includes a supervisor module that oversees hardware initialization, USB connectivity, file system mounting, and automatic execution of user code upon boot. Python bindings are provided through the shared-bindings layer, which exposes low-level hardware abstractions via consistent APIs, while an event-driven scheduler enables non-blocking I/O operations essential for real-time embedded applications.[16] Memory management in CircuitPython employs a fixed heap allocation, typically ranging from 32 KB on boards like those using the SAMD21 microcontroller to 256 KB on higher-end devices such as the RP2040, leaving limited space for dynamic objects after accounting for system overhead. Garbage collection is implemented to suit real-time constraints, automatically triggered when heap space is exhausted but manually invocable viagc.collect() to mitigate fragmentation; this process scans for and frees unreferenced objects, though it consumes CPU cycles and is optimized to avoid long pauses in critical loops. To prevent fragmentation, core loops avoid dynamic allocations, favoring pre-allocated buffers and static structures, which ensures predictable behavior in memory-tight environments.[17][18]
The file system integrates seamlessly with USB, emulating a mass storage device named CIRCUITPY that appears as a VFAT-compatible drive on host computers, allowing drag-and-drop loading of code files and libraries without specialized tools. This VfsFat-based implementation handles mounting and unmounting directly, as CircuitPython operates without a traditional OS, and supports automatic execution of code.py from the root directory upon reset. Users can disable the drive via storage.disable_usb_drive() for deployed applications, ensuring the file system remains accessible only when needed.
Performance optimizations target low-power microcontrollers, such as the SAMD21, by supporting standby and deep sleep modes through the alarm module, which shuts down the CPU and most peripherals to minimize current draw while preserving wake-up capabilities via timers or pins. Boot times are typically around 1-2 seconds, including a 1-second delay for safe mode entry, enabling rapid iteration in development. Concurrency is handled without native threading to conserve resources, instead relying on asyncio for cooperative multitasking and event loops that yield control during I/O waits.
Security features include a sandboxed runtime environment that isolates execution on the microcontroller, restricting access to the host system beyond controlled USB interfaces like mass storage and serial REPL, thereby preventing unintended interactions. On supported hardware with secure boot capabilities, such as the Raspberry Pi Pico 2 (RP2350), optional secure boot mechanisms verify firmware integrity during startup to guard against tampering.[19]
Language Implementation
CircuitPython implements a dialect of Python 3 that is a subset of the language specification, drawing from versions 3.6 and later, with support extending to features introduced in Python 3.10 as of CircuitPython 9.x releases. This includes core constructs such as imports, classes, functions, generators, and comprehensions, enabling familiar Python syntax for embedded programming. However, advanced features like complex metaclasses, arbitrary-precision integers in all contexts, and C extensions are omitted to accommodate the constrained resources of microcontrollers, prioritizing simplicity and performance over full CPython equivalence.[20] The implementation is derived from MicroPython but customized by Adafruit for broader hardware compatibility and user-friendliness, ensuring that most standard Python code runs with minimal modifications on supported devices.[21] The interpreter operates through a read-eval-print loop (REPL) accessible via USB serial connection, allowing interactive sessions for testing code snippets directly on the device.[21] Upon boot or file changes, Python source files (typicallycode.py) are compiled on-the-fly to bytecode, which the virtual machine then executes; this process repeats automatically on modifications to support rapid iteration. Error handling follows Python conventions, displaying tracebacks in the console for debugging, though stack traces may be truncated on memory-limited boards to prevent overflows. The REPL activates after main script execution unless disabled in safe mode, providing an immediate feedback loop that distinguishes CircuitPython from traditional compiled embedded languages.[21]
CircuitPython includes a selection of built-in modules that mirror subsets of the Python standard library, such as time for basic timing operations, math for mathematical functions, and os restricted to filesystem interactions like directory listing and file manipulation.[20] Hardware-oriented extensions augment this foundation, including digitalio for general-purpose input/output (GPIO) control, pulseio for PWM signals, and busio for interfacing with I2C, SPI, and UART peripherals, all abstracted to work consistently across supported microcontrollers. These modules are implemented in C for efficiency, with Python bindings exposed via the shared bindings system, ensuring low-level hardware access without requiring users to write C code.[22]
Key deviations from standard Python arise from the embedded environment, including the absence of package management tools like pip, where libraries must be manually copied to the device's /lib directory for import.[23] Floating-point operations use IEEE 754 doubles where hardware supports it, but on lower-end microcontrollers with limited RAM, precision and performance may be reduced compared to desktop Python implementations. The asyncio module enables asynchronous programming with async/await syntax for cooperative multitasking, suitable for I/O-bound tasks, but multiprocessing and true threading are unsupported due to the single-core nature of target hardware. These constraints promote lightweight, deterministic code that avoids blocking operations, aligning with real-time embedded requirements.[20]
To mitigate load times and memory usage, CircuitPython employs optimization techniques such as pre-compiled bytecode caching in .mpy files, generated using the mpy-cross cross-compiler tool.[24] These binary files load faster than raw .py source and consume less storage—often 20-50% smaller—making them essential for resource-constrained boards where every kilobyte matters. Users can compile libraries offline on a host machine and deploy the .mpy versions to the filesystem, reducing runtime compilation overhead and enabling larger projects without exhausting flash space.[25] This approach balances portability with efficiency, allowing Python's expressiveness in environments where full compilation would be impractical.[24]
Development and Usage
Programming Workflow
The programming workflow for CircuitPython begins with installing the firmware on a compatible microcontroller board. Users download the latest .uf2 firmware file specific to their board from the official CircuitPython downloads page at circuitpython.org. To install, the board is placed into bootloader mode—typically by double-tapping the reset button on most boards or holding the BOOTSEL button while resetting on RP2040-based devices—which mounts a boot drive visible as a USB mass storage device. The .uf2 file is then dragged and dropped onto this drive, after which the board resets automatically, and the CIRCUITPY drive appears, ready for file operations.[26][14] Code development involves editing Python files directly on the CIRCUITPY drive using any text editor, with CircuitPython supporting beginner-friendly options like Mu or Thonny, or advanced ones like Visual Studio Code with extensions for syntax highlighting and serial integration. The primary file, code.py, runs automatically upon boot or save; modifications, such as adjusting delays in a loop, are saved to the drive, triggering an immediate auto-reload for live testing without manual resets. This file-based workflow leverages the board's USB mass storage emulation, allowing seamless iteration between development on a host computer and execution on the device.[27][28] Debugging relies on built-in tools accessible via the USB serial connection. The serial console outputs print statements from code.py, enabling real-time monitoring of variables, sensor data, or execution flow for print-based debugging. To enter the REPL (Read-Evaluate-Print-Loop) for interactive testing, users connect to the serial console and press Ctrl+C to interrupt the running program, then any key at the prompt to access the >>> shell, where commands can be executed line-by-line; Ctrl+D exits and reloads the code. Visual error indicators include the onboard status LED, which blinks in specific patterns (e.g., red for runtime errors like NameError) to signal issues without console access. Additionally, the watchdog timer detects code lockups by monitoring for feed() calls; if not fed within the set timeout, it triggers a reset to prevent hangs from infinite loops or crashes.[29][30] For deployment, a simple example is blinking the onboard LED, which imports the board and digitalio modules to configure and toggle the pin:import board
import digitalio
import time
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
while True:
led.value = True
time.sleep(0.5)
led.value = False
time.sleep(0.5)
import board
import digitalio
import time
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
while True:
led.value = True
time.sleep(0.5)
led.value = False
time.sleep(0.5)
Libraries and Extensions
CircuitPython provides a rich ecosystem of libraries that abstract hardware interactions, enabling developers to interface with peripherals such as sensors, displays, and actuators without low-level programming. These libraries are divided into built-in modules, which are included in the firmware for core functionality, and third-party extensions, primarily from the Adafruit bundle and community contributions. This separation allows for efficient resource use on resource-constrained microcontrollers, where libraries must be selected and deployed judiciously.[5] The built-in libraries form the foundational set, comprising over 80 modules, varying by board, in CircuitPython version 10.0 and later, implementing subsets of Python standard libraries alongside hardware-specific abstractions. Key examples includebusio for hardware-accelerated I2C and SPI protocols, pulseio for pulse-width modulation (PWM) and pulse counting, audioio for audio playback and mixing, and storage for file system operations on the device's storage. These modules are written in C for performance and are always available, providing essential APIs for input/output, timing, and device management without additional installation. Version 10.0, released in October 2025, introduced enhancements to built-in modules for audio, graphics, and networking, expanding usage possibilities.[35][36][3]
The third-party ecosystem significantly expands capabilities, with over 540 libraries available as of October 2025, predominantly maintained by Adafruit and hosted in community repositories on GitHub. Notable Adafruit libraries include drivers for sensors like the BMP280 barometric pressure sensor and displays such as the SSD1306 OLED, which simplify integration by handling protocol details and data parsing. Installation involves downloading version-specific bundles and copying compiled .mpy files to the lib folder on the device's CIRCUITPY drive, supporting offline deployment suitable for embedded environments. Community contributions further diversify options, covering niche hardware like LED strips and custom boards.[37][38][5]
Extension mechanisms in CircuitPython emphasize static deployment over dynamic loading, with no support for runtime installations or network-dependent package managers to maintain simplicity and security. Libraries are distributed in CircuitPython-specific bundles, often as pre-compiled .mpy binaries to reduce memory footprint, and can be selectively included based on project needs. Representative extensions include the adafruit_neopixel library for controlling addressable LED strips via the built-in neopixel_write module, and adafruit_circuitplayground for board-specific features on devices like the Circuit Playground Express, which bundle sensors, lights, and speakers into high-level APIs.[5]
Contributing new libraries, such as display drivers, involves forking the Adafruit CircuitPython repository and implementing custom code. For example, to add a new display driver like for the AXS15231B, developers write a new C driver file (e.g., axs15231b.c) in the shared-bindings directory, modeled after existing ones, utilizing hardware-specific features such as the ESP32-S3's SPI master in quad mode through ESP-IDF APIs. Initialization sequences are extracted from Arduino or ESP-IDF drivers, and the Python interface subclasses busdisplay.BusDisplay to support QSPI without a traditional DC pin, while incorporating I2C for touch functionality. After adding the C code and Python bindings, a custom firmware UF2 file is built, followed by testing and debugging on target hardware.[39][40][41][42]
Version compatibility is ensured through tagged releases, with libraries compiled for specific major CircuitPython versions (e.g., 9.x or 10.x) to account for API changes in .mpy formats. Backward compatibility is maintained across major releases where possible, allowing libraries from prior versions to function with minor updates, though users are encouraged to match bundle versions to the firmware for optimal performance.[43][5]
Limitations arise from the embedded nature of CircuitPython, including strict size constraints where libraries must fit within available RAM—often prompting the use of compact .mpy files over source .py—and the absence of network-dependent installations, requiring all dependencies to be pre-loaded manually. These design choices prioritize reliability on low-power devices but necessitate careful library selection to avoid exceeding storage or memory limits.[5][24]