Monitor serie y depuración en el ESP32: deja de adivinar

Cómo depurar de verdad en el ESP32: monitor serie bien configurado, logs por niveles, brownout, watchdog, backtraces de pánico y cuándo usar JTAG.

También disponible en: EN, ES

Serie Introducción al ESP32 Parte 21 Ver la serie →
Monitor serie y depuración en el ESP32

Cuando algo no funciona, la tentación es cambiar código a ciegas. Eso alarga el problema. Lo que de verdad ahorra tiempo es ver qué está pasando. Y para eso tienes el monitor serie y los logs.

El monitor serie, bien configurado

void setup() {
  Serial.begin(115200);
  Serial.println("Arrancando…");
}

Tres cosas que casi todos olvidan:

  • La velocidad debe coincidir (115200 es el estándar). Si ves ����, no coincide.
  • Tras Serial.begin() da un respiro antes de imprimir; a veces las primeras líneas se pierden.
  • El monitor resetea la placa al abrirse en muchas configuraciones: no te asustes si «arranca solo».

Si no ves nada:

  1. ¿Está el monitor en el puerto correcto?
  2. ¿La placa usa USB nativo (S3/C3) y estás mirando el puerto equivocado?
  3. ¿Cerraste otro programa que tenía el puerto abierto?

Logs por niveles (si usas ESP-IDF)

En lugar de printf a lo loco, usa niveles:

#include "esp_log.h"
static const char *TAG = "app";

ESP_LOGI(TAG, "info");
ESP_LOGW(TAG, "aviso");
ESP_LOGE(TAG, "error");

Puedes subir o bajar el nivel por componente desde menuconfig, y en producción dejar solo errores. Eso no lo da un printf.

Los mensajes que te están contando el problema

Al arrancar, el ESP32 imprime un montón de información útil:

  • rst:0x... → por qué se reinició: power-on, watchdog, pánico, brownout.
  • Brownout detector was triggeredfalta de corriente. Cambia el cable, el puerto USB o añade un condensador.
  • Guru Meditation Error → un panic. Debajo viene un backtrace con las direcciones; con idf.py monitor se traduce solo a nombres de función.
  • Task watchdog got triggered → tu loop() o una tarea se quedó atascada.

Aprender a leer esas cuatro líneas resuelve la mitad de los problemas.

Técnicas que funcionan

  1. Bisección: comenta la mitad del código. El problema está en la otra mitad. Repite.
  2. Serial.println estratégico: marca por dónde pasa, no valores sueltos. Mejor [sensor] leído: %d.
  3. LED de estado: un LED que parpadea rápido = «estoy aquí». Sin monitor.
  4. Multímetro: mide alimentación y niveles antes de culpar al código.
  5. Analizador lógico (barato): imprescindible para I2C/SPI. Ver el bus es otro nivel.
  6. JTAG (S3/C3): puntos de ruptura de verdad cuando el bug es escurridizo.

Errores típicos

  • Cambiar código al azar sin mirar el monitor.
  • Ignorar un brownout pensando que es software.
  • No leer el backtrace (ahí está la línea exacta).
  • Usar delay() en el loop y comerse el watchdog.
  • Depurar a 9600 baudios y esperar que salga todo.

Un loop() que no bloquea (y no dispara el watchdog)

unsigned long last = 0;

void loop() {
  if (millis() - last >= 1000) {
    last = millis();
    // trabajo pesado aquí
  }
  // el resto del tiempo, respira
}

Resumen

  • Configura el monitor a 115200 y comprueba puerto y velocidad.
  • Usa logs con nivel (ESP-IDF) en lugar de printf sueltos.
  • rst:, brownout, backtrace y watchdog te dicen qué pasa; apréndelos.
  • Bisección + LED de estado + multímetro resuelven la mayoría.
  • Para buses (I2C/SPI), un analizador lógico vale su peso en oro.
  • Cuando el bug se esconde, JTAG (S3/C3).

Siguiente paso: con esto cierras la Introducción al ESP32. Ahora puedes seguir con Explorar o volver al hub de la serie.

Entradas relacionadas

↑↓ navegar ↵ abrir Esc cerrar