
Ich benutze Claude jeden Tag, und die Frage, die ich am häufigsten stelle, dreht sich nicht um Code. Sie lautet: “Wie viel von meiner Woche ist noch übrig?” Der /usage-Bildschirm von Claude Code beantwortet sie, aber nur, wenn ich innehalte und sie eintippe. Ich wollte die Antwort auf meinem Schreibtisch, so wie eine Uhr die Zeit anzeigt.
Der M5Stack Basic passt gut. Er ist ein fertiges Gerät: ein 2-Zoll-320×240-Bildschirm, drei Tasten, ein Akku und ein ESP32 in einem 54-mm-Gehäuse. Kein Breadboard, kein Löten.
Dieser Artikel beschreibt das Dashboard: was es anzeigt, wie die Daten von Claude auf den Bildschirm gelangen, wie sich das Gerät ohne jede Einrichtung verbindet und welche Schritte nötig sind, um dein eigenes zu bauen. Die UI wurde auf dem M5Stack Core in Velxio entworfen, bevor sie die Hardware berührte, und diesen Weg empfehle ich, wenn du eines bauen willst. Du kannst diese Firmware auch in deinem Browser ausführen, mit Demo-Daten, ohne das Gerät.
Das Dashboard auf dem Gerät: auf YouTube ansehen.
Der gesamte Code, die Firmware und die PC-Bridge, ist auf GitHub unter der MIT-Lizenz verfügbar: velxio/m5claude. Der Abschnitt “Der Code, Teil für Teil” weiter unten geht durch, was jede Datei tut.
Die Hardware

Das Board ist das M5Stack Basic Core IoT Development Kit v2.7:
- ESP32-D0WDQ6-V3, zwei Kerne mit 240 MHz.
- 520 KB SRAM und kein PSRAM. Diese Einschränkung prägt die Firmware.
- 16 MB Flash.
- Ein 2-Zoll-320×240-IPS-Panel mit einem ILI9342C-Controller, beim v2.7 hinter Glas.
- Drei Tasten (A, B, C) auf GPIO 39, 38 und 37.
- Ein CH9102-USB-zu-Seriell-Chip, Wi-Fi und Bluetooth LE.
- Ein 1-W-Lautsprecher auf GPIO 25.
- Ein IP5306-Stromchip mit einem 110-mAh-Akku, über I2C auslesbar.
Sonst ist nichts nötig: Das Dashboard nutzt nur, was im Gehäuse steckt. Das Board hat keinen IMU, kein Mikrofon, keine LEDs und keine Echtzeituhr, also nutzt das Dashboard alles andere: den Bildschirm und die Tasten, den Lautsprecher für Alarme, die Hintergrundbeleuchtung zum Stromsparen und den Stromchip zur Anzeige des Ladezustands.
Was der Bildschirm zeigt
Das Dashboard funktioniert mit zwei Arten von Claude-Konten und mit mehreren von jeder:
- Pro- und Max-Abos. Diese haben Nutzungslimits: ein 5-Stunden-Sitzungsfenster, ein Wochenlimit und Wochenlimits pro Modell. Der Bildschirm zeigt jedes davon als Prozentwert mit seiner Rücksetzzeit.
- API-Organisationen. Diese zahlen pro Token, daher zeigt der Bildschirm stattdessen die Ausgaben: heute und die letzten sieben Tage, in Dollar.
Für beide zeigt es Tokens pro Tag für die letzte Woche, aufgeteilt in Eingabe, Ausgabe, Cache-Lesevorgänge und Cache-Schreibvorgänge sowie nach Modell.
Es gibt vier Ansichten. B wechselt zur nächsten, A und C wechseln zwischen Konten, Gedrückthalten von B fordert frische Daten vom PC an, und Gedrückthalten von C öffnet die Einstellungen. Das sind alle Bildschirme, mit der Animation, die jede Ansicht beim Öffnen abspielt:

Übersicht. Eine Karte pro Konto. Das Layout passt sich an, wie viele Konten es gibt: ein Konto füllt den Bildschirm, zwei bekommen höhere Karten mit einer Zeile für die heutige Nutzung, und drei oder mehr werden zu einer scrollbaren Liste.


