Open-source project
peterhinch/micropython-samples avatar
peterhinch/micropython-samples

micropython-samples: an unofficial MicroPython FAQ from a Pyboard desk

Assorted code ideas, unofficial MP FAQ, plus index to my other repositories.

532 stars95 forksPythonMIT

At a glance

What is it?
The micropython-samples repository is a working notebook rather than a library, holding twenty code samples, five essays and a set of hardware notes written by someone who keeps finding questions the official documentation does not answer. The most useful entry is the USB pitfall, which explains why the Pyboard mass storage mode corrupts files.
Who is it for?
micropython-samples suits someone building on a Pyboard or an ESP board who has hit a problem the official documentation does not cover, since the essays and hardware notes are precisely the knowledge that is missing elsewhere and the samples are short enough to read in one sitting. It does not suit you as a dependency, since the author states that feature requests may not be accepted and that some entries are pointers rather than solutions.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 58 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The readme is an index with two different kinds of entry

The repository is described as assorted code ideas for MicroPython, an unofficial MicroPython FAQ, and an index to other repositories, and the readme makes the structure explicit with five numbered sections.

The first part is the code, and the framing is careful about what it is. Some samples are targeted at Pyboard variants, some are intended as pointers for programmers rather than being complete solutions, and the policy is stated plainly: egregious bugs will be fixed but feature requests may not be accepted.

That single sentence is the most useful thing in the document for anyone deciding whether to depend on something here. This is a notebook of working answers, not a supported library, and the distinction between a sample you can copy and a project you can depend on is drawn by the author before you find out the hard way.

Section 5 is a different kind of thing entirely. It is an index to complete applications and modules which are documented and supported, and it covers asyncio tutorials and drivers, memory device drivers, inertial measurement units, other hardware drivers, communications, displays, Pyboard micropower, Pyboard DSP, a fork of rshell with text macros, and a category for things that do not fit anywhere else.

So the repository holds two tiers. Sections 1 to 4 are the loose notes, and section 5 points at the maintained work. The readme also links the official MicroPython examples as the place to look for the canonical versions of anything.

The topic tags are embedded, esp32, esp8266, micropython and stm32, the licence is MIT, and the last push was on 2026-08-26 with no GitHub releases.

The USB pitfall is the most consequential thing in the docs

One entry in the installation guides section is a hardware problem rather than a code sample, and it is the kind of thing that silently destroys work.

By default the Pyboard's boot.py enables mass storage mode. This makes the Pyboard look like a USB stick, making its filesystem visible to the PC. The documentation calls it a helpful feature and then explains that it ignores a fundamental flaw which leads to filesystem corruption.

The reason is a mismatch of expectations. The USB standard requires mass storage devices to behave like disks with static content, whereas a Pyboard can independently modify the disk contents, causing chaos.

So the feature that makes it easy to copy files onto the board is also the feature that can corrupt the filesystem, because the host and the board are both writing to what looks like the same medium with completely different assumptions.

The fix is one line. You edit the boot.py so that the usb_mode line reads:

python
pyb.usb_mode('VCP')

On reboot the Pyboard will no longer appear as a mass storage device on the PC. Various tools are available to manage the device's storage over USB instead, and the author uses rshell.

That is a good illustration of the FAQ half of this repository. There is no official page saying this, because it is a consequence of how the USB mass storage specification interacts with a board that is running code while mounted, and it takes somebody who has lost data to work out the mechanism and write it down.

The other entries in this section follow the same pattern of practical knowledge rather than code. There is a buildcheck tool that raises an exception if a firmware build is earlier than a given date, which is a way of catching a stale flash, and a section on installing MicroPython libraries which describes a simple way to override modules that have been incorporated into the firmware as frozen bytecode.

The web framework answer is Microdot, and it says why

The web framework entry names two options and explains the reasoning, which is the useful part.

Paul Sokolovsk's PicoWeb requires his fork of MicroPython and requires some modification to run under official MicroPython. The solution preferred by the MicroPython maintainers is Microdot.

That is a small but complete piece of guidance. PicoWeb is a fine framework that assumes a specific MicroPython build, which means adopting it means adopting somebody's fork of the firmware, and a fork of the firmware is a long term maintenance commitment for a project that otherwise has none. Microdot is the option that works with the firmware you already have.

The fastbuild entry is the build side of the same problem. There are scripts for building MicroPython for various target hardware types and for updating your local source, and the entry notes that it now detects and builds for Pyboard D.

