New Release

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 on every Tier 1 & 2 port
🚢
machine.CAN
Standardized CAN bus API
📄
t-strings
PEP 750 template strings
🔗
weakref
GC callbacks & weak references
0 Contributors
0 Timezones
0 New Boards
The t-string and weakref output on this page is generated by real MicroPython running in your browser via PyScript. MicroPython is compiled to WebAssembly (~170 KB) and executes live as the page loads — no server required.
New

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.

Interactive Demo — PWM Waveform Playground
1000 Hz
32768 (50%)
main.py
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.

esp32
esp8266
rp2
nrf
samd
mimxrt
renesas-ra
stm32 NEW
alif NEW
stm32 Highlight
The stm32 implementation works across all 14 MCU families. A heuristic statically assigns the optimal TIM and channel to each pin to maximise independent PWM outputs. Supports freq(), duty_u16(), duty_ns(), and output inversion.
New

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.

Interactive Demo — CAN Bus Network
CAN Bus (500 kbit/s) Node A STM32 (bxCAN) Node B STM32 (FD-CAN) Node C Coming Soon 120Ω 120Ω
› Ready. Click Send to transmit a CAN frame.
can_example.py
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]}")
bxCAN FD-CAN esp32 — Coming Soon rp2 — Coming Soon
New — PEP 750

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.

Interactive Demo — f-string vs t-string

Input Code

name = "MicroPython"
version = 1.28

result = f"Welcome to {name} v{version}"

Output — String

"Welcome to MicroPython v1.28"
Bonus: Nested f-strings now work!
As a byproduct of the t-string parser, f-strings can now be nested within f-string expressions:
f"{'yes' if f'{x}' == '1' else 'no'}"
tstring_example.py
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))
Try It Live — Real MicroPython in Your Browser PyScript

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

Loading MicroPython...

Nested f-strings

Enabled on: alif, mimxrt, samd (SAMD51), and webassembly (pyscript) ports.

New

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.

Interactive Demo — GC Lifecycle Visualizer
moduleapp
Sensorsensor
bytearraybuffer
weakrefref(sensor)
weakreffinalize
› All objects are alive.
› app holds a strong ref to sensor.
› weakref.ref tracks sensor (dashed).
Strong ref Weak ref
weakref_example.py
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
Try It Live — weakref in Action PyScript

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.

mimxrt nrf renesas-ra samd
🔄

machine.Counter & Encoder

The mimxrt port now implements quadrature encoder and counter classes with IRQ callbacks, index/reset/match pins, and cycle counting.

mimxrt
📦

RISC-V Zcmp Opcodes

Compressed instructions for RV32 targets produce smaller native code. Enabled for ESP32-P4 and RP2350 in RV32 mode.

esp32 rp2
🌙

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).

alif
🚀

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.

mimxrt
🛠

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.

rp2
🧭

Xtensa Inline Assembler

Inline assembler support extended to windowed Xtensa cores, expanding native code capabilities on the esp32.

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.

By the Numbers

0 Contributors
0 Timezones
0 New Boards

Code Size Changes

Change in .text section size since v1.27. Hover for details.