Limits. Das Wochenlimit als Ring, mit der Sitzung und den Limits pro Modell daneben. Die Modellnamen kommen von Claude selbst, sodass die Zeilen den Limits folgen, die dein Plan hat. Die Farben ändern sich bei 60 % (Bernstein) und 85 % (Rot).

Tokens. Heute, die letzten sieben Tage und der Dollar-Betrag, dann Tokens pro Tag mit einer gestrichelten Linie beim Durchschnitt. Bei einem Abo ist der Dollar-Betrag das, was dieselben Tokens zu API-Listenpreisen kosten würden. Es ist keine Abbuchung, aber eine nützliche Möglichkeit zu sehen, wie stark du den Plan nutzt.


Aufschlüsselung. Die Tokens der Woche nach Typ und nach Modell. Mit Claude Code sind Cache-Lesevorgänge normalerweise der Großteil der Summe.


Der Punkt neben der Uhr zeigt die Verbindung: grün, solange die Daten frisch sind, bernsteinfarben, wenn sie veraltet sind, rot, wenn kein PC verbunden ist. Die Fotos zeigen mein eigenes Konto. Die Screenshots verwenden Demo-Konten.
Akku, Ton und Einstellungen
Neben der Uhr ist der Akku, gezeichnet wie Telefone es tun: der Ladestand und ein Blitz mit einer Füllung, die beim Laden ansteigt. Der IP5306-Stromchip meldet nur vier Stufen (25, 50, 75 und 100 %), daher bewegt sich die Zahl in 25er-Schritten.

Der Lautsprecher wird für Warnungen verwendet. Wenn eine Sitzung oder ein Wochenlimit 90 % überschreitet (oder 80 %, wenn du das wählst), spielt das Gerät einen kurzen doppelten Ton und zeigt, welches Konto und welches Limit betroffen ist. Wenn ein Limit zurückgesetzt wird, spielt es einen aufsteigenden Ton. Genehmigungsanfragen von einem neuen Computer geben ebenfalls einen Ton. Button-Klicks sind optional.
Gedrückthalten von C öffnet die Einstellungen. A und C bewegen, B ändert einen Wert, und Gedrückthalten von B schließt den Bildschirm. Die Einstellungen werden auf dem Gerät gespeichert.

- Sprache. Englisch oder Spanisch. Jeder Text auf dem Bildschirm lebt in einer Tabelle, sodass das Hinzufügen einer Sprache ein weiterer Eintrag ist.
- Helligkeit. 25, 50, 75 oder 100 %.
- Töne. Aus, nur Warnungen oder Warnungen und Button-Klicks.
- Warnung bei. 80 %, 90 % oder aus.
- Bildschirm aus im Akkubetrieb. Nie, nach einer Minute oder nach fünf. Jeder Button weckt ihn, und der Druck, der ihn weckt, tut nichts anderes. Bei einem 110-mAh-Akku ist das wichtig.
- Nachtdimmung. Senkt die Hintergrundbeleuchtung von 22:00 bis 07:00 Uhr, unter Verwendung der PC-Uhr.
- Gekoppelte Computer. Wie viele genehmigt sind, und B vergisst sie nach einer Bestätigung.


