Building a macOS Status Display with an ESP32-S3
Getting an ESP32-S3 and round display to show live macOS volume, CPU, memory, and battery information over a serial connection.

The idea
I wanted a small screen on my desk that could show a few useful statistics from my Mac without becoming another full monitor. The plan was an ESP32-S3 connected to a round display, with macOS sending it the current volume, CPU use, memory use, and battery percentage.
The hardware for this project is:
Testing it the wrong way first
Before soldering the headers, I connected the display with jumper wires and started troubleshooting why nothing worked reliably.
The answer was not hidden in the firmware. It was not a bad library or some obscure macOS serial problem. The header pins were sitting loose in the ESP32 board, which is not the same thing as making an electrical connection no matter how much I wanted it to be.
That was the point when I realized the headers actually needed to be soldered. Obvious in hindsight, but apparently not obvious enough five minutes earlier.
Testing it that way was also a bad idea. Loose pins can make intermittent contact, bridge connections, or move onto the wrong pin while power is connected. I could have damaged the ESP32, the display, or both. I got lucky and turned the power off before converting a simple oversight into a parts order.
Good enough soldering
I soldered the headers in a hurry because I wanted to find out whether the project worked. The result was not going into a soldering textbook.
Some joints are cleaner than others. They made solid contact, there were no bridges, and the board still powered on. At that moment, those were the three specifications I cared about.
I can clean the joints up later if they give me trouble. For initial testing, they worked, and working hardware has a persuasive argument against taking it apart immediately.
The firmware finally ran
Once the headers were soldered and the display had dependable connections, I flashed the firmware again.
Then the screen came on and started showing the data.
I was genuinely excited. This was one of those small hardware moments where the result should be simple, but it only looks simple after every separate part agrees to work at the same time. The ESP32 had to boot, the display had to initialize, the wiring had to be correct, the serial connection had to open, and the data had to arrive in a format the firmware understood.
When the status screen appeared, all of that stopped being a list of possible failures and became a working object on my desk. I spent a while changing the Mac’s volume just to watch the number move. This was not serious testing, but it was satisfying testing.
Getting the data from macOS
A Python helper runs on the Mac side. It looks for the ESP32’s serial port, connects to it, collects the current system values, and sends snapshots to the board.
The display currently shows:
- Volume
- CPU use
- Memory use
- Battery percentage
- Mac connection status
The ESP32 does not need to know how macOS exposes any of that information. It receives the values over serial and draws them. The Python helper handles the computer-specific work, while the firmware handles the screen.
Automatically finding the serial port matters because device names can change between connections. I do not want to edit a port name every time I unplug the board, move it, or reconnect it through the dock. The helper should find the right device and get on with the job.

Battery was not my best choice
The battery percentage works, but it is not especially useful on this Mac. The laptop spends most of its time connected to a dock, so the battery section usually reports some variation of “still plugged in.”
That space could show something more useful. Network activity, disk use, temperature, uptime, or the current audio device would tell me more than a battery that rarely gets a chance to discharge.
I have not decided what will replace it yet. The important part is that the data path works. Changing one field is now a software problem instead of another round of wondering whether a loose header pin is pretending to be connected.
What comes next
The display is working, the Python helper can find the serial connection, and the firmware can show the snapshots it receives. That is enough to call the first version successful.
I still need to add the hardware links, decide what should replace the battery reading, clean up the wiring, and spend more time testing reconnects. I also want the finished setup to look like something intended to stay on a desk rather than a development board that escaped during assembly.
For now, it works. The soldering may not win any awards, but the screen turns on, the numbers change, and I did not blow up the ESP32. I am counting all three as progress.
I also plan on 3D printing a full case to hold both the ESP32 and the display so it does not look like a jumble of wires on my desk.