A BLE Analog Activity Monitor
- Eldan Ben Haim
- Apr 29, 2022
- 5 min read
I’m not entirely sure about the psychology around it, but some people — me included — have an affection towards big instrument clusters that display various measurements. The utility of these measurements clearly doesn’t justify the space they take so I guess it’s an aesthetics thing. Obviously a matter of taste ;)
A few years back I’ve made this project for my old workplace, as a farewell gift (I was recently told that the device is still alive and kicking!). This includes 3 analog gauges with selectors that allow choosing what is displayed by each gauge: Current DEFCON level, IBM stock level (guess which employer I was departing from), weather, time… The device fetched information from the Internet through a WiFi connection, so it was completely self-sufficient. Er, except for relying on the Internet.

A few months ago I was looking for a quick, non-committing project to relax from the Quadcopter project. I figured that what my desktop really lacks is a touch of geek in the form of an instrument cluster. But what would I measure? For this project, I’ve decided to go for measuring my computer’s CPU and memory usage. This felt well enough within the realm of useless gadgets. Since I use a laptop, clearly this device was supposed to work wirelessly. Now, this was meant to sit on my office desk. I didn’t want to go through the trouble of connecting this to the office WiFi (which would require IT clearance which may be… challenging… to justify), so I had to go for Bluetooth as an infra-less wireless connection. And specifically, I went for BLE.
Hardware
I’ve decided to use an ESP-32 as the microcontroller here. There’s a really compact and complete WeMos D1 Mini board around it going on sale on AliExpress for cheap. It has WiFi which I don’t use in this project, BLE which was the driving factor for choosing it (along with the cost), more than enough PWM outputs to drive the gauges and about 1,382 times the computing power I need for this project :) There are other alternatives. You could go for Arduino BLE (which I bought for this project but decided to keep for future stuff), and there are many other BLE chips.
For the two gauges I got a couple of Ampere-meters measuring up to 20mA. Again, got them on AliExpress. Word of advice: the transparent plastic on these breaks easily on shipment. Luckily I knew I should order some spares, and indeed out of the 4 units I ordered 2 came with usable plastic case. I’ve since ordered another batch for a friend, and these came with better success ratio. The gauges are driven by two transistors (one for each gauge), through a trim-pot and a fixed resistor for each. Ohm’s law tells us we want a roughly 3.3V/0.02A=165Ohm resistance so a constant 100Ohm resistor and a 0-100Ohm trim-pot allow to get to values around this. Obviously doing the trimming in hardware would be more than sufficient for such a simple project (just scale the values to a smaller scale than 0-100% of the PWM duty cycle), but I do have a stock of these trim pots and I think they’re really neat :)
You can see both the schemata and the hand-soldered circuit below.


Mechanics
The mechanics are really simple here. Basically a rectangular panel with rounded edges, and holes cut out for the two Ampere-meters. This is 3D-printed, with silicon anti-skid pads attached to the bottom of the case and some putty dough attached to the base from the inside of the case to add weight.

Software
We have two pieces of software here: one is the firmware for the gauge panel, and the other is a background application running on the monitored machine, connecting to the gauge panel via BLE and transmitting the readouts.
For the firmware things are relatively easy. We use the convenient ESP-32 BLE API to act as a BLE peripheral, advertising one service with two characteristics. Each characteristic can have a value written — and that sets the position of the gauge by setting the PWM duty cycle for the GPIO pin attached to the gauge.
There are two enhancements around this basic scheme that are implemented in the firmware:
When changing the PWM duty cycle of a gauge pin abruptly (e.g switch from 0 to 50%), the gauge would overshoot and correct. In fact, it would often overshoot so badly that it would hit the edge of the scale making an annoying noise. To overcome this, the firmware implements a motion damping mechanism whereby the PWM duty cycle is gradually adjusted towards the desired set point.
Much, much more importantly — on startup, the firmware execute a cool sweep effect on the gauges (see video below). This is probably my favorite feature about this entire project!
For the system monitor background application I’ve used Swift. I’m using CoreBluetooth to implement a BLE central device, search for BLE devices advertising the GaugePanel service and connecting to their characteristics. I used Perfect-SysInfo for the actual system information readout. All in all the thing is relatively trivial. The two war stories here are:
It took a considerable amount of trial-and-error to figure out how to handle recovery from BLE disconnects, machine going to sleep, machine going out-of-range, etc. The CoreBluetooth documentation is a little cheap on details around these topics. The code now is stable enough to work and cope with all of these situations.
I’ve developed this on my work laptop. Unfortunately I forgot to push this to my GitHub repository and so when I left my previous employer, I found myself with an uncontrollable instrument cluster. Now, the last thing you want is an uncontrollable instrument cluster :) So I found myself developing the entire thing from scratch, again. A lot of the learnings from the previous time persisted in my memory, but I must say that I still had to battle with CoreBluetooth more than I hoped for even in this second take at implementing it.
In Closing
The desktop gauge is now sitting on my desk at my new job. It provides me ample entertainment as I wait for software to compile, and loyally provides analog readings that explain the familiar “take off” noise that (Intel) MacBooks tend to make when they are pushed to their limits (e.g., loading a webpage). As a side effect it also makes me seem more sociable — much like the effect of walking around with a puppy or a child ;)

If you want to build one of these yourself, you should really go for it. It’s really easy to do, and a good candidate for a first non “blink led” Make project. The parts are really cheap, and if you don’t have a 3D printer you can easily use a cardboard box for the panel. You can find the software, hardware schematics and mechanics on GitHub here: https://github.com/eldanb/GaugePanel
Comments