110 mAh haltbar machen
Die erste Firmware entleerte den Akku in deutlich weniger als einer Stunde. Die CPU lief mit 240 MHz, der Bildschirm wurde jede Sekunde neu gezeichnet, und das Funkmodul sendete mit voller Leistung und einem Verbindungsintervall von 15–30 ms. Nichts davon ist nötig, um eine Zahl anzuzeigen, die sich einmal pro Minute ändert. Im Akkubetrieb macht die Firmware jetzt Folgendes:
- CPU mit 80 MHz, die niedrigste Geschwindigkeit, die Bluetooth unterstützt. Bei USB-Strom kehrt sie zu 240 MHz zurück.
- Hintergrundbeleuchtung: Sie dimmt nach 20 Sekunden ohne Buttondruck und schaltet sich nach der in den Einstellungen gewählten Zeit aus.
- Standby: 15 Sekunden nachdem der Bildschirm ausgeht, schaltet sich das Funkmodul ab und der ESP32 geht in Light Sleep. Der RAM bleibt erhalten, sodass jeder Button den Bildschirm sofort mit den letzten Daten zurückbringt und die Bridge sich innerhalb von Sekunden wieder verbindet. Alle 10 Minuten weckt ein Timer ihn für bis zu 45 Sekunden, während der Bildschirm aus bleibt. Er holt frische Daten, und wenn ein Limit die Warnschwelle überschritten hat, beleuchtet er den Bildschirm und spielt die Warnung ab.
- Funk: 0 dBm statt +9, Werbung alle 0,5–1 s und ein Verbindungsintervall von 100–200 ms mit Slave Latency. Ein Snapshot von 600 Byte pro Minute braucht kaum mehr.
- Neuzeichnungen erfolgen nur, wenn sich die Minute ändert oder neue Daten eintreffen, und im Akkubetrieb gibt es keine Leerlaufanimationen.
Für den ganzen Tag abseits des Schreibtischs stapelt sich das Battery Module 13.2 unter dem Basic und fügt 1500 mAh hinzu.
So funktioniert es
Die Designregel lautet, dass das Gerät nichts weiß. Es enthält keine Claude-Zugangsdaten und keine Wi-Fi-Einstellungen. Ein kleines Programm auf dem PC, die Bridge, sammelt alles und sendet dem Gerät einen Snapshot zum Zeichnen. Das hält Geheimnisse von einem Gerät fern, das auf einem Schreibtisch steht, und bedeutet, dass ein Wechsel des Computers oder Netzwerks keine Neukonfiguration erfordert.
Woher die Daten kommen
Die Bridge besteht aus etwa 1.100 Zeilen Python mit zwei Abhängigkeiten (pyserial und bleak). Sie liest drei Quellen:
- Tariflimits aus dem Login von Claude Code. Jedes Konfigurationsverzeichnis von Claude Code (
~/.claude,~/.claude-work, …) enthält den Login eines Kontos. Die Bridge findet sie alle und nutzt jedes Token, um dieselben Limits zu lesen, die der/usage-Bildschirm von Claude Code anzeigt. Sie liest das Token nur und erneuert es nie, denn eine Erneuerung würde das Token rotieren und Claude Code abmelden. - Tokens aus den Transkripten von Claude Code. Jede Antwort, die Claude Code erhält, wird in eine JSONL-Datei unter
projects/geschrieben, zusammen mit ihrer Token-Nutzung und dem Modell. Die Bridge summiert diese pro Tag, entfernt Duplikate (eine fortgesetzte Sitzung kopiert frühere Nachrichten in eine neue Datei) und bepreist sie mit der API-Preisliste. - Ausgaben für API-Organisationen aus der Usage and Cost Admin API.
usage_report/messagesliefert Tokens pro Tag und Modell.cost_reportliefert die tatsächlichen Ausgaben. Beide benötigen einen Admin-API-Schlüssel (sk-ant-admin01-...).
Zwei Lektionen aus dem Betrieb mit echten Konten:
- Der Limits-Endpunkt ist rate-limitiert. Während meiner Tests begann er, HTTP 429 ohne
Retry-Afterzurückzugeben. Die Bridge liest Limits jetzt alle fünf Minuten statt jede Minute, behält die letzte gute Antwort auf der Festplatte und zeigt sie durch temporäre Fehler hindurch weiter an. Tokens werden weiterhin jede Minute aktualisiert, da sie aus lokalen Dateien stammen. - Transkripte werden groß. Meine waren 665 MB. Die Bridge liest nur Dateien, die in den letzten acht Tagen geändert wurden, und parst eine Datei nur neu, wenn sich ihre Größe oder Änderungszeit ändert. Eine Aktualisierung dauert etwa eine Sekunde.
Der Snapshot
Jede Aktualisierung erzeugt eine JSON-Zeile von etwa 600 Bytes:
{"v":1,"ts":1792770195,"tz":3600,"acc":[
{"n":"Personal","p":"Max 20x","k":"sub","ok":1,
"s":[42,1792778235],"w":[67,1793037195],"x":[["Opus",54,1793037195],["Sonnet",31,1793037195]],
"td":2840000,"tk":[2310000,1480000,15900000,1120000],"c":84.2,"ct":11.35,
"d":[1900000,3400000,2600000,4100000,3300000,2670000,2840000],"m":[["Opus",61],["Sonnet",34],["Haiku",5]]}]}
s, w und x sind die Sitzungs-, Wochen- und Pro-Modell-Limits als [Prozent, Rücksetzzeit]. d sind Tokens pro Tag. ts und tz sind die Uhr des PCs und der UTC-Offset. Der M5Stack Basic hat keine Echtzeituhr und keine Zeitzonendatenbank, daher übernimmt das Gerät beides aus dem Snapshot und zählt die Sekunden von dort aus weiter. Das reicht für „setzt zurück in 2h 14m” und „Di 04:00”.
Verbinden ohne Konfiguration
Ich wollte überhaupt kein Setup. Ein Wi-Fi-Passwort in ein Gerät mit drei Tasten einzutippen ist unangenehm. Die IP-Adresse des PCs auf dem Gerät zu speichern, bricht, sobald man den Computer wechselt. Also unterstützt das Gerät zwei Verbindungen, und keine davon braucht Einstellungen.
USB. Kabel einstecken. Die Bridge sucht nach seriellen Ports, deren USB-Chip von einem M5Stack stammt (CH9102 oder CP2104). Sie öffnet den Port, ohne DTR und RTS umzuschalten, damit der ESP32 nicht zurückgesetzt wird, und wartet auf eine Begrüßung. Die Firmware sendet alle zwei Sekunden {"hello":"m5claude",...}, bis Daten ankommen. Kommt innerhalb weniger Sekunden keine Begrüßung an, gibt die Bridge den Port frei und lässt ihn eine Weile in Ruhe, damit andere ESP32-Boards und Flash-Werkzeuge nicht beeinträchtigt werden.
Bluetooth LE. Die Firmware bewirbt einen GATT-Dienst mit zwei Characteristics: eine, in die der PC Zeilen schreibt, und eine, auf der das Gerät Benachrichtigungen sendet. Die Bridge sucht nach der Dienst-UUID und verbindet sich. Es gibt keinen Windows-Kopplungsdialog und nichts, was man aus einer Liste auswählen müsste.
Da jeder Computer in Reichweite das Gerät finden könnte, wird jeder neue PC einmal auf dem Gerät bestätigt:

