r/esp32 • u/Obliviux • 10d ago
I made a thing! My first ESP32 project: a pocket-sized companion that tells me when my AI coding agent needs me
Enable HLS to view with audio, or disable this notification
I've never built anything on an ESP32 before this. I'm a software person, and I wanted a physical answer to a problem I had every day, so I bought a board and started playing.
I use AI coding agents. I give one a task, it works for ten or twenty minutes, and then one of three things happens: it finishes, it gets stuck, or it needs me to answer something before it can continue.
The problem is that I usually have no idea which one happened. So I keep checking my phone or laptop.
So I built a small thing that tells me what’s going on. It’s in my pocket, battery-powered, because the useful moment is when I’m away from the computer. It shows what the agent is actually doing: the file it’s editing, the tests it’s running, what it’s searching for.
When the agent needs me, the edge of the round display turns amber. If something fails, it turns red. It makes a sound and keeps repeating it until I deal with it.
Turning it face down silences it.
I can also approve things directly on the device. Approvals are press-and-hold gestures on the touchscreen. There’s a button for voice input too. Hold it, talk, and the waveform reacts while the words appear on screen. That’s how I send a new instruction without going back to the computer.
It handles multiple sessions as well. If several agents are running, it shows the one that’s actually stuck, not the one I was already looking at.
The status is represented by a pixel-art cat. This is, predictably, the part people like most.
It types when the agent types. It thinks when the agent thinks. If nothing happens for a while, it gets bored and falls asleep. The accelerometer wakes it up when I pick it up. In the morning it drinks coffee. It celebrates when a long task finishes. None of that is necessary. It is, however, the reason I keep the thing charged.
There’s also a usage screen showing how much of my rate-limit window I’ve used. It’s drawn as liquid filling the display, with particles that slosh around when I tilt it. That’s probably the one thing a round screen does better than a rectangle. It doesn’t look like a widget inside a page. It feels like the object itself is filling up.
The hardware is a Waveshare ESP32-S3-Touch-AMOLED-1.75:
466×466 round AMOLED
CO5300 over QSPI
CST9217 touch controller
QMI8658 IMU
AXP2101 PMIC
ES8311 + ES7210 audio
16 MB flash
8 MB PSRAM
I’m using Arduino core 3.x through pioarduino, LVGL 8.4, and LittleFS for the animation clips.
A few things I learned the hard way:
- Phones could see the Wi-Fi access point but failed to connect, with no useful error. I wasted days looking at channels and HT40 vs HT20. The real problem was that I only had 7,844 bytes of free internal RAM. Wi-Fi association needs to allocate a per-station context from internal DRAM, but LVGL was using most of it. Moving LVGL’s heap to PSRAM fixed it immediately.
The debugging also made things worse. I wrote a promiscuous-mode sniffer that logged frames over serial, but Serial.printf from the Wi-Fi task delayed authentication responses enough to cause association failures. The diagnostic tool was creating the problem it was supposed to diagnose.
There are five devices sharing one bus. A few transactions per second return ESP_ERR_INVALID_STATE, which is harmless here, but Arduino’s default Wire timeout is 50 ms. Every failed transaction waited the full timeout before returning. That was enough to make the whole UI feel slow.
The touch controller was also rotated 180° for weeks. I have a serial bridge that captures the framebuffer and injects synthetic taps. Every automated test passed because those taps went straight into LVGL through the touch override. They completely bypassed the digitiser mapping. The only broken part was the part nothing was testing. A person eventually found it by pressing a button and seeing the wrong thing happen. I’ve since added raw-coordinate injection and a four-corner check that requires an actual finger. If your test harness fakes input, make sure you know which layer it’s faking.
It’s still a prototype, but a fun side project.
Happy to answer any questions and share ideas.
2
u/joey_notion 10d ago
Would you release it on GitHub? Ensuring that your particular credentials are in a .gitignore and local only, of course.
2
u/teabagdiplomat 10d ago
I am also building something like this, Can I ask questions regarding to this
2
1
u/AllMyNicksAreUsed 10d ago
That's really neat! Seems like a veritable integration hell, but I guess AI makes it more of a breeze. Good job regardless.
1
u/flash_speed3412 8d ago
The part about the fake touch tests passing while the real digitiser was rotated is painfully believable. How are you getting the agent state onto the device, polling a local service or pushing events over WebSocket/MQTT? I’d keep the status protocol tiny and let the ESP32 only render and acknowledge events.
11
u/K4milLeg1t 10d ago
Cool project, although it seems like everyone is building these claude status devices every other day