A build script that detects the board is more than a convenience. MicroPython is a firmware that has to be cross compiled per target, and the set of targets is large enough that maintaining that by hand is a real tax. A script that handles the detection turns a chore into a single command.

The micropip directory deserves a mention too. Its own documentation describes a simple way to override modules which have been incorporated in the firmware as frozen bytecode, and the reason that matters is specific to MicroPython: frozen bytecode means the module is part of the firmware image rather than a file on the filesystem, so you cannot simply replace it on the device. The workaround is to shadow it.

Taken together, these four entries are the answer to the question a newcomer actually has, which is how do I install a library on a microcontroller where I did not build the firmware. The answer here is three-part: shadow the frozen module, build the firmware yourself if you need something the build does not include, and use a web framework that does not require a fork.

The essays are the part with no code in them at all

The essays section holds five pieces of general thinking, and it is the section that makes this repository an FAQ rather than a code dump.

Resilient is a guide to writing resilient WiFi code, which on a microcontroller is the central reliability problem, since the radio drops and reconnects constantly and naive code treats that as an error path rather than the normal case.

Serialisation is a review of MicroPython's five serialisation libraries, which is exactly the kind of comparison that saves an afternoon of benchmarking by hand. MicroPython ships more than one option for turning objects into bytes, and they differ in speed, size and memory behaviour, which on a device with a few hundred kilobytes of RAM is the deciding factor.

Measurement of relative timing and phase of fast analog signals is for the Pyboard, and the framing of it is the interesting part. It is about measuring the phase between two analog signals, not about measuring time, which is a genuinely different problem on a microcontroller with no floating point hardware and a limited timer.

Import subtleties is about ways to save RAM with import statements. On a device where every import costs you memory that you will want later, how you structure your imports is a design decision rather than a style preference, and this one is written by someone who had to learn that the hard way.

The fifth entry is an SSL and TLS tutorial, and it is credited to somebody else. The parenthetical note says this excellent resource is not my work. That is worth noting because it tells you the author distinguishes between what is here and what is a pointer, and the index is explicit about which entries are pointers rather than complete solutions.

The essays are also the section with the longest shelf life. The code samples will bit rot against firmware changes, but a guide to writing resilient WiFi code or a comparison of serialisation libraries stays true for as long as the constraint exists.

Twenty code samples, several of which solve a specific hardware problem

The code samples section lists twenty entries, and the naming convention is stated: samples prefixed Pyboard are Pyboard specific. Everything else is meant to be portable.

Three of them are watchdog implementations and they are worth separating because they solve different problems. The Pyboard watchdog accesses the Pyboard hardware WDT, which is a timer in the chip that resets the board if it is not fed, and the software watchdog is a cross-platform soft WDT, meaning the same idea implemented in Python with a timer thread rather than in hardware.

That pairing is a pattern throughout the list. The Pyboard mutex shares data between threads and interrupts, which is a specific and notoriously tricky problem on a single core microcontroller where an interrupt can preempt a critical section. The timed function times execution with a decorator, which is a small utility that solves a recurring annoyance. The reverse entry gives reversal algorithms for bytearrays, which is a case where the obvious approach allocates a new buffer and the careful one does not.

The bitmaps entry is described as non-allocating ways to access bitmaps, and that adjective is the whole point. On a device with a fixed heap, allocating a temporary list to read a single pixel is not a style issue, it is the difference between working and raising an out of memory error.

The verifying incrementing sequences entry tests communications drivers, which is a clever piece of test design: rather than checking that a driver returns what you sent for one case, you check that the driver can round trip a sequence of incrementing values, which catches byte order, framing and off-by-one errors in one pass.

Several entries are algorithms rather than drivers. The rotary incremental encoder gives a fast, simple, proven algorithm for the hardware that reports rotation as a stream of pulses, and the pseudo random number generators entry collects several. The 2D array indexing entry uses a slice-like syntax to address a 2D array, which is a small language extension that makes numeric work readable. The greatest common divisor entry gives a neat algorithm. The astronomy entry derives sun and moon rise and set times and the moon phase. The tone detection entry uses the Goertzel algorithm, which is the efficient way to detect one frequency in a signal.

Two entries are about hardware families rather than algorithms. The ESP8266 MQTT benchmark tests performance of MQTT with the official library, which is the kind of measurement you need before choosing a protocol for a battery powered node. And using RP2XXX hardware is an introduction to PIO, DMA and dual-core code, which is the Pico's distinctive features and the reason people buy the board.

