E-paper shopping list for the M5Stack PaperMono, with a FastAPI server and phone web UI
C++
3
2 commits
updated Sep 28, 2026
Firmware for the M5Stack PaperMono e-paper device. It turns the device into a household shopping list that lives on the fridge and stays in sync with a phone web app.
The PaperMono is an ESP32-S3 with a 3.97" 480×800 e-paper touchscreen. This project is a complete, working app for it that's small enough to read: about 2,400 lines of C++. You can use it as a shopping list, or as a starting point for your own PaperMono firmware.
The device shows the list grouped by aisle, in the order you walk the shop. Tap an item to tick it off, or add one with the on-screen keyboard. Everyone else adds things from their phone.
A small server in between stores the list. It remembers which aisle every item belongs to and can optionally sort brand-new items into the right aisle with Claude.
flowchart LR
device["PaperMono<br/>(firmware/)"] -- "Wi-Fi, hourly or on tap<br/>and after each edit" --> server
phone["Phone browser"] -- HTTP --> server
subgraph server["Server (server/)"]
api["FastAPI + SQLite"]
web["Web UI"]
end
api -. "new item names only" .-> claude["Claude Code CLI<br/>(optional)"]
firmware/ PlatformIO project for the PaperMono (C++ / Arduino)
server/ FastAPI server, SQLite store, phone web UI, tests
docs/ Hardware notes, architecture, API, build and deploy guides, design notes
cd server
python3 -m venv .venv && .venv/bin/pip install -e .
SHOPPING_LIST_CLASSIFIER=none .venv/bin/uvicorn shopping_list.main:app --host 0.0.0.0 --port 8000
Open http://<server-ip>:8000/ on your phone, tap Aisles, and add your shop's
aisles in the order you walk them. See docs/server.md for
systemd and Docker deployment and for turning on auto-sorting.
You need PlatformIO and a PaperMono connected over USB-C.
cd firmware
cp src/secrets.example.h src/secrets.h # set Wi-Fi SSID/password and the server URL
pio run -t upload
Back up your device's flash before the first flash. It holds that unit's factory calibration data. docs/firmware.md covers the backup, download mode and flashing from a browser.
| Doc | What's in it |
|---|---|
| Hardware notes | Pin map, I²C devices, bring-up sequence, display, touch and power details; reusing the drivers |
| Firmware | Building, configuring, flashing and recovering the device; using it; troubleshooting |
| Architecture | Components, data model, the sync protocol, offline behaviour, display refresh policy |
| Server | Running and deploying the server, configuration, auto-sorting, security |
| HTTP API | Every endpoint, request and response |
| Design notes | Where the firmware came from, decisions and trade-offs, known limitations |
A personal project, running on one device at home. It works, but it isn't a product. There's no on-device Wi-Fi setup (credentials are compiled in), no authentication on the server (keep it on your LAN or behind an authenticating reverse proxy), and only the PaperMono C153 has been tested. See known limitations.
Built by Seamus Cawley, who builds Bronto, the logging and observability platform, by day.
The firmware's board support, e-paper and touch drivers, keyboard layout and widget style are adapted from MonoMesh by andrecolz, an independent Meshtastic-compatible firmware for the same hardware. docs/design-notes.md lists exactly what was reused.
GNU General Public License v3.0, the same license as MonoMesh, which parts of the firmware derive from.
C++
50.7%
Python
23.4%
JavaScript
15.7%
CSS
4.5%
HTML
3.6%
Shell
1.6%
E-paper shopping list for the M5Stack PaperMono, with a FastAPI server and phone web UI
C++
3
2 commits
updated Sep 28, 2026
Firmware for the M5Stack PaperMono e-paper device. It turns the device into a household shopping list that lives on the fridge and stays in sync with a phone web app.
The PaperMono is an ESP32-S3 with a 3.97" 480×800 e-paper touchscreen. This project is a complete, working app for it that's small enough to read: about 2,400 lines of C++. You can use it as a shopping list, or as a starting point for your own PaperMono firmware.
The device shows the list grouped by aisle, in the order you walk the shop. Tap an item to tick it off, or add one with the on-screen keyboard. Everyone else adds things from their phone.
A small server in between stores the list. It remembers which aisle every item belongs to and can optionally sort brand-new items into the right aisle with Claude.
flowchart LR
device["PaperMono<br/>(firmware/)"] -- "Wi-Fi, hourly or on tap<br/>and after each edit" --> server
phone["Phone browser"] -- HTTP --> server
subgraph server["Server (server/)"]
api["FastAPI + SQLite"]
web["Web UI"]
end
api -. "new item names only" .-> claude["Claude Code CLI<br/>(optional)"]
firmware/ PlatformIO project for the PaperMono (C++ / Arduino)
server/ FastAPI server, SQLite store, phone web UI, tests
docs/ Hardware notes, architecture, API, build and deploy guides, design notes
cd server
python3 -m venv .venv && .venv/bin/pip install -e .
SHOPPING_LIST_CLASSIFIER=none .venv/bin/uvicorn shopping_list.main:app --host 0.0.0.0 --port 8000
Open http://<server-ip>:8000/ on your phone, tap Aisles, and add your shop's
aisles in the order you walk them. See docs/server.md for
systemd and Docker deployment and for turning on auto-sorting.
You need PlatformIO and a PaperMono connected over USB-C.
cd firmware
cp src/secrets.example.h src/secrets.h # set Wi-Fi SSID/password and the server URL
pio run -t upload
Back up your device's flash before the first flash. It holds that unit's factory calibration data. docs/firmware.md covers the backup, download mode and flashing from a browser.
| Doc | What's in it |
|---|---|
| Hardware notes | Pin map, I²C devices, bring-up sequence, display, touch and power details; reusing the drivers |
| Firmware | Building, configuring, flashing and recovering the device; using it; troubleshooting |
| Architecture | Components, data model, the sync protocol, offline behaviour, display refresh policy |
| Server | Running and deploying the server, configuration, auto-sorting, security |
| HTTP API | Every endpoint, request and response |
| Design notes | Where the firmware came from, decisions and trade-offs, known limitations |
A personal project, running on one device at home. It works, but it isn't a product. There's no on-device Wi-Fi setup (credentials are compiled in), no authentication on the server (keep it on your LAN or behind an authenticating reverse proxy), and only the PaperMono C153 has been tested. See known limitations.
Built by Seamus Cawley, who builds Bronto, the logging and observability platform, by day.
The firmware's board support, e-paper and touch drivers, keyboard layout and widget style are adapted from MonoMesh by andrecolz, an independent Meshtastic-compatible firmware for the same hardware. docs/design-notes.md lists exactly what was reused.
GNU General Public License v3.0, the same license as MonoMesh, which parts of the firmware derive from.
C++
50.7%
Python
23.4%
JavaScript
15.7%
CSS
4.5%
HTML
3.6%
Shell
1.6%