Ho avuto anch'io la brutta sorpresa di scoprire che debbo pigiare il bottoncino BOOT per caricare uno sketch.
Debbo dire che sono completamente privo di esperienza con l’ESP32; ne ho comperato uno avendo sentito grandi lodi su questo dispositivo, ma già l’acquisto è stato complicato, poiché non riuscivo a districarmi nella selva di produttori di schede di sviluppo. Alla fine ho comperato quello della Hiletgo, e temo che non sia stata la scelta migliore, vista l’assoluta mancanza di documentazione nel sito della Hiletgo. Anche l’installazione su IDE Arduino non è stata semplicissima, perché ho faticato a capire quale tra le innumerevoli schede ESP32 dovevo selezionare. Una volta superato questo scoglio, è comparso il fatidico messaggio:
Serial port COM5
Connecting............................_____...
A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header.
Nella pagina di Github dedicata a espressif/arduino-esp32 è scritto:
Sometimes to program ESP32 via serial you must keep GPIO0 LOW during the programming process.
Anche qui non è immediato capire che per tenere low il GPIO0 bisogna pigiare il famoso bottoncino. Comunque a tentativi e spintoni ci sono arrivato, anche a capire che il bottoncino va pigiato quando compare il messaggio “Connecting….”
Tuttavia, che si debba intervenire manualmente per caricare uno sketch è intollerabile. Ho provato ad immaginare che fosse un problema dell’IDE Arduino, e ho caricato l’ambiente di sviluppo suggerito da Espressif (esp-idf), ma le cose non sono cambiate molto: alcuni sketch caricano, altri no; e lo stesso sketch, alcune volte si, altre volte no. È evidente che c’è una criticità circuitale e/o di configurazione dei tools.
La soluzione segnalata da Steve-cr mi solleva qualche perplessità, perché io, senza dettagliate informazioni sulla circuiteria sottostante, non connetterei mai un condensatore così grosso ad un ingresso logico. Il suo effetto è quello di rallentare i fronti dei segnali e se la capacità è grossa, li potrebbe rallentare oltre il consentito. Spesso le specifiche degli integrati dichiarano il limite massimo per il tempo di transizione dei segnali, perché un segnale lento lascia più a lungo i transistor in zona lineare, dove assorbono più corrente del normale, provocandone l’invecchiamento prematuro (in casi estremi, la morte istantanea). Per questo, non sapendo nulla della circuiteria sottostante, io a priori non fare mai una manovra del genere.
Perciò mi sono messo a studiare le soluzioni circuitali adottate per realizzare la funzione illustrata nel documento citato da steve-cr
Development boards (including all Espressif boards) usually use additional circuitry to avoid this problem - if both RTS and DTR are both asserted together, this doesn't reset the chip. Consult Espressif development board schematics for the specific details.
La circuiteria menzionata sono i due transistors NPN con gli emettitori incrociati verso gli ingressi alle basi, che realizzano in maniera un po’ naif (nell’epoca delle FPGA è più facile integrare un intero processore che due stupidissime porte logiche) due funzioni logiche: En=/DTR+RTS e GPIO0=DTR+/RTS. In questo modo, se DTR e RTS sono asseriti o negati contemporaneamente, En e GPIO0 non fanno nulla (restano alti in pull-up), se invece DTR e RTS sono asseriti alternativamente, En e GPIO0 fanno quello che devono, Il boot o il reset.
Ho guardato gli schemi del modulo della Hiletgo e il DevKitC V4 della Esperssif. In effetti il modulo della Espressif ha due condensatori di debouncing da 100nF in parallelo ai due bottoncini e altri 100nF vicini al pin EN, che il modulo della Hitletgo non ha (e ci sono altre piccole differenze su valori delle resistenze di pull-up).
Siamo nella situazione descritta dalla succitata pagina:
(Some third party ESP32 development boards use an automatic reset circuit for EN & GPIO pins, but don't add a capacitor on the EN pin. This results in unreliable automatic reset, especially on Windows. Adding a 100nF (or higher) value capacitor between EN pin and GND may make automatic reset more reliable..)
Quindi la soluzione va nella direzione indicata da Steve-cr (ma con un valore del condensatore ben più ragionevole).
Tutto induce quindi pensare che ci sia un problema nel timing dei segnali.
Infatti gli sviluppatori di esptool.py dicono:
Entering the Bootloader
Both ESP8266 and ESP32 have to be reset in a certain way in order to launch the serial bootloader.
On some development boards (including NodeMCU, WeMOS, HUZZAH Feather, Core Board, ESP32-WROVER-KIT), esptool.py can automatically trigger a reset into the serial bootloader - in which case you don't need to read this section.
For everyone else, three things must happen to enter the serial bootloader - a reset, required pins set correctly, and GPIO0 pulled low
La scheda Hiletgo è una NodeMCU, quindi non dovrei preoccuparmi, ma evidentemente non è così. La mia impressione è che tanti disegnatori di schede di sviluppo per l’ESP32 si siano gettate sull’affare, copiandosi più o meno l’un dall’altro, senza approfondire certi dettagli circuitali.
Quindi è un problema di timing dei segnali, che il condensatore sul segnale EN tende a risolvere, o mitigare.
Ma poi in quest’altra pagina si scopre che, per lo stesso modulo, il problema affligge chi usa Windows ma non chi usa Linux, e si scopre che la causa sta nel driver USB to UART della Silicon Labs per il chip CP2104, implementato in Windows, che introduce un piccolo ritardo sul segnale GPIO0, per cui bisogna ritardare artificialmente il segnale EN. L’equivalente driver per Linux non ha questi problemi, e gli sviluppatori di esptool.py non hanno workaround. Non resta che il condensatore su EN.
Va detto che il problema è stato segnalato alla Slicon Labs (vedi qui), ma per ora non hanno reagito positivamente.
Debbo anche dire che ho fatto qualche prova e per la mia scheda il problema si è risolto con soli 10nF.
Ps.: Mi scuso del lungo post, ma ho dedicato molto tempo a capire questo problema, e il post è il risultato delle mie annotazioni, sperando che siano utili a qualcuno