Thirty directories, and what the folder names reveal

The top level of the repository is the clearest evidence that this is a working notebook rather than a curated package, because the directory names are exactly the index entries and nothing more.

There is a directory for each sample and each essay: astronomy for the astronomy entry, bitmap, buildcheck, data_to_py, date, encoders, fastbuild, functor_singleton, goertzel for the tone detection, import, mutex, ntptime, parse2d for the 2D array indexing, phase, power for the Pyboard power meter, quaternion, random, resilient, reverse, rp2, sequence, soft_wdt, temp, timed_function and watchdog. Each of the hardware notes has one too: DS3231, ESP32, ESP8266 and pyboard_d.

Four directories have documentation files at the top level rather than folders, and each is a subject with enough detail to deserve its own file. PICOWEB.md, QUATERNIONS.md, RSHELL_MACROS.md and SERIALISATION.md. The quaternions one covers the sample and the file is at the root, which suggests it was written up as a document rather than growing out of a directory.

Three directories are not samples at all. The PicoWeb directory holds the vendored or referenced web framework work, and there is a separate subdirectory in the examples for the same thing, which suggests the layout grew as the work did. The RSHELL_MACROS documentation describes a fork of rshell with text macros, and the fork lives in the section 5 index rather than here.

The data_to_py entry is the one name that needs no explanation. On a microcontroller, having data tables in a Python file rather than as a separate binary format is a decision about how the data gets into the firmware image, and it is a problem every embedded project has to solve in some way.

The two Pyboard hardware directories are named after the specific problems they address. The DS3231 entry is about using cheap hardware to calibrate the Pyboard RTC, since the real time clock on the board needs correcting against a temperature compensated reference and the cheap module is the one most people will actually buy. The pyboard_d entry records that some information remains absent or hard to find in the documentation.

That last one is a good summary of what this repository is. It is a set of answers to questions about hardware that the official documentation does not answer, written by somebody who has a board on the desk and keeps finding them.

Editorial conclusion

micropython-samples suits someone building on a Pyboard or an ESP board who has hit a problem the official documentation does not cover, since the essays and hardware notes are precisely the knowledge that is missing elsewhere and the samples are short enough to read in one sitting. It does not suit you as a dependency, since the author states that feature requests may not be accepted and that some entries are pointers rather than solutions. Before you copy a sample, check whether it is prefixed for a Pyboard, because only those are specific to that board, and read the USB pitfall before you rely on mass storage mode to move files on and off a Pyboard.

Frequently asked questions

What is the micropython-samples repository for?

It holds assorted code ideas for MicroPython, serves as an unofficial MicroPython FAQ, and indexes the author's other repositories. The README is explicit that some samples are pointers for programmers rather than complete solutions, that egregious bugs will be fixed, and that feature requests may not be accepted.

Why should I change the Pyboard usb_mode setting?

Because the default mass storage mode makes the board's filesystem visible to the PC, and the USB standard requires mass storage devices to behave like disks with static content, whereas the Pyboard can independently modify its contents, which leads to filesystem corruption. Setting usb_mode to VCP stops it appearing as a mass storage device.

Which web framework does micropython-samples recommend for MicroPython?

Microdot, which is the solution preferred by the MicroPython maintainers. The alternative, PicoWeb, requires a fork of MicroPython and some modification to run under official MicroPython.

What kinds of code are in the micropython-samples code samples?

Twenty entries covering watchdog implementations in hardware and software, a mutex for sharing data between threads and interrupts, reversal algorithms for bytearrays, non-allocating bitmap access, a timed function decorator, an MQTT benchmark on the ESP8266, a rotary incremental encoder algorithm, pseudo random number generators, 2D array indexing, astronomy calculations, tone detection with the Goertzel algorithm and an introduction to PIO, DMA and dual-core code on RP2XXX hardware.

What are the essays in micropython-samples about?

Five pieces of general thinking: a guide to writing resilient WiFi code, a review of MicroPython's five serialisation libraries, measuring relative timing and phase of fast analog signals on the Pyboard, import subtleties for saving RAM, and a linked SSL and TLS tutorial credited to another author.

Official sources

  1. Issues
  2. License: MIT
  3. peterhinch/micropython-samples on GitHub
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/peterhinch-micropython-samples.svg)](https://hysenlabs.com/projects/peterhinch-micropython-samples)

Was this useful?