Die Bridge speichert eine zufällige ID in ~/.m5claude/pc_id. Das Gerät speichert die IDs von bis zu vier bestätigten PCs im NVS. Ein bekannter PC wird sofort akzeptiert, und A beim Einschalten gedrückt zu halten vergisst alle. Ein Gerät, das bereits über USB verbunden ist, wird bei Bluetooth übersprungen, damit es nicht gebeten wird, denselben PC zweimal zu bestätigen.
Bis die Bridge läuft, zeigt das Gerät an, was zu tun ist:

Die Firmware
Die Firmware ist ein Arduino-Sketch, der mit arduino-cli auf dem arduino-esp32-2.0-Core gebaut wird. Sie verwendet drei Bibliotheken:
- LovyanGFX zum Zeichnen des Bildschirms.
- NimBLE-Arduino für Bluetooth. NimBLE verbraucht etwa die Hälfte des RAMs des Standard-Bluedroid-Stacks.
- ArduinoJson 7 zum Parsen von Snapshots.
Der UI-Code hängt nicht von der Hardware ab. Er zeichnet in ein LovyanGFX-Ziel und liest die drei Tasten. Alles, was spezifisch für das Board ist (das Panel, USB, BLE, NVS), lebt im Sketch.
Einige Details, die es wie ein Produkt statt wie eine Demo aussehen lassen:
- Anti-aliasing-Text. Die Schriften sind Inter, konvertiert in LovyanGFX’s glattes VLW-Format durch ein kleines Python-Skript in sechs Größen. Das Skript enthält nur die Zeichen, die jede Größe verwendet, insgesamt etwa 77 KB.
- Anti-aliasing-Anzeigen. Die Ringe werden pro Pixel gezeichnet: Die Abdeckung wird aus dem Abstand zu den Rändern des Rings berechnet, und die Enden sind abgerundet. Balken und Karten verwenden LovyanGFX’s glatte abgerundete Rechtecke.
- Kurze Animationen. Bei jedem Ansichtswechsel wachsen Balken und Zahlen über eine halbe Sekunde mit einer Ease-out-Kurve zu ihren Werten.
Zeichnen ohne PSRAM und die diagonalen Streifen
Ein vollständiger 320×240-Frame in 16-Bit-Farbe sind 150 KB. Der größte freie Speicherblock des ESP32 ist mit laufendem Bluetooth kleiner als das. Also wird die UI viermal pro Frame in ein 320×60-Band (38 KB) gezeichnet. Jeder Durchlauf zeichnet alles um den Offset des Bands nach oben verschoben, und Teile, die außerhalb des Bands liegen, werden abgeschnitten.
Als dies zum ersten Mal auf dem Board lief, zeigte der Bildschirm diagonale Streifen, und die Tasten der Bestätigungsabfrage erschienen zweimal, oben und unten. Die Panel-Konfiguration war mein erster Verdacht. Ich schrieb sie von Hand aus der M5Stack-Dokumentation neu, und nichts änderte sich. Die Ursache lag woanders:
LovyanGFX sendet einen Sprite mit DMA im Hintergrund an das Panel. Meine Schleife begann, das nächste Band in denselben Puffer zu zeichnen, während das vorherige noch gesendet wurde, sodass das Panel die Hälfte eines Bands und die Hälfte des nächsten erhielt. Die Lösung verwendet zwei Puffer abwechselnd und wartet auf die vorherige Übertragung, bevor gepusht wird:
for (int y = 0, k = 0; y < 240; y += 60, k ^= 1) {
LGFX_Sprite& band = bands[k];
band.fillScreen(BG);
draw_ui(band, /*offset_y=*/y); // runs while the other buffer is still being sent
lcd.waitDMA(); // the other buffer's transfer has finished
band.pushSprite(&lcd, 0, y); // starts this buffer's transfer
}
lcd.waitDMA();
Das kostet einen weiteren 38-KB-Puffer, von etwa 275 KB freiem RAM.
Der Code, Teil für Teil
Lade den Code mit git clone https://github.com/velxio/m5claude.git herunter oder als ZIP über die Schaltfläche Code des Repositories. Er besteht aus zwei Hälften, die nichts außer dem Protokoll gemeinsam haben: bridge/ läuft auf dem PC, und firmware/ plus src/ laufen auf dem M5Stack.
Auf dem M5Stack
firmware/m5claude/m5claude.ino: alles, was spezifisch für die Platine ist.
- Die Panel-Konfiguration: ILI9342C auf VSPI, seine Pins, Rotation und Farbinvertierung.
- Die USB-Verbindung. Sie liest den seriellen Port und schreibt Antworten.
- Die Bluetooth-Verbindung. Sie ist ein NimBLE-GATT-Dienst mit einer Characteristic, in die der PC schreibt, und einer, auf der das Gerät benachrichtigt. Bytes, die in NimBLEs Callbacks empfangen werden, landen in einem Stream-Puffer und werden in
loop()verarbeitet, sodass der restliche Code nie auf dem Bluetooth-Task läuft. - Die Liste der freigegebenen PCs und die Einstellungen, gespeichert im NVS mit
Preferences. - Die Batterie: alle zwei Sekunden liest sie über I2C die Lade-, Ladeabschluss- und Füllstandsbits des IP5306.
- Der Lautsprecher: ein kleiner Sequencer spielt die Alarm-, Reset- und Pairing-Töne mit LEDC-Rechteckwellen bei niedrigem Tastverhältnis ab und hält dann den Pin auf Low, damit der Lautsprecher zwischen den Tönen nicht zischt.
src/app/app.cpp: das Protokoll, unabhängig von der Verbindung.
- Jede Verbindung (USB oder Bluetooth) bekommt ihren eigenen Zeilenpuffer und Zustand. Es parst eine Zeile bei jedem Zeilenumbruch und wiederholt die Begrüßung alle zwei Sekunden, bis Daten ankommen.
- Eine nicht vertrauenswürdige Verbindung durchläuft eine Freigabe: Das Gerät fragt die UI, merkt sich die Antwort und antwortet mit
pair: okoderdenied. - Es verwandelt ein langes Drücken von B in
{"req":"refresh"}. - Es behält eine Kopie des vorherigen Snapshots, damit die UI erkennen kann, wenn ein Limit die Alarmschwelle überschritten hat oder zurückgesetzt wurde.
- Es führt die Uhr: die Zeit des letzten Snapshots plus die Sekunden seit seiner Ankunft.
src/model/: die Daten.
model.hbeschreibt ein Konto: Tarif, Limits als Prozent und Reset-Zeit, Tokens pro Tag, Kosten und Modelle.parse.cppfüllt das Modell aus einem Snapshot mit ArduinoJson. Es parst in eine separate Kopie und ersetzt die aktuellen Daten nur, wenn die gesamte Zeile gültig ist, sodass eine beschädigte Zeile den Bildschirm nie halb aktualisiert zurücklassen kann.mock.cppenthält die Demo-Konten, die in den Screenshots dieses Artikels verwendet werden, nützlich während der Gestaltung.
src/ui/: die Bildschirme.
ui.cppzeichnet die vier Ansichten, die Einstellungen und die Freigabeabfrage. Es behandelt die Tasten: ein Klick oder ein langes Drücken nach 650 ms. Es führt die Halbsekunden-Animationen aus, entscheidet über die Hintergrundbeleuchtungsstufe (gewählte Helligkeit, Nachtdimmung, aus bei Leerlauf im Akkubetrieb), löst die Limit-Alarme aus und rendert in Bändern mit zwei DMA-Puffern.i18n.henthält jeden String auf dem Bildschirm, auf Englisch und Spanisch, einschließlich der Wochentagsnamen und der Fehlermeldungen der Bridge.gfx.henthält die Farben und die Zeichenhelfer: abgerundete Balken, den kantengeglätteten Ring und den Offset, der es demselben Zeichencode ermöglicht, jedes Band zu füllen.fonts_gen.henthält die Inter-Schriften. Sie werden vontools/make_fonts.pygeneriert.
Auf dem PC
Die Bridge liegt in bridge/m5claude_bridge/. Ihre einzigen Abhängigkeiten sind pyserial und bleak. HTTPS-Aufrufe verwenden die Standardbibliothek.
__main__.py: die Kommandozeile und die Hauptschleife.
- Die Befehle sind
run,snapshot,accounts,init,add-apiundautostart. - Vor dem Ausführen nimmt es eine Sperre (ein lauschender Socket auf localhost), sodass immer nur eine Bridge läuft.
runsammelt alle 60 Sekunden einen Snapshot oder sofort, wenn ein Gerät einen anfordert, und übergibt ihn an den Hub.
autostart.py registriert die Bridge so, dass sie sich beim Anmelden ohne Fenster startet: der Run-Registrierungsschlüssel mit pythonw unter Windows, ein LaunchAgent unter macOS, eine systemd-User-Unit unter Linux.
config.py: die Konten.
- Es erkennt jedes Claude-Code-Konfigurationsverzeichnis mit einem Login.
- Alternativ liest es
~/.m5claude/config.json, wo du Konten benennen und API-Organisationen hinzufügen kannst.
sources/: eine Datei pro Datenquelle.
subscription.pyliest den Claude-Code-Login eines Kontos und seine Tariflimits.local_logs.pyliest die Transkripte von Claude Code. Es parst inkrementell, entfernt doppelte Nachrichten und summiert Tokens pro Tag und pro Modell.admin_api.pyliest die Usage and Cost Admin API für API-Organisationen und folgt der Paginierung.
pricing.py enthält die API-Listenpreise pro Modellfamilie. Es schätzt den Wert der Abonnementnutzung.
snapshot.py: baut den Snapshot.
- Es sammelt jedes Konto parallel, sodass ein langsames Konto die übrigen nicht verzögert.
- Es wendet die Limit-Richtlinie an: alle fünf Minuten, mit der letzten guten Antwort auf der Festplatte zwischengespeichert und bei temporären Fehlern beibehalten.
hub.py behält den neuesten Snapshot und gibt ihn an jedes verbundene Gerät weiter. Eine langsame Verbindung bekommt nur den neuesten, nie einen Rückstau.
transports/: eine Datei pro Verbindung.
usb_serial.pyfindet M5Stack-USB-Chips und behält einen Port nur, wenn die Firmware ihn begrüßt.ble.pyscannt, verbindet, wartet auf die Freigabe und schreibt in Blöcken, die in die ausgehandelte MTU passen.tcp.pyist eine lokale Verbindung für die Entwicklung.
Die README des Repositories enthält dieselbe Tour als Tabellen, plus Fehlerbehebung.
Baue dein eigenes
Die Reihenfolge, die ich empfehle: Entwirf die Bildschirme in Velxio, flashe dann das Board und verbinde anschließend die Bridge.
1. Ausführen und anpassen auf dem M5Stack Core in Velxio
Velxio simuliert den M5Stack Core mit seinem 320×240-Bildschirm, den Tasten A, B und C sowie dem Batterie-Chip. Einen 2-Zoll-Bildschirm zu gestalten bedeutet viele kleine Anpassungen (ein Label zwei Pixel zu tief, eine Zahl, die nicht in ihre Karte passt), und jede davon dauert im Browser Sekunden statt eines Flash-Zyklus.
Das Dashboard ist in Velxios Beispielgalerie enthalten, mit denselben Quelldateien wie im Repository:
- Öffne M5Stack Core: Claude usage dashboard (m5claude) und klicke auf die Play-Schaltfläche. Eine Anmeldung ist nicht nötig. Es startet mit den Demo-Konten aus diesem Artikel.
- Klicke auf A und C, um ein Konto auszuwählen, und auf B, um durch die Ansichten zu blättern. Der Simulator führt die Firmware langsamer aus als das Board, um die Einstellungen zu öffnen, halte C einige Sekunden lang gedrückt.
- Um deine eigenen Zahlen zu sehen, führe
m5claude-bridge snapshotauf deinem PC aus und füge die ausgegebene Zeile in den seriellen Monitor ein. Der erste Kommentar im Sketch enthält eine Beispielzeile, die du bearbeiten kannst. - Ändere die Bildschirme in
ui.cppund führe es erneut aus. Wenn sie richtig aussehen, flashe das Board.
Zwei Dinge unterscheiden sich vom Board: Velxio hat kein Bluetooth, daher entfällt diese Verbindung und der serielle Monitor ist die einzige Verbindung, und der Lautsprecher-Code verwendet die Aufrufe des neueren ESP32-Arduino-Cores. Jede Änderung ist im Sketch markiert.
Um ein eigenes Dashboard von einem leeren Bildschirm aus zu starten, ist M5Stack Core: Hello LCD + Buttons das kleinste Beispiel. Es verwendet M5Stacks M5GFX, das auf LovyanGFX aufbaut und dessen Zeichen-API teilt, sodass Code zwischen beiden übertragbar ist.
2. Die Firmware flashen
git clone https://github.com/velxio/m5claude.git && cd m5claude
arduino-cli core install esp32:esp32
arduino-cli lib install LovyanGFX NimBLE-Arduino ArduinoJson
./firmware/build.sh /dev/ttyUSB0 # Linux / macOS
.\firmware\build.ps1 -Upload # Windows, finds the COM port by itself
Die Skripte bauen für den M5Stack Core mit einem Partitionsschema, das Platz für eine große App lässt (PartitionScheme=no_ota). Die Firmware ist etwa 820 KB groß. Zwei Einstellungen haben mich erwischt:
- C++17. Der arduino-esp32-2.0-Core kompiliert standardmäßig als C++11, und der Code verwendet C++14- und C++17-Funktionen. Füge
--build-property "compiler.cpp.extra_flags=-std=gnu++17"hinzu. - Das Panel. Ich konfiguriere das ILI9342C explizit (VSPI, MOSI 23, MISO 19, SCK 18, CS 14, DC 27, RST 33, Backlight 32,
offset_rotation = 3), anstatt LovyanGFX’ Board-Autoerkennung zu verwenden. Das IPS-Panel des v2.7 benötigt invertierte Farben. Es wird auf dieselbe Weise erkannt wie bei M5Stacks eigenen Bibliotheken: daran, wie die Reset-Leitung zurückgelesen wird.
3. Die Bridge ausführen
pip install -e bridge # from the repository root; installs pyserial and bleak
m5claude-bridge accounts # which accounts it found
m5claude-bridge autostart on # start now, and at every login
autostart on registriert die Bridge so, dass sie bei der Anmeldung ohne Fenster startet. Unter Windows fügt es einen Wert unter dem Run-Registrierungsschlüssel des Benutzers hinzu, der pythonw startet. Unter macOS installiert es einen LaunchAgent und unter Linux einen systemd-Benutzerdienst. autostart status zeigt an, ob sie läuft, und die letzten Zeilen ihres Logs in ~/.m5claude/bridge.log. Es läuft immer nur eine Bridge gleichzeitig: Eine zweite würde um den USB-Port und die Bluetooth-Verbindung konkurrieren, daher beendet sie sich mit einer Meldung. Wenn du m5claude-bridge allein ausführst, bleibt sie im Vordergrund, mit dem Log im Terminal.
Pro- und Max-Konten werden aus den Konfigurationsverzeichnissen von Claude Code gefunden. Um ein zweites Abonnement hinzuzufügen, melde es unter seinem eigenen Verzeichnis an:
$env:CLAUDE_CONFIG_DIR = "$HOME\.claude-work"; claude # then /login
API-Organisationen benötigen einen Admin-API-Schlüssel aus der Claude Console unter Settings → Admin keys:
m5claude-bridge add-api "Acme API" --key-env ACME_ADMIN_KEY
4. Verbinden
Stecke das USB-Kabel ein, oder lass das Gerät auf dem Schreibtisch stehen und Bluetooth es finden. Beim ersten Mal über Bluetooth drücke C am Gerät, um den PC zu bestätigen. Die Daten erscheinen innerhalb weniger Sekunden.
Einschränkungen
- Der Endpunkt für die Planlimits ist keine öffentliche API. Es ist der Endpunkt, den der
/usage-Bildschirm von Claude Code verwendet, und er könnte sich ändern. Die Bridge fällt auf ältere Feldnamen zurück, aber eine Formatänderung würde ein Update erfordern. - Anmeldungen laufen ab. Claude Code erneuert sein Token, wenn du es verwendest. Ein Konto, das du einige Stunden lang nicht verwendet hast, zeigt “Login expired”, bis Claude Code wieder damit läuft.
- Der Dollar-Betrag für Abonnements ist eine Schätzung zu den API-Listenpreisen. API-Organisationen zeigen ihre tatsächlichen Ausgaben aus dem Kostenbericht.
Wie es weitergeht
- Ein Tray-Symbol auf dem PC, das den Verbindungsstatus anzeigt.
- Ein Verlauf auf der microSD-Karte für Diagramme, die länger als sieben Tage sind.
- Eine RGB-LED am Grove-Port, die über 90 % rot wird und im ganzen Raum sichtbar ist.
- Eine optionale Wi-Fi-Verbindung, konfiguriert von der Bridge über USB oder Bluetooth, damit das Gerät in einem anderen Raum stehen kann.
Der Code ist unter github.com/velxio/m5claude zu finden. Issues und Pull Requests sind willkommen.
Danke an M5Stack für ein Board, das sofort einsatzbereit ist, und an die Autoren von LovyanGFX, NimBLE-Arduino, ArduinoJson und bleak.
Links zum M5Stack-Shop auf dieser Seite sind Affiliate-Links: Wenn du darüber kaufst, verdient Velxio eine kleine Provision ohne zusätzliche Kosten für dich, und es hilft, den Simulator kostenlos zu halten.