Volver

Un panel de uso de Claude en el M5Stack Basic: límites del plan y gasto de API en tu escritorio

El M5Stack Basic sobre el teclado de un portátil mostrando el panel: una cuenta Claude Max al 88% de su límite semanal, la sesión de 5 horas al 30% y 142M de tokens hoy

Uso Claude todos los días, y la pregunta que más me hago no es sobre código. Es “¿cuánto me queda de semana?”. La pantalla /usage de Claude Code la responde, pero solo cuando me paro a escribirla. Quería la respuesta en mi escritorio, como un reloj muestra la hora.

El M5Stack Basic encaja bien. Es un dispositivo terminado: una pantalla de 2 pulgadas y 320×240, tres botones, una batería y un ESP32 en una carcasa de 54 mm. Sin protoboard, sin soldaduras.

Este artículo describe el panel: qué muestra, cómo llegan los datos de Claude a la pantalla, cómo se conecta el dispositivo sin ninguna configuración y los pasos para construir el tuyo. La interfaz se diseñó en el M5Stack Core en Velxio antes de tocar el hardware, y esa es la ruta que recomiendo si quieres construir uno. También puedes ejecutar este firmware en tu navegador, con datos de demostración, sin el dispositivo.

El panel en el dispositivo: míralo en YouTube.

Todo el código, el firmware y el puente en el PC, está en GitHub bajo la licencia MIT: velxio/m5claude. La sección “El código, parte por parte” de más abajo repasa qué hace cada archivo.

El hardware

El M5Stack Basic v2.7: un ESP32 con una pantalla IPS de 2 pulgadas y 320x240, tres botones, USB-C, una ranura microSD y una batería de 110 mAh

La placa es el M5Stack Basic Core IoT Development Kit v2.7:

No hace falta nada más: el panel usa solo lo que viene en la carcasa. La placa no tiene IMU, micrófono, LEDs ni reloj en tiempo real, así que el panel usa todo lo demás: la pantalla y los botones, el altavoz para las alertas, la retroiluminación para ahorrar batería y el chip de alimentación para mostrar la carga.

Qué muestra la pantalla

El panel funciona con dos tipos de cuentas de Claude, y con varias de cada uno:

Para ambos, muestra los tokens por día de la última semana, desglosados en entrada, salida, lecturas de caché y escrituras de caché, y por modelo.

Hay cuatro vistas. B pasa a la siguiente, A y C cambian entre cuentas, mantener pulsado B pide datos nuevos al PC y mantener pulsado C abre los ajustes. Estas son todas las pantallas, con la animación que reproduce cada vista al abrirse:

Un recorrido animado por todas las pantallas: la vista general con tres cuentas, las vistas de límites, tokens y desglose, una organización de API, la vista general de una sola cuenta, la batería cargando, los ajustes en inglés y español, el aviso de aprobación y la pantalla de espera

Vista general. Una tarjeta por cuenta. El diseño se adapta a cuántas cuentas hay: una cuenta llena la pantalla, dos tienen tarjetas más altas con una fila para el uso de hoy, y tres o más se convierten en una lista desplazable.

La vista general con una cuenta de Claude Max: el límite semanal como un anillo, la sesión de 5 horas y los límites por modelo a la derecha, y los tokens de hoy con un gráfico de siete días

La vista general con dos cuentas Max y una organización de API: porcentaje semanal, barras de 5 horas y 7 días, horas de reinicio y gasto de siete días para la cuenta de API

Límites. El límite semanal como un anillo, con la sesión y los límites por modelo al lado. Los nombres de los modelos vienen del propio Claude, así que las filas siguen los límites que tenga tu plan. Los colores cambian al 60% (ámbar) y al 85% (rojo).

La vista de límites: un anillo semanal al 67%, la sesión de 5 horas al 42%, y los límites semanales de Opus y Sonnet

Tokens. Hoy, los últimos siete días y la cifra en dólares, y luego los tokens por día con una línea discontinua en la media. Para una suscripción, la cifra en dólares es lo que costarían esos mismos tokens a los precios de lista de la API. No es un cargo, pero es una forma útil de ver con qué intensidad usas el plan.

La vista de tokens: 2,84 M de tokens hoy, 20,8 M en siete días, un valor de API de 84,20 $ y un gráfico de barras de tokens por día

La vista de tokens en el dispositivo, con 142 M de tokens hoy y 296 M en siete días

Desglose. Los tokens de la semana por tipo y por modelo. Con Claude Code, las lecturas de caché suelen ser la mayor parte del total.

La vista de desglose: una barra apilada de tokens de entrada, salida, lectura de caché y escritura de caché, y la proporción de cada modelo

La vista de desglose en el dispositivo: casi todos los 296 M de tokens de una semana son lecturas de caché, repartidas entre Opus y Fable

