MicroPython v1.28
PWM on alif and stm32, a new standardized machine.CAN API, PEP 750 template strings, and the weakref module.
Released April 6, 2026
machine.PWM — PWM Everywhere
PWM support has finally been added to the stm32 and alif ports, completing coverage across all Tier 1 and Tier 2 microcontroller-based ports. Create and control PWM outputs in a consistent way, no matter which board you're running on.
from machine import Pin, PWM pwm = PWM(Pin(0), freq=1000, duty_u16=32768) # 50.0% duty cycle at 1000 Hz # Pulse width: 500000 ns
PWM Port Support
All Tier 1 and Tier 2 ports now have machine.PWM support.
Ports added in v1.28 are highlighted.
freq(), duty_u16(),
duty_ns(), and output inversion.
machine.CAN — CAN Bus Goes Standard
After years of development, MicroPython now has a finalized, standardized CAN bus API with documentation, comprehensive tests, and an implementation for the stm32 port. A consistent way to use CAN across all ports—other implementations will follow soon.
from machine import CAN # Initialize CAN bus can = CAN(1, CAN.NORMAL, baudrate=500_000) # Send a message can.send(b'\x01\x02\x03', id=0x123) # Receive a message msg = can.recv() print(f"ID: {msg[0]:#x}, Data: {msg[1]}")
Template Strings (t-strings)
Template strings are a new string literal type that keeps interpolation components as separate
objects within a Template,
rather than concatenating them like f-strings. This enables safer string processing, custom renderers,
and structured string handling.
Input Code
version = 1.28
result = f"Welcome to {name} v{version}"
Output — String
f"{'yes' if f'{x}' == '1' else 'no'}"
from string.templatelib import Template name = "MicroPython" version = 1.28 # f-string: produces a concatenated string greeting = f"Welcome to {name} v{version}" # → "Welcome to MicroPython v1.28" # t-string: produces a Template object template = t"Welcome to {name} v{version}" # → Template(strings=('Welcome to ', ' v', ''), # interpolations=(Interpolation('MicroPython', 'name'), # Interpolation(1.28, 'version'))) # Process template components individually for part in template: print(type(part), repr(part))
Edit the code below and click Run to execute it with real MicroPython compiled to WebAssembly (~170 KB). No server required.
f-string vs t-string
Nested f-strings
Enabled on: alif, mimxrt, samd (SAMD51), and webassembly (pyscript) ports.
weakref Module
The new weakref
module adds weakref.ref
and weakref.finalize
for registering callbacks when objects are reclaimed by the garbage collector. Follows CPython semantics closely.
import weakref class Sensor: def __init__(self, pin): self.pin = pin self.buffer = bytearray(1024) # Create sensor and register cleanup callback sensor = Sensor(4) weakref.finalize(sensor, lambda p: print(f"Pin {p} sensor cleaned up"), 4) # Create a weak reference ref = weakref.ref(sensor) print(ref()) # <Sensor object> # Delete the strong reference del sensor # When GC runs: "Pin 4 sensor cleaned up" print(ref()) # None
The weakref
module is enabled on the webassembly/pyscript port — edit and run this code right in your browser.
weakref.ref and weakref.finalize
Currently enabled on the webassembly (pyscript) port. Can be manually enabled on any port.
Highlights
Other notable improvements in this release.
VfsRom Filesystem Expansion
ROM filesystem support is now available on more ports, making it easier to include read-only assets in your firmware.
machine.Counter & Encoder
The mimxrt port now implements quadrature encoder and counter classes with IRQ callbacks, index/reset/match pins, and cycle counting.
RISC-V Zcmp Opcodes
Compressed instructions for RV32 targets produce smaller native code. Enabled for ESP32-P4 and RP2350 in RV32 mode.
alif Deep Sleep
Improved deepsleep power saving with wake-up from a falling GPIO edge or RTC alarm via the standard machine.deepsleep(timeout_ms).
mimxrt Upgrades
PSRAM support, DP83867 PHY Ethernet driver, and RTC resolution increased from 1 second to 1/32768 seconds. SDK updated to MCUX 2.16.100.
pico-sdk 2.2.0
The rp2 port has been updated to pico-sdk 2.2.0, switching all RNG sources from ROSC to the new pico_rand component.
Xtensa Inline Assembler
Inline assembler support extended to windowed Xtensa cores, expanding native code capabilities on the esp32.
Design Values
A new section in the main README articulating MicroPython's design philosophy. All users and developers are encouraged to read it.
New Boards
11 new board definitions added across 4 ports.
rp2 (7 boards)
esp32 (2 boards)
stm32 (2 boards)
mimxrt (1 board)
By the Numbers
Code Size Changes
Change in .text section size since v1.27. Hover for details.