El ESP32 no sube el programa: causas y cómo destrabarlo
Por qué el computador no ve la placa, qué significa «Timed out waiting for packet header» y cómo forzar el modo de programación a mano.
Revisada el
Casi nunca es la placa. Los cinco síntomas de abajo se arreglan sin soldar nada y sin comprar nada: un cable, un driver, dos botones apretados en el orden correcto, o una fuente que no da la corriente que el chip pide.
Esta guía está armada al revés de un tutorial: busca tu síntoma en la tabla, ándate a esa sección y no leas el resto. Los mensajes de error van copiados tal como salen de la consola —con la puntuación y todo— para que los puedas comparar letra por letra con el tuyo.
| Lo que ves | La causa más probable |
|---|---|
| No aparece ningún puerto | El cable es de sólo carga, o falta el driver del conversor USB-serie. En el ESP32-C3, que tiene USB nativo, casi siempre es el cable o un programa que apagó el puerto. |
| Timed out waiting for packet header | La placa nunca entró en modo de programación: arrancó el programa que ya tenía. |
| Brownout detector was triggered | Se cae la alimentación. Cable largo, puerto flojo, o un periférico pidiendo más corriente de la que hay. |
| El monitor serie muestra basura | Los baudios del monitor no son los del programa. A veces es un reinicio en bucle disfrazado. |
| La placa se reinicia sola | Hay algo colgando de un pin de strapping, o es otra vez la alimentación. |
No aparece ningún puerto en el IDE
Parte por el cable, porque es la causa más común y la más barata de descartar: muchos cables USB traen sólo los dos hilos de alimentación y ningún par de datos. Cargan un teléfono perfecto y no sirven para programar nada, y por fuera se ven iguales. Prueba con el de un disco externo, que ese sí lleva datos.
Si el cable lleva datos, lo que sigue depende de qué placa tengas, y acá hay una diferencia que confunde a mucha gente.
Las placas ESP32 clásicas —las alargadas de treinta y tantos pines— suelen llevar un chip aparte que traduce USB a serie: un CH340 o un CP2102. Ese chip es el que tu computador tiene que reconocer, y para eso necesita el driver del fabricante. Sin driver no aparece ningún puerto por más que la placa esté enchufada y con corriente.
La SuperMini no lleva ese chip. Habla USB directo desde el mismo silicio, por un periférico que Espressif llama USB Serial/JTAG: el D+ sale por GPIO19 y el D− por GPIO18. Por eso no necesita driver — el sistema la ve como un puerto serie USB estándar y aparece sola.
Ojo con la conclusión fácil, porque acá es donde alguien se va sin arreglar su problema: que el chip sepa hablar USB no significa que toda placa con un C3 lo aproveche. La ESP32-C3-DevKitM-1, de la propia Espressif, trae un puerto micro-USB con un conversor USB-serie detrás, y esa sí pide driver.
¿Y cómo sabes cuál de las dos tienes? Si no te aparece ningún puerto, la respuesta corta es que da lo mismo: instala el driver del CH340 y el del CP2102, y vuelve a mirar. En una placa de USB nativo no estorban, y en una con conversor es exactamente el paso que te faltaba. Lo que no sirve para decidirlo es mirarle los chips a la placa: en placas de este tipo suele haber más de un integrado chico además del módulo, y ninguno viene rotulado para que lo adivine alguien que recién parte.
Cuando el puerto ya aparezca, el nombre sí te dice cuál es. En Linux es limpio, y lo documenta Espressif: el USB nativo sale como /dev/ttyACM… y un conversor sale como /dev/ttyUSB…. En Windows los dos salen como COM y el nombre no distingue nada. En macOS los dos empiezan con /dev/cu., y ahí Espressif no se compromete con más que eso para el USB nativo los ejemplos de conversores que publica sí traen la marca en el nombre —cu.usbserial-… o cu.SLAB_USBtoUART—, pero eso es indicio nuestro y no una regla suya.
Que no necesite driver tiene una contra, y es la que trae a mucha gente hasta acá: el puerto lo hace el chip, así que el programa que corre adentro lo puede apagar. Si lo último que subiste reconfigura GPIO18 o GPIO19, desactiva el periférico USB o se manda a dormir profundo, el puerto desaparece del sistema. La documentación de esptool lo dice con esas palabras: si la aplicación reconfigura los pines del USB o desactiva el periférico, el dispositivo desaparece.
No es que la placa se haya roto. Es que el puerto lo hacía el programa que acabas de reemplazar por uno que lo apaga.
Failed to connect to ESP32: Timed out waiting for packet header
El mensaje completo, tal como sale:
A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header
Dos variantes de lo mismo. Si le declaraste al IDE una placa C3, en el medio dirá «Failed to connect to ESP32-C3». Y si tienes esptool 4 o más nuevo —que es lo que traen las versiones recientes del soporte de ESP32 para Arduino—, la misma falla se escribe «Failed to connect to ESP32-C3: No serial data received.». Es el mismo problema con otra redacción.
Qué está diciendo: esptool reseteó la placa, mandó el saludo de sincronización y no le contestó nadie. El puerto existe, la placa está encendida, pero lo que hay al otro lado no es el bootloader esperando un programa — es tu programa anterior corriendo tranquilo.
Por qué pasa: para poder recibir un programa nuevo, el chip tiene que arrancar en modo de descarga en vez de arrancar lo que ya tiene en la flash. Eso se decide en el instante del reset, mirando el nivel de unos pines llamados de strapping, y después ya no se puede cambiar: el chip los lee una vez, se los guarda en un latch y los libera para que los uses como pines normales.
En el ESP32-C3 los pines de strapping son GPIO2, GPIO8 y GPIO9, y la tabla de arranque de la hoja de datos es corta:
• GPIO9 en alto durante el reset — arranca el programa de la flash. Es lo normal, y es adonde llega solo: GPIO9 trae un pull-up interno débil.
• GPIO9 en bajo durante el reset, con GPIO8 en alto — arranca el bootloader serie, el que espera el programa.
• GPIO8 en bajo y GPIO9 en bajo a la vez — combinación inválida, según la documentación de esptool, y provoca comportamiento inesperado.
• GPIO2 no decide entre uno y otro, pero la hoja de datos recomienda dejarlo en alto por los glitches del encendido. Queda flotando si no le conectas nada.
Normalmente nada de esto te importa, porque la placa lo hace sola: el IDE le pide al puerto serie que mueva las líneas DTR y RTS, que en la placa están cableadas a GPIO9 y a EN, y esa coreografía deja el chip en modo de descarga sin que toques un botón. Cuando falla —un cable raro, un driver que no mueve las líneas, un condensador que la placa genérica no trae— hay que hacerlo a mano.
A mano, si tu placa trae los dos botones:
1. Mantén apretado BOOT, que es el que va a GPIO9.
2. Sin soltarlo, aprieta y suelta RESET.
3. Recién ahí suelta BOOT.
4. Dale subir en el IDE.
Lo que importa de esa secuencia es una sola cosa: que GPIO9 esté en tierra en el momento exacto en que el chip sale del reset. Si tu placa no trae botón de BOOT, un puente de GPIO9 a GND mientras la reseteas hace exactamente lo mismo, y si no trae ninguno de los dos, desenchufa y enchufa el USB con el puente puesto.
Si igual falla, prueba dejando BOOT apretado desde antes: apriétalo, dale subir, y suéltalo recién cuando la consola diga «Connecting...». Es lo que recomienda la documentación de esptool para cuando el reset funciona pero el chip no queda en el modo.
Brownout detector was triggered
El mensaje sale así, muchas veces cortado por la mitad:
Brownout detector was triggered
No es un error de tu código. Es el chip avisando que el voltaje de alimentación se le fue abajo de un umbral y que por eso se va a resetear, antes de hacer algo impredecible con la memoria a medio escribir. ESP-IDF trae el detector encendido por defecto y en su nivel más bajo, unos 2,51 V sobre el riel de 3,3 V imprime la línea y reinicia.
Que salga cortado no es culpa de tu monitor: la documentación de Espressif advierte que si el voltaje se cae rápido, alcanza a salir sólo parte del mensaje. Si ves «Brownout detect» y nada más, es esto igual.
Qué revisar, en orden de qué es más probable:
• La radio. El WiFi es el que pide los picos: la hoja de datos del C3 declara hasta 335 mA de consumo transmitiendo en 802.11b a 21 dBm, contra 84 mA recibiendo. Si el reinicio ocurre siempre en el mismo punto del programa —justo al conectarse a la red—, es esto y no otra cosa.
• El cable. Uno largo o flaco cae voltaje de verdad, y se nota. Prueba con uno corto antes de sospechar de nada más.
• El puerto. Los de un hub sin alimentación propia, los de un teclado y los del frente de algunos gabinetes no dan lo que dicen. Enchúfala directo a un puerto de atrás del computador.
• Lo que le colgaste. Un motor, un servo o una tira de LED alimentados desde la placa. Esa corriente sale del mismo puerto USB y viaja por el mismo cable que alimenta al chip: cuando el motor tira, el riel entero se hunde y el chip lo lee como brownout. Esas cargas van con su propia fuente, y con la placa sólo comparten la tierra.
El detector se puede subir de umbral o apagar por configuración. Apagarlo no arregla nada: cambia un reinicio con mensaje por un cuelgue sin mensaje.
El monitor serie muestra basura
Caracteres raros, rombos con signo de pregunta, líneas cortadas a la mitad. Casi siempre son los baudios: el monitor y el programa tienen que estar en el mismo número, y si no lo están el monitor lee los bits en el momento equivocado. La pista de que es esto y no un cable malo es que la basura sea estable —los mismos símbolos raros cada vez— y no ruido distinto en cada arranque.
Pon el monitor en el número que dice el Serial.begin() de tu programa. Si dice Serial.begin(115200), el monitor va en 115200.
Hay un caso que confunde, y es el arranque. La ROM del ESP32-C3 imprime su log a 115200 por defecto, y esa velocidad no la cambia tu Serial.begin(): son dos emisores distintos por el mismo cable. Así que si tu programa corre a otra velocidad vas a ver siempre una de las dos partes ilegible, las primeras líneas o el resto. No está fallando nada, y 115200 es el número que deja legibles las dos.
Si estás conectado por el USB nativo del C3 y aun así ves basura, cambiar el número rara vez lo arregla: ahí no hay conversor USB-serie en el medio, el USB Serial/JTAG es un dispositivo USB de función fija hecho en hardware y el dato viaja en paquetes.
Mira entonces si lo que aparece es un reinicio en bucle disfrazado de basura: un «Guru Meditation Error», una línea que empieza con «rst:0x» y se repite cada un segundo, o el mensaje de brownout de más arriba. Eso no se arregla en el monitor, se arregla en la sección que corresponda.
La placa se reinicia sola, o arranca en un modo raro
Son dos causas distintas y se distinguen leyendo el log.
Si el reinicio viene acompañado de «Brownout detector was triggered», es alimentación: ándate a esa sección.
Si no aparece ese mensaje, pero la placa arranca en un modo que no es el tuyo o simplemente no corre el programa, mira qué tienes conectado a los pines de strapping. En el ESP32-C3 son GPIO2, GPIO8 y GPIO9, y no son pines especiales todo el tiempo: el chip los lee en el instante del reset y después quedan libres como cualquier otro. El problema es ese instante.
Un pulsador, un sensor con la salida en bajo al partir, la resistencia de pull-down que trae un módulo: cualquier cosa que deje GPIO9 en bajo mientras el chip resetea lo manda al bootloader en vez de a tu programa, y desde afuera eso se ve como «no arranca». Y GPIO8 en bajo junto con GPIO9 en bajo es la combinación que la documentación de esptool declara inválida.
Cómo se descarta en un minuto: desconecta todo lo que tengas en GPIO2, GPIO8 y GPIO9 y resetea. Si con la placa pelada arranca bien, ya sabes que era uno de los tres.
Cómo se arregla sin renunciar al pin: lo barato es mover esa señal a otro GPIO, y casi siempre alcanza. Si de verdad necesitas ese pin, tiene que estar en el nivel correcto durante el reset y recién después servir para lo tuyo. GPIO9 llega solo a alto por su pull-up interno GPIO2 y GPIO8 quedan flotando, y por eso la hoja de datos recomienda dejar GPIO2 en alto. Cómo hacerlo ya no lo dice: como el pin no trae pull-up propio, deducimos nosotros que es con una resistencia externa. La ventana es corta: el chip deja de mirarlos unos 3 ms después de que se suelta el reset.
Si probaste todo esto y sigue sin subir, escríbenos por WhatsApp con dos cosas: el mensaje de error completo, copiado y pegado tal cual, y una foto de la placa con todo lo que tengas conectado. Con eso casi siempre se ve.