El punto junto al reloj muestra el enlace: verde mientras los datos están frescos, ámbar cuando están desactualizados, rojo cuando no hay ningún PC conectado. Las fotos muestran mi propia cuenta. Las capturas usan cuentas de demostración.

Batería, sonido y ajustes

Junto al reloj está la batería, dibujada como la dibujan los teléfonos: el nivel, y un rayo con un relleno que sube mientras carga. El chip de alimentación IP5306 solo informa de cuatro pasos (25, 50, 75 y 100%), así que el número avanza en pasos de 25.

La cabecera mientras carga: 75% con un rayo y una batería verde, junto al punto de enlace y el reloj

El altavoz se usa para las alertas. Cuando una sesión o un límite semanal supera el 90% (o el 80%, si lo eliges), el dispositivo reproduce un breve doble timbre y muestra qué cuenta y qué límite. Cuando un límite se reinicia, reproduce un timbre ascendente. Las solicitudes de aprobación de un ordenador nuevo también suenan. Los clics de los botones son opcionales.

Mantener pulsado C abre los ajustes. A y C se mueven, B cambia un valor y mantener pulsado B cierra la pantalla. Los ajustes se guardan en el dispositivo.

La pantalla de ajustes: idioma, brillo, sonidos, umbral de alerta, apagar pantalla con batería, atenuar de noche, ordenadores emparejados y la versión del firmware

Las mismas pantallas en español: los ajustes y la vista general

La vista general en español

Hacer que 110 mAh duren

El primer firmware agotaba la batería en bastante menos de una hora. La CPU iba a 240 MHz, la pantalla se repintaba cada segundo y la radio transmitía a plena potencia con un intervalo de conexión de 15–30 ms. Nada de eso hace falta para mostrar un número que cambia una vez por minuto. Con batería, el firmware ahora hace esto:

Para un uso de todo el día lejos del escritorio, el Battery Module 13.2 se apila debajo del Basic y añade 1500 mAh.

Cómo funciona

Los datos fluyen desde el inicio de sesión y las transcripciones de Claude Code y desde la Admin API hacia el puente en Python, y luego por USB o Bluetooth LE hasta el M5Stack, que solo dibuja lo que se le envía

La regla de diseño es que el dispositivo no sabe nada. No guarda credenciales de Claude ni ajustes de Wi-Fi. Un pequeño programa en el PC, el puente, lo recopila todo y envía al dispositivo una instantánea para dibujar. Así los secretos no están en un dispositivo que descansa sobre un escritorio, y cambiar de ordenador o de red no requiere reconfigurar nada.

De dónde vienen los datos

El puente son unas 1.100 líneas de Python con dos dependencias (pyserial y bleak). Lee tres fuentes:

  1. Límites del plan, desde el inicio de sesión de Claude Code. Cada directorio de configuración de Claude Code (~/.claude, ~/.claude-work, …) guarda el inicio de sesión de una cuenta. El puente los encuentra todos y usa cada token para leer los mismos límites que muestra la pantalla /usage de Claude Code. Solo lee el token y nunca lo renueva, porque renovarlo rotaría el token y cerraría la sesión de Claude Code.
  2. Tokens, desde las transcripciones de Claude Code. Cada respuesta que recibe Claude Code se escribe en un archivo JSONL dentro de projects/, con su uso de tokens y su modelo. El puente los suma por día, elimina duplicados (una sesión reanudada copia mensajes anteriores a un archivo nuevo) y les asigna precio con la lista de precios de la API.
  3. Gasto de las organizaciones de API, desde la Usage and Cost Admin API. usage_report/messages da los tokens por día y modelo. cost_report da el gasto real. Ambas necesitan una clave de Admin API (sk-ant-admin01-...).

Dos lecciones de ejecutarlo contra cuentas reales:

La instantánea

Cada actualización produce una línea JSON de unos 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 y x son los límites de sesión, semanal y por modelo como [porcentaje, hora de reinicio]. d son los tokens por día. ts y tz son el reloj del PC y su desfase UTC. El M5Stack Basic no tiene reloj en tiempo real ni base de datos de zonas horarias, así que el dispositivo toma ambos de la instantánea y cuenta los segundos a partir de ahí. Eso basta para “se reinicia en 2h 14m” y “mar 04:00”.

Conectar sin configuración

Quería que no hubiera que configurar nada. Escribir una contraseña de Wi-Fi en un dispositivo con tres botones es desagradable. Guardar la dirección IP del PC en el dispositivo deja de funcionar en cuanto cambias de ordenador. Así que el dispositivo admite dos enlaces, y ninguno necesita ajustes.

