Clawdmeter
Clawdmeter: A Small ESP32 Dashboard for Claude Code Usage
Introduction Clawdmeter is a compact, purpose-built ESP32 dashboard designed to live on your desk and keep a watchful eye on Claude Code usage. It runs on a Waveshare ESP32-S3-Touch-AMOLED-2.16, with support for a few alternative boards, and it pairs over Bluetooth to deliver live usage data right to your fingertips. At startup, a splash screen greets you with pixel-art Clawd animations that intensify as your usage rate climbs, turning the room into a little theatre of encoded motion. The device includes two side buttons that act as Space and Shift+Tab via BLE HID, enabling Claude Code’s voice mode and quick mode toggles on the host computer without disrupting focus. This project blends embedded hardware, LVGL-powered UI, and a lightweight daemon that talks to Claude’s API to create a responsive, useful desk companion.
Visuals you can expect
- A usage meter that graphically represents session and weekly activity
- A Clawd animation screen that morphs and thickens as usage escalates
- Clear status indicators about Bluetooth pairing, session data, and the current display state
- Pixel-art Clawd sprites derived from claudepix and built for a playful yet informative UI
- A splash screen that transitions into usable screens with simple taps
Notes on imagery
- Usage meter: assets/demo.jpeg
- Clawd animation screen: assets/demo.gif
- Splash, Usage, and Bluetooth screens: screenshots/splash.png, screenshots/usage.png, screenshots/bluetooth.png
Hardware and board compatibility Out of the box, Clawdmeter supports several Waveshare boards, with a clean path for porting to other hardware:
- Waveshare ESP32-S3-Touch-AMOLED-2.16
- Waveshare ESP32-C6-Touch-AMOLED-2.16
- Waveshare ESP32-S3-Touch-AMOLED-1.8
If you’re using an alternative board, the firmware is designed as a thin hardware abstraction layer (HAL). Per-board folders reside under firmware/src/boards/. You can drop in a new folder and define a new PlatformIO environment; the core files main.cpp, ui.cpp, and splash.cpp stay unchanged. The project documentation includes a walk-through for porting (docs/porting/adding-a-board.md) and details about the HAL interfaces (docs/porting/hal-contract.md). Before opening a new port PR, it’s recommended to check for existing ports and share QA feedback to avoid duplication.
Prerequisites and setup basics Clawdmeter assumes a development environment with Linux (Ubuntu tested) or macOS, plus PlatformIO CLI. You’ll also need tools and dependencies for Bluetooth, the host daemon, and Claude Code access:
- Linux: curl, bluetoothctl, busctl (BlueZ stack)
- macOS: python3 (installer sets up a venv with bleak and httpx)
- PlatformIO CLI
- A Claude Code subscription in good standing
macOS installation and workflow The macOS side includes a Python daemon, a LaunchAgent, and a flash helper. The macOS pieces were contributed by Chris Davidson, and the setup workflow is designed for a smooth first run with proper Bluetooth permissions.
Flashing the firmware
- The recommended commands flash the ESP32 package for the Waveshare AMOLED 2.16, selecting the correct board environment:
- ./flash-mac.sh waveshareamoled216
- ./flash-mac.sh waveshareamoled18 (when targeting the 1.8/1.9-inch variants)
- If you’re using a specific USB serial port, provide it explicitly:
- /dev/cu.usbmodem1101 for the 18-inch variant
- You can see all available environments by running ./flash-mac.sh with no arguments (the list is scraped from firmware/platformio.ini)
Pairing the device
- After flashing, open System Settings → Bluetooth and connect to “Clawdmeter.” The daemon will discover it on its next scan (roughly 30 seconds).
Installing the daemon
- The daemon reads your Claude Code OAuth token from the macOS Keychain (service Claude Code-credentials), polls usage every 60 seconds, and transmits the data to the display over BLE.
- The installation steps create a Python venv, install the required packages, render a LaunchAgent, and load it. The first run prompts for Bluetooth permission.
- Useful commands:
- launchctl list | grep claude-usage
- tail -F ~/Library/Logs/claude-usage-daemon.out.log
- launchctl unload ~/Library/LaunchAgents/com.user.claude-usage-daemon.plist
- launchctl load -w ~/Library/LaunchAgents/com.user.claude-usage-daemon.plist
Linux installation and workflow If you’re using Linux, the process is similar but tailored to Linux tooling and services.
Flashing the firmware
- ./flash.sh waveshareamoled216
- ./flash.sh waveshareamoled18
- As with macOS, you can pass an explicit USB serial port if needed.
Pairing the device
- The device advertises as “Claudemeter.” To pair:
- bluetoothctl scan le
- When Claude Controller appears, pair and trust it
- bluetoothctl pair F4:12:FA:C0:8F:E5
- bluetoothctl trust F4:12:FA:C0:8F:E5
- The MAC address appears on the Bluetooth screen; press the middle (PWR) button to cycle to it.
Installing the daemon
- Start the user-level service:
- ./install.sh systemctl --user start claude-usage-daemon
- Check status and logs:
- systemctl --user status claude-usage-daemon
- journalctl --user -u claude-usage-daemon -f
What the daemon does and how the data flows 1) Token retrieval: The daemon reads your Claude Code OAuth token. On macOS, this lives in the Keychain under the service Claude Code-credentials. On Linux, you store credentials in ~/.claude/.credentials.json or a similar local cache. 2) Minimal API call: It makes a tiny request to api.anthropic.com/v1/messages to pull the most recent usage data, just enough to extract rate-limited metrics. 3) Headers carry usage: The relevant numbers live in response headers such as anthorpic-ratelimit-unified-5h-utilization and related fields. These headers reflect session and weekly utilization. 4) BLE bridge: The daemon connects to the ESP32 over BLE and writes a compact JSON payload to the GATT RX characteristic. 5) LVGL update: The firmware’s LVGL UI consumes the JSON, updating the dashboard with current session %, weekly %, and other stats. 6) Mood-driven splash: The firmware tracks the rate of change of the session percentage over a five-minute window and selects a splash animation that fits the mood of the data. 7) Independent controls: The two side buttons operate independently of the data pipeline and send Space and Shift+Tab as standard BLE HID keyboard inputs to the host.
Physical buttons and their functions Clawdmeter features three side buttons. They’re mapped to consistent actions across screens, with the middle button providing screen-awareness:
- Left button (GPIO 0): Hold to send Space — Claude Code voice-mode push-to-talk
- Middle button (PWR, GPIO not user-mapped): Cycles screens (Usage ↔ Bluetooth); on splash, cycles through animations
- Right button (GPIO 18): Press to send Shift+Tab — Claude Code mode toggle
One important nuance: Space and Shift+Tab are emitted as standard BLE HID keyboard reports, so they trigger in the active window on the paired host, not just within Claude Code.
BLE protocol and payloads The device advertises a custom data service along with the standard HID service. The key identifiers are:
- Data Service UUID: 4c41555a-4465-7669-6365-000000000001
- RX Characteristic (write): 4c41555a-4465-7669-6365-000000000002
- TX Characteristic (notify): 4c41555a-4465-7669-6365-000000000003
- HID Service UUID: 00001812-0000-1000-8000-00805f9b34fb
JSON payload format written to RX: { "s": 45, "sr": 120, "w": 28, "wr": 7200, "st": "allowed", "ok": true }
Field meanings:
- s: session % (current session usage)
- sr: session reset (minutes)
- w: weekly % (weekly utilization)
- wr: weekly reset (minutes)
- st: status
- ok: success flag
Porting and ensuring compatibility Porting to another board follows a simple pattern: new board, new PlatformIO environment; the core application code is board-agnostic, with per-board support contained in firmware/src/boards/. The main entry points (main.cpp, ui.cpp, splash.cpp) do not require changes for a new platform. The porting docs provide the steps, hooks, and interface contracts required for a smooth adaptation.
Font handling and typography The UI uses LVGL-compatible fonts compiled into C sources. Fonts are preprocessed with lvfontconv, and there are important compatibility tweaks to LVGL 9:
- Generate fonts with lvfontconv for specific font files (Tiempos Text, Styrene B, DejaVu Sans Mono)
- Patch generated files to remove LVGL version guards and adjust font descriptor fields for LVGL 9 compatibility
- Ensure proper defaults for font properties, including fallback, user data, and kerning
- For CJK support, a dedicated font (Noto Sans CJK SC) is used at 16px, 2bpp, with LVGL 9 patch requirements
In practice, the font generation steps look like:
- npm install -g lvfontconv
- Generate fonts such as:
- Tiempos Text 56px for titles
- Styrene B in several sizes (48, 28, 24, 20) for panel labels and body text
- DejaVu Sans Mono 32px for UI and symbols
- Apply LVGL 9 patches to ensure proper rendering
- For full CJK coverage, fontcjk16.c handles the basic block along with ASCII and additional punctuation; enabling large font offsets may require a build flag like -DLVFONTFMTTXTLARGE=1
Lucide icons and color handling The UI uses Lucide icons converted to LVGL-ready RGB565 arrays for display and icons such as Bluetooth and battery indicators. The conversion process includes:
- A node-based tool (pngtolvgl.js) that converts PNG icons (e.g., iconbluetooth48.png) into LVGL-friendly hex arrays
- Default tint is white (0xFFFFFF) so black-on-transparent Lucide artwork remains legible on a dark UI
- An option to bypass tinting (--no-tint) for pre-colored artwork like the logo
- Battery icons include an alpha channel via RGB565A8 to blend cleanly over the splash screen
The converted icon data is placed into firmware/src/icons.h
Splash animations and assets Clawdmeter’s splash animations are drawn from claudepix.vercel.app, a library of Clawd sprites. The project uses tooling to scrape frame data and palettes and convert them into C arrays for the firmware:
- tools/scrape_claudepix.js (evaluates the site’s JavaScript to pull frame data)
- tools/converttoc.js (converts frames to RGB565 arrays and generates firmware/src/splash_animations.h)
Re-pulling the animations is straightforward:
- node tools/scrape_claudepix.js
- node tools/converttoc.js
- pio run -d firmware -t upload
You can re-create the animation set after updates to the source library, ensuring the UI remains fresh and synced with the latest Clawd sprites. See the tools/ and docs/ files for deeper details.
Credits and licensing caveats
- Pixel-art Clawd animations: @amaanbuilds via claudepix
- Lucide icon set (bluetooth and battery UI): lucide.dev
- Anthropic brand fonts (Tiempos Text, Styrene B): used under license
- Licensing gray area warning: Because this project uses proprietary fonts and copyrighted Clawd assets in a non-copyleft repo, the author notes licensing limitations. Users should review licensing terms if forking or distributing.
A note on licensing and usage This project relies on proprietary fonts and assets. While the codebase itself is non-proprietary, the fonts and the Clawd mascot assets are licensed for particular uses by Anthropic and the asset providers. The repository contains a licensing warning to highlight these restrictions. If you plan to fork or publish derivatives, you should carefully review the licensing terms and ensure you maintain compliance with the fonts and asset licenses that accompany this project.
Screens and user experience The device cycles between three core views:
- Splash: The initial screen with animated Clawd sprites. The middle button cycles through visual modes when on the splash, and the display auto-rotates through mood-based animations every 20 seconds to avoid a single loop feeling.
- Usage: Presents session and weekly utilization, along with trends and numeric indicators. The usage screen is designed to be readable at a glance, with the LVGL font setup delivering crisp, high-contrast text on the OLED panel.
- Bluetooth: Displays the connection status and bond management—useful when pairing or diagnosing the BLE link.
The device is designed for tactile simplicity: a tap on the display flips between screens, except when you’re in the Bluetooth zone, where tapping the screen won’t dismiss the panel’s state until you exit the zone.
Hardware ports and future directions
- The firmware’s HAL layer is intentionally slim and portable. Adding a new board is primarily about providing a new board folder with the correct initialization sequences and a PlatformIO environment.
- If you tweak or extend the UI, you’ll primarily work in the LVGL-based display code (ui.cpp) and the splash code (splash.cpp). The underlying data flow to the BLE and the host remains stable, making integration smoother for future hardware upgrades.
What you’ll see on screen (summary)
- A visually engaging splash that transitions into real metrics
- A live usage meter that reflects current Claude Code usage and weekly trends
- An easy-to-access Bluetooth status screen for pairing and connection details
- Subtle, responsive animations that reflect the rate of change in usage
Putting it all together: why Clawdmeter matters Clawdmeter is not just a pretty dashboard; it’s a pragmatic bridge between your Claude Code usage and the hardware you already own. By leveraging a compact ESP32-based display, BLE HID integration, and a light-weight daemon that interfaces with Claude’s API, you gain a tangible, at-a-glance view of how your usage evolves over time. The palette of LVGL-driven UI, pixel-art Clawd sprites, and battery-friendly OLED display makes it a delightful desk companion rather than a station-keeping gadget. The architecture favors customization and porting, so if you own a different board or want to experiment with a different set of visual assets, you can adapt with a minimal footprint.
Images included in the post
- Usage meter: assets/demo.jpeg
- Clawd animation: assets/demo.gif
- Splash screen: screenshots/splash.png
- Usage screen: screenshots/usage.png
- Bluetooth screen: screenshots/bluetooth.png
Closing thoughts Clawdmeter demonstrates how a careful blend of hardware, software, and delightful visuals can transform a data stream into a personal, usable display. It’s a practical example of how to present real-time usage data in a way that’s easy to understand at a glance, while also letting you interact with Claude Code in a natural, unobtrusive manner. If you’re enthusiastic about embedded UI design, BLE-enabled gadgets, and the joy of pixel art, Clawdmeter offers a rich, approachable project to explore and extend.
Enjoying this project?
Discover more amazing open-source projects on TechLogHub. We curate the best developer tools and projects.
Repository:https://github.com/HermannBjorgvin/Clawdmeter
GitHub - HermannBjorgvin/Clawdmeter: Clawdmeter
A small ESP32 dashboard to monitor Claude Code usage...
github - hermannbjorgvin/clawdmeter
