A physical-button interface for logging real-world events with almost no friction.
A full-stack IoT habit-tracking system built around one idea: physical buttons placed exactly where the behavior happens are more likely to be used than any app. Press a button next to your water bottle. Press a button by your exercise machine. Press a button next to your water bottle. Press a button by your exercise machine. Press a button near a tool bench, machine, or supply shelf. The data lands in a dashboard without you ever touching your phone.
- Project overview — introduces the idea and the ESP32-S3 microcontroller prototype
- Button matrix demo — simulates a button press through the wired matrix and shows the server receiving it
- OLED mode update — shows the device refreshing its mode list from the server
- Dashboard demo — walks through the web dashboard
- Embedded firmware development on ESP32-S3 using Arduino/C++
- WiFi provisioning without per-device flashing or serial configuration
- UDP-based device discovery and event transmission on a local network
- Node.js/Express API design with SQLite persistence
- React/Vite dashboard UI with drag-and-drop organization and historical reporting
- Hardware/software integration across buttons, OLED display, rotary encoder, and web dashboard
- Product thinking: reducing user friction by moving the interface to the physical point of behavior
The Physical Button Project is a three-part system:
| Layer | What it does |
|---|---|
| Firmware (ESP32-S3) | Handles WiFi provisioning, button scanning, and UDP service discovery |
Backend API (button-authenticator) |
Node.js/Express server that receives clicks, stores history, and serves the dashboard |
Web Dashboard (button-dashboard) |
React app for mapping devices, reviewing history, and organizing buttons |
Each button device is a small WiFi-connected microcontroller with up to a 4×3 grid of 12 buttons, an optional rotary encoder, and an optional OLED display. Multiple devices can be provisioned at once. Devices use UDP for lightweight event transmission and discovery. The backend also exposes HTTP endpoints for dashboard configuration, manual testing, and administrative updates.
Think about the last time you tried to log a habit. You probably had to:
- Unlock your phone
- Find the app
- Navigate to the right item
- Confirm the action
That friction kills habits. A physical button mounted in the right place removes every one of those steps. The closest analog is a supermarket self-checkout tally — zero thought, one press.
The same insight scales to completely different contexts:
- Habit Tracker — water, coffee, vitamins, push-ups; track who in the household did what
- Makerspace — "I used the laser cutter" / "I took some filament" — log equipment use and consumable consumption without a sign-in sheet
- Kids' Console — four big colorful buttons (Heart, Star, Diamond, X) that log whatever a child decides they mean
[ Button Device ] → UDP broadcast → [ button-authenticator API ]
↑ ↓
(WiFi auto- SQLite database
provisioned) ↓
[ button-dashboard ] ← browser
Full walkthrough: docs/ARCHITECTURE.md
The first unconfigured device you power on becomes the setup leader — it creates a Button_Setup access point. Every device powered on within the next second or two joins as a follower over UDP. You connect your phone or laptop to Button_Setup, visit http://192.168.4.1, pick your home WiFi, enter the password once, and assign a module type to each device that joined. They all reboot, connect to your network, and find the server automatically.
No per-device flashing. No serial cable. No configuration files to edit.
Hardware details: docs/HARDWARE.md
Shows every registered device, where it lives, and which buttons on it have been discovered. Useful for getting an overview across an entire space — a home, an office, or a makerspace floor.
Groups buttons by meaning rather than by physical device. A child's console has four buttons; a makerspace might have buttons on six different devices. Pouches let you drag buttons into whatever groupings make sense to you — the layout is freeform, not always a grid. Think of it as your own personal button mixtape.
Timeline and histogram views of click activity, with per-button breakdowns.
Buttons can optionally observe modes — a list of strings pushed from the server to the device's OLED display. The rotary encoder lets the user scroll through the list; the currently selected mode is shown on screen and attached to each button press as context.
Example: A kitchen device has modes ["Dad", "Mom", "Son"]. Every press of the Water button records not just that someone drank water, but who did.
Mount a small device on the fridge, by the exercise mat, on the nightstand. Each button is one behavior. No phone required.
A device near each machine logs equipment use. Wall-mounted buttons near storage racks track consumable inventory. The map view gives staff a live picture of what's being used and where.
Four big buttons. Any shape, any emoji, any color. The child decides what each one means. Parents see the data. Pouches let you arrange them however they want — no grid required.
More use case details: docs/USE-CASES.md
- Voice memos — Hold a dedicated button while speaking; the device records audio and transmits it to the server, which runs speech-to-text and saves it as a timestamped note. A button + a microphone = a hands-free reminder log.
- More device types — The firmware's module system is designed to accommodate new hardware profiles beyond the standard button grid.
- Richer dashboard — Additional pouch layouts, sharing, and per-device configuration from the web UI.
| Component | Stack |
|---|---|
| Firmware | C++ / Arduino (ESP32-S3) |
| Backend API | Node.js · Express 5 · SQLite |
| Dashboard | React 19 · Vite · Tailwind CSS · Recharts · dnd-kit |
| Device Discovery | UDP broadcast |
| Device→Server protocol | UDP (events) + HTTP REST (config) |
This project is private source — the repositories are not publicly visible.
If you're interested in collaborating, building on top of this, or just want to take a look around, reach out and ask for access. I'm happy to share with folks who are curious.
| Doc | What's in it |
|---|---|
| Architecture | Full system flow, WiFi provisioning, UDP discovery, API overview |
| Hardware | Components, wiring, button matrix, OLED, rotary encoder |
| Use Cases | Habit tracker, makerspace, kids' console — with examples |
| Access | How to request source code access |
This project is intentionally playful, but the architecture is real: embedded firmware, local-network discovery, event ingestion, persistence, and a React dashboard.