USB. Enchufa el cable. El puente busca puertos serie cuyo chip USB sea de un M5Stack (CH9102 o CP2104). Abre el puerto sin conmutar DTR y RTS, para que el ESP32 no se reinicie, y espera un saludo. El firmware envía {"hello":"m5claude",...} cada dos segundos hasta que llegan datos. Si no llega ningún saludo en unos segundos, el puente libera el puerto y lo deja tranquilo un rato, para no afectar a otras placas ESP32 ni a herramientas de flasheo.

Bluetooth LE. El firmware anuncia un servicio GATT con dos características: una en la que el PC escribe líneas y otra en la que el dispositivo envía notificaciones. El puente busca el UUID del servicio y se conecta. No hay diálogo de emparejamiento de Windows ni nada que elegir de una lista.

Como cualquier ordenador dentro del alcance podría encontrar el dispositivo, cada PC nuevo se aprueba una vez, en el dispositivo:

El aviso de aprobación: "New computer, DESKTOP-STUDIO. Allow it to send usage data?" con Deny en el botón A y Allow en el botón C

El intercambio de emparejamiento: saludo del dispositivo, el nombre y el id estable del PC desde el puente, una respuesta pendiente, el aviso en pantalla, luego ok, una petición de actualización y las instantáneas

El puente guarda un id aleatorio en ~/.m5claude/pc_id. El dispositivo almacena en NVS los ids de hasta cuatro PCs aprobados. Un PC conocido se acepta al instante, y mantener pulsado A al encender olvida todos. Un dispositivo que ya está conectado por USB se omite en Bluetooth, para no pedirle que apruebe dos veces el mismo PC.

Hasta que el puente está en marcha, el dispositivo muestra qué hacer:

La pantalla de espera: "Waiting for your PC. Run m5claude-bridge on your computer. It connects over USB or Bluetooth automatically."

El firmware

El firmware es un sketch de Arduino compilado con arduino-cli sobre el core arduino-esp32 2.0. Usa tres librerías:

El código de la interfaz no depende del hardware. Dibuja sobre un destino de LovyanGFX y lee los tres botones. Todo lo específico de la placa (el panel, USB, BLE, NVS) vive en el sketch.

Algunos detalles que hacen que parezca un producto y no una demo:

Dibujar sin PSRAM, y las rayas diagonales

Un fotograma completo de 320×240 en color de 16 bits son 150 KB. El mayor bloque de memoria libre del ESP32, con Bluetooth en marcha, es menor que eso. Así que la interfaz se dibuja cuatro veces por fotograma en una banda de 320×60 (38 KB). Cada pasada dibuja todo desplazado por el desfase de la banda, y las partes que caen fuera de la banda se recortan.

La primera vez que esto se ejecutó en la placa, la pantalla mostró rayas diagonales, y los botones del aviso de aprobación aparecieron dos veces, arriba y abajo. La configuración del panel fue mi primera sospecha. La reescribí a mano a partir de la documentación de M5Stack, y nada cambió. La causa estaba en otro sitio:

Con un solo búfer, la siguiente banda se dibuja en el búfer mientras el DMA todavía lo está enviando. Con dos búferes, uno se dibuja mientras el otro se envía, y la CPU espera a la transferencia antes de reutilizar un búfer

LovyanGFX envía un sprite al panel con DMA, en segundo plano. Mi bucle empezaba a dibujar la siguiente banda en el mismo búfer mientras la anterior todavía se estaba enviando, así que el panel recibía la mitad de una banda y la mitad de la siguiente. La solución usa dos búferes por turnos y espera a la transferencia anterior antes de enviar:

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();

Cuesta un búfer más de 38 KB, de unos 275 KB de RAM libre.

El código, parte por parte

Descarga el código con git clone https://github.com/velxio/m5claude.git, o como ZIP desde el botón Code del repositorio. Tiene dos mitades que no comparten nada salvo el protocolo: bridge/ se ejecuta en el PC, y firmware/ más src/ se ejecutan en el M5Stack.

En el M5Stack

firmware/m5claude/m5claude.ino: todo lo específico de la placa.

src/app/app.cpp: el protocolo, independiente del enlace.

src/model/: los datos.

src/ui/: las pantallas.

En el PC

El puente vive en bridge/m5claude_bridge/. Sus únicas dependencias son pyserial y bleak. Las llamadas HTTPS usan la biblioteca estándar.

__main__.py: la línea de comandos y el bucle principal.

autostart.py registra el puente para que se inicie al iniciar sesión sin ventana: la clave de registro Run con pythonw en Windows, un LaunchAgent en macOS, una unidad de usuario de systemd en Linux.

config.py: las cuentas.

sources/: un archivo por fuente de datos.

pricing.py contiene los precios de lista de la API por familia de modelos. Estima el valor del uso de la suscripción.

snapshot.py: construye la instantánea.

hub.py guarda la instantánea más reciente y se la da a cada dispositivo conectado. Un enlace lento solo recibe la última, nunca un acumulado.

transports/: un archivo por enlace.

El README del repositorio tiene el mismo recorrido en tablas, además de la solución de problemas.

Crea el tuyo

El orden que recomiendo: diseña las pantallas en Velxio, luego flashea la placa y después conecta el puente.

1. Ejecútalo y modifícalo en el M5Stack Core en Velxio

Velxio simula el M5Stack Core con su pantalla de 320×240, los botones A, B y C y el chip de batería. Maquetar una pantalla de 2 pulgadas implica muchos ajustes pequeños (una etiqueta dos píxeles más abajo, un número que no cabe en su tarjeta), y cada uno lleva segundos en el navegador en lugar de un ciclo de flasheo.

El panel está en la galería de ejemplos de Velxio, con los mismos archivos fuente que el repositorio:

  1. Abre M5Stack Core: Claude usage dashboard (m5claude) y haz clic en el botón de reproducir. No hace falta registrarse. Arranca con las cuentas de demostración de este artículo.
  2. Haz clic en A y C para elegir una cuenta y en B para recorrer las vistas. El simulador ejecuta el firmware más lento que la placa, así que para abrir los ajustes, mantén pulsado C unos segundos.
  3. Para ver tus propios números, ejecuta m5claude-bridge snapshot en tu PC y pega la línea que imprime en el monitor serie. El primer comentario del sketch tiene una línea de ejemplo que puedes editar.
  4. Cambia las pantallas en ui.cpp y vuelve a ejecutar. Cuando se vean bien, flashea la placa.

Dos cosas difieren de la placa: Velxio no tiene Bluetooth, así que ese enlace se omite y el monitor serie es el único enlace, y el código del altavoz usa las llamadas del core de ESP32 Arduino más reciente. Cada cambio está marcado en el sketch.

Para empezar un panel propio desde una pantalla vacía, M5Stack Core: Hello LCD + Buttons es el ejemplo más pequeño. Usa M5GFX de M5Stack, que está construido sobre LovyanGFX y comparte su API de dibujo, así que el código se mueve entre los dos.

2. Flashea el firmware

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

Los scripts compilan para el M5Stack Core con un esquema de particiones que deja espacio para una app grande (PartitionScheme=no_ota). El firmware ocupa unos 820 KB. Dos ajustes me pillaron por sorpresa:

3. Ejecuta el puente

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 registra el puente para que se inicie al iniciar sesión, sin ventana. En Windows añade un valor bajo la clave de registro Run del usuario que lanza pythonw. En macOS instala un LaunchAgent, y en Linux un servicio de usuario de systemd. autostart status muestra si está en ejecución y las últimas líneas de su log, en ~/.m5claude/bridge.log. Solo se ejecuta un puente a la vez: un segundo competiría por el puerto USB y la conexión Bluetooth, así que sale con un mensaje. Ejecutar m5claude-bridge por sí solo lo mantiene en primer plano, con el log en la terminal.

Las cuentas Pro y Max se encuentran a partir de los directorios de configuración de Claude Code. Para añadir una segunda suscripción, iníciala bajo su propio directorio:

$env:CLAUDE_CONFIG_DIR = "$HOME\.claude-work"; claude    # then /login

Las organizaciones de API necesitan una clave de Admin API, desde la Claude Console en Settings → Admin keys:

m5claude-bridge add-api "Acme API" --key-env ACME_ADMIN_KEY

4. Conecta

Enchufa el cable USB, o deja el dispositivo en el escritorio y deja que Bluetooth lo encuentre. La primera vez por Bluetooth, pulsa C en el dispositivo para aprobar el PC. Los datos aparecen en unos segundos.

Advertencias

Qué viene después

El código está en github.com/velxio/m5claude. Las issues y pull requests son bienvenidas.

Gracias a M5Stack por una placa que está lista para usar nada más sacarla de la caja, y a los autores de LovyanGFX, NimBLE-Arduino, ArduinoJson y bleak.

Los enlaces a la tienda de M5Stack en esta página son enlaces de afiliado: si compras a través de ellos, Velxio gana una pequeña comisión sin coste adicional para ti, y ayuda a mantener el simulador gratuito.


Compartir en:
David Montero

Escrito por

David Montero

Creator of Velxio, the open-source circuit and Arduino simulator.

GitHub velxio.dev

Artículos relacionados


Artículo anterior
Cute Desktop Robot: una cara que escucha en el ESP-VoCat, con su emulador en tu navegador
Artículo siguiente
Raspberry Pi 4 y 5 en el navegador: modo básico y modo Linux, paso a paso