Corso ESP-IDF, puntata 1: ESP-IDF in una mappa
Io: Cheap, si parte con un corso nuovo: ESP-IDF, quaranta puntate.
Cheap: Quaranta? Spero che almeno il framework sia gratis.
Io: Gratis e open source, licenza Apache-2.0. Lo scrive Espressif, la stessa che fa i chip.
Cheap: Allora mi piace già. E l’hardware? Non dirmi oscilloscopi da mille euro.
Io: Una ESP32-C6-DevKitC-1 e un cavo USB-C. Per oggi basta quella: il chip ci racconterà chi è e quanto è caldo.
Cheap: Un termometro che misura sé stesso. Finalmente un sensore che non devo comprare.
Io: Prima però facciamo la mappa: che cosa c’è dentro ESP-IDF, quali chip supporta, quale versione usiamo e perché.
Cheap: Una mappa prima del viaggio. Pignolo come piace a me.
In questa puntata
Obiettivi
- Capire che cos’è ESP-IDF: il framework ufficiale di Espressif, basato su FreeRTOS e diviso in componenti, che si guida con il comando
idf.py. - Conoscere le famiglie di chip supportate da ESP-IDF v6.1 e le loro differenze principali (core e radio).
- Capire come funzionano versioni e periodi di supporto, e perché il corso usa la v6.1.
- Collocare ESP-IDF rispetto ad Arduino-ESP32.
- Conoscere la scheda del corso, la ESP32-C6-DevKitC-1, e il metodo di lavoro: teoria, esercizi, verifica.
Prerequisiti: conoscere il linguaggio C (puntatori, struct, switch, printf). Per compilare gli esercizi serve l’ambiente installato: lo vediamo passo per passo nella Puntata 2 (pubblicazione in arrivo). Chi ha già ESP-IDF v6.1 può provarli subito.
Che cos’è ESP-IDF
ESP-IDF sta per Espressif IoT Development Framework: è il framework di sviluppo ufficiale di Espressif per i suoi SoC (System on Chip, cioè chip che contengono processore, memorie, periferiche e spesso radio). Gira su Windows, Linux e macOS ed è distribuito con licenza Apache-2.0: si può usare anche in prodotti commerciali, senza costi e senza obbligo di pubblicare il proprio codice.
Dentro ESP-IDF trovi tre cose:
- Il codice che gira sul chip: sistema operativo, driver, stack di rete e Bluetooth, file system, sicurezza, aggiornamenti via rete. È organizzato in componenti.
-
Gli strumenti sul PC: il sistema di build basato su CMake e Ninja, il configuratore
menuconfig,esptoolper scrivere la flash, il monitor seriale. Tutti si comandano da un unico programma,idf.py. -
Documentazione ed esempi: cartelle
docs/edexamples/.
FreeRTOS sotto il cofano
Ogni applicazione ESP-IDF gira sopra FreeRTOS, un RTOS (Real-Time Operating System, sistema operativo in tempo reale) open source. La documentazione della v6.1 lo descrive così: ESP-IDF FreeRTOS è basato su FreeRTOS v10.5.1 “vanilla”, con modifiche importanti per gestire i chip a due core in modalità SMP (Symmetric Multiprocessing). Non devi avviarlo tu: quando il tuo codice parte, lo scheduler è già in funzione e app_main() gira dentro un task.
I componenti: mattoncini con un nome
Nella v6.1 la cartella components/ contiene 146 componenti. Ognuno è una cartella con il suo codice, i suoi header e il suo CMakeLists.txt. I nomi sono parlanti: esp_wifi, nvs_flash, esp_http_server, esp_driver_uart. Anche la tua applicazione è un insieme di componenti: il più importante si chiama main.
I componenti sono disposti a strati. In alto ci sono i servizi (protocolli di rete, memorizzazione, radio); al centro FreeRTOS e i servizi di sistema (log, heap, timer ad alta risoluzione); sotto i driver delle periferiche. Ancora più in basso c’è l’astrazione dell’hardware: la guida Hardware Abstraction la divide in strato LL (Low Level, funzioni minime che leggono e scrivono i registri) e strato HAL (Hardware Abstraction Layer), con un componente esp_hal_xxx per ogni modulo hardware. Ogni strato usa solo quello sotto di sé: il driver usa la HAL, la HAL usa il LL, il LL usa le definizioni dei registri del componente soc.

components/ nella v6.1; a destra gli strumenti sul PC e il registro dei componenti esterni.Non tutto sta dentro ESP-IDF. Molti componenti vivono nel registro dei componenti di Espressif e si aggiungono al progetto con il Component Manager: basta dichiararli in un file idf_component.yml e la build li scarica da sola. Per esempio l’esempio blink della v6.1 usa espressif/led_strip per pilotare il LED RGB. Ne parleremo nella Puntata 38 (pubblicazione in arrivo).
idf.py: un comando per tutto
Il lavoro di tutti i giorni si fa con pochi sottocomandi di idf.py, sempre gli stessi:
idf.py set-target esp32c6 # sceglie il chip per cui compilare
idf.py menuconfig # apre il menu delle opzioni (Kconfig)
idf.py build # compila applicazione, bootloader e tabella delle partizioni
idf.py -p COM5 flash # scrive la flash (COM5 è un esempio: usa la tua porta)
idf.py -p COM5 monitor # apre il monitor seriale (si esce con Ctrl+])
idf.py --version # stampa la versione di ESP-IDF
Il target si fissa una volta per progetto: da lì in poi la build sa quali componenti e quali opzioni valgono per quel chip. Tutto il resto, dall’installazione al primo flash, è il tema della Puntata 2 (pubblicazione in arrivo).
I chip supportati dalla v6.1
L’elenco ufficiale sta nel codice stesso di idf.py (file tools/idf_py_actions/constants.py). La v6.1 supporta in modo stabile dieci famiglie di chip. La tabella riassume core e radio come li descrive la guida Get Started della v6.1, controllati con i file soc_caps.h di ogni chip:
| Chip | Target | CPU | Radio |
|---|---|---|---|
| ESP32 | esp32 |
2 core Xtensa LX6 | Wi-Fi 2,4 GHz, Bluetooth (Classic e LE) |
| ESP32-S2 | esp32s2 |
1 core Xtensa LX7 | Wi-Fi 2,4 GHz |
| ESP32-S3 | esp32s3 |
2 core Xtensa LX7 | Wi-Fi 2,4 GHz, Bluetooth LE |
| ESP32-C2 | esp32c2 |
1 core RISC-V | Wi-Fi 2,4 GHz, Bluetooth LE |
| ESP32-C3 | esp32c3 |
1 core RISC-V | Wi-Fi 2,4 GHz, Bluetooth LE |
| ESP32-C5 | esp32c5 |
1 core RISC-V | Wi-Fi 6 a 2,4 e 5 GHz, Bluetooth LE, 802.15.4 |
| ESP32-C6 | esp32c6 |
1 core RISC-V (più un core LP) | Wi-Fi 6 a 2,4 GHz, Bluetooth LE, 802.15.4 |
| ESP32-C61 | esp32c61 |
1 core RISC-V | Wi-Fi 6 a 2,4 GHz, Bluetooth LE |
| ESP32-H2 | esp32h2 |
1 core RISC-V | Bluetooth LE, 802.15.4 |
| ESP32-P4 | esp32p4 |
2 core RISC-V | nessuna |
L’802.15.4 è lo standard radio a basso consumo su cui si appoggiano Thread e Zigbee: lo useremo nella Puntata 33 (pubblicazione in arrivo). Accanto ai chip stabili, la v6.1 elenca alcuni target in anteprima (preview): esp32h21, esp32h4, esp32s31 e linux, che compila l’applicazione come programma per il PC ed è utile per i test (Puntata 37, pubblicazione in arrivo). I vecchi ESP8266 ed ESP8285 non sono supportati: per loro esiste l’ESP8266 RTOS SDK.
Ogni chip esce poi in più revisioni del silicio, numerate vX.Y. Il file COMPATIBILITY.md nella radice di ESP-IDF dice da quale versione di ESP-IDF è supportata ogni revisione: per l’ESP32-C6, le revisioni v0.0 e v0.1 sono supportate dalla v5.1, la v0.2 è richiesta e consigliata dalla v5.4 in su. Con la v6.1 siamo tranquilli.
Versioni e periodo di supporto
ESP-IDF segue il versionamento semantico, descritto nella pagina ESP-IDF Versions della documentazione:
- Versione maggiore (per esempio da v5.x a v6.0): aggiunge funzioni e può cambiarne o toglierne. Il codice può richiedere modifiche; le note di rilascio elencano i breaking changes.
- Versione minore (da v6.0 a v6.1): aggiunge funzioni e corregge errori, senza rompere le API documentate. Basta ricompilare e ritestare.
- Bugfix (da v6.1 a v6.1.1): solo correzioni.
Ogni versione maggiore o minore è supportata per 30 mesi dal primo rilascio stabile, divisi in due periodi:
| Periodo | Durata | Consigliato per progetti nuovi? |
|---|---|---|
| Service | 12 mesi | sì: bugfix frequenti |
| Maintenance | 18 mesi | no: solo correzioni gravi e di sicurezza |
Finito il periodo, la versione è a fine vita (EOL, End of Life) e non riceve più correzioni. Le versioni di prova (beta, -rc, -dev) non hanno nessun periodo di supporto.
Perché la v6.1. È l’ultima versione stabile quando parte il corso: il tag v6.1 porta la versione 6.1.0 ed è di fine agosto 2026. Quindi è “in Service”, come la documentazione raccomanda per i progetti nuovi. In più è una 6.x: i driver legacy non ci sono più e impariamo solo le API attuali, senza dover disimparare nulla. La versione la puoi leggere da programma con esp_get_idf_version(), che restituisce la stringa IDF_VER scritta nel firmware: lo fa l’esercizio 01.1.
ESP-IDF e Arduino-ESP32
Molti incontrano gli ESP32 con Arduino. Il “core” Arduino per ESP32 (Arduino-ESP32), mantenuto da Espressif, è costruito sopra ESP-IDF: sotto setup() e loop() ci sono FreeRTOS, i driver e gli stack di rete di ESP-IDF. Non sono quindi due mondi rivali, ma due livelli dello stesso edificio.
Arduino-ESP32 è ottimo per partire in fretta e per sfruttare la sua enorme raccolta di librerie. ESP-IDF dà accesso diretto a tutto il resto: la configurazione completa con menuconfig, la tabella delle partizioni, la gestione dei consumi, la sicurezza (Secure Boot, flash cifrata), gli aggiornamenti OTA, i test, e il supporto ai chip nuovi appena escono. In questo corso scriviamo C con le API di ESP-IDF: quello che impari vale anche quando torni su Arduino, perché lì sotto gira la stessa cosa.
La scheda del corso: ESP32-C6-DevKitC-1
Usiamo la ESP32-C6-DevKitC-1, la scheda di sviluppo ufficiale di Espressif per l’ESP32-C6. Secondo la guida utente (versione v1.2 della scheda), monta il modulo ESP32-C6-WROOM-1 con 8 MB di flash SPI e antenna su circuito stampato (esiste anche la variante WROOM-1U con connettore per antenna esterna).

Le parti da conoscere subito:
- Il chip ESP32-C6: un core RISC-V “HP” (High Power) che ESP-IDF fa girare per default a 160 MHz, più un core “LP” (Low Power) RISC-V che resta acceso quando il resto dorme. Radio Wi-Fi 6, Bluetooth LE e 802.15.4. Ha anche un sensore di temperatura interno, che leggeremo oggi.
- Due porte USB-C. Quella che la guida utente chiama USB Type-C to UART Port passa da un ponte USB-UART fino a 3 Mbps e arriva alla UART0 del chip (GPIO16 TX, GPIO17 RX). L’altra, la ESP32-C6 USB Type-C Port, va direttamente all’USB Serial/JTAG interno al chip (GPIO12 e GPIO13): offre una porta seriale virtuale e il debug JTAG senza sonde esterne (Puntata 6, pubblicazione in arrivo).
- LED RGB indirizzabile su GPIO8, pilotato con un solo filo di dati (Puntata 14, pubblicazione in arrivo).
- Pulsanti BOOT e RESET: tenendo premuto BOOT e premendo RESET si entra nella modalità di download del firmware. BOOT è collegato a GPIO9 e diventa un normale ingresso quando il programma gira (Puntata 13, pubblicazione in arrivo).
- Ponticello J5: togliendolo si può misurare la corrente assorbita dal modulo, utile per il risparmio energetico (Puntata 24, pubblicazione in arrivo).
- Connettori J1 e J3, 16 piedini ciascuno, con tutti i GPIO disponibili tranne quelli della flash.
Quale porta USB usare per vedere i messaggi? Con la configurazione predefinita della v6.1 la console principale è la UART0 e c’è una console secondaria sull’USB Serial/JTAG (opzioni ESP_CONSOLE_UART_DEFAULT e ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG del componente esp_stdio): i printf escono su entrambe. Per gli esercizi di oggi va bene l’una o l’altra.
Un dettaglio che vedrai nell’esercizio 01.2: la scheda ha 8 MB di flash, ma l’opzione ESPTOOLPY_FLASHSIZE di ESP-IDF vale per default 2 MB. Il valore configurato finisce nell’intestazione dell’immagine e il driver usa quello; all’avvio il log avvisa se la flash rilevata è più grande. Impareremo a sistemarlo con menuconfig nella Puntata 3 (pubblicazione in arrivo).
Un primo assaggio di API
Le API di ESP-IDF hanno nomi con prefisso (esp_, temperature_sensor_) e quasi sempre restituiscono un esp_err_t. Per sapere chi è il chip basta una chiamata che riempie una struct:
esp_chip_info_t info;
esp_chip_info(&info);
La struct esp_chip_info_t ha quattro campi: model (il modello, per esempio CHIP_ESP32C6), features (una maschera di bit CHIP_FEATURE_*), revision (nel formato major * 100 + minor) e cores. Nel C6 le funzionalità sono fisse per famiglia: Wi-Fi 2,4 GHz, Bluetooth LE e 802.15.4. La maschera non distingue il Wi-Fi 6 dal Wi-Fi 4.
I driver seguono quasi sempre lo stesso schema: configurazione, installazione che restituisce un handle, abilitazione, uso:
temperature_sensor_handle_t sensore = NULL;
temperature_sensor_config_t cfg = TEMPERATURE_SENSOR_CONFIG_DEFAULT(-10, 80);
ESP_ERROR_CHECK(temperature_sensor_install(&cfg, &sensore));
ESP_ERROR_CHECK(temperature_sensor_enable(sensore));
ESP_ERROR_CHECK ferma il programma con un messaggio chiaro se la funzione non restituisce ESP_OK: la vedremo per bene nella Puntata 5 (pubblicazione in arrivo). L’intervallo da -10 a 80 °C non è casuale: il driver del C6 ha cinque scale di misura e sceglie quella con l’errore minore che contiene l’intervallo chiesto. Per -10~80 °C l’esempio ufficiale temp_sensor mostra nel log un errore inferiore a 1 °C. Ricorda però che, come avverte la documentazione, il sensore misura la temperatura del silicio, non quella dell’ambiente.
Come usare il corso
Ogni puntata ha la stessa struttura:
- Teoria, con figure e frammenti di codice presi da progetti che compilano.
-
Tre esercizi: ★ base, ★★ intermedio, ★★★ sfida. Ognuno ha una traccia, il risultato atteso sul monitor seriale e qualche suggerimento. Per ogni esercizio esistono due progetti ESP-IDF:
traccia, che compila già ma ha i punti da completare marcati// TODO(esercizio), esoluzione, completo. - Verifica: cinque domande per controllare di aver capito.
- Riepilogo e link alla documentazione v6.1.
Le soluzioni non sono negli articoli: stanno nello ZIP degli esercizi, insieme alle tracce. A fine corso tutte le puntate saranno raccolte in un ebook in PDF, con le risposte della verifica in appendice. Ebook e ZIP non si scaricano dal sito: si chiedono scrivendo all’autore, e Igor li manda a chi li richiede. Tracce e soluzioni compilano con ESP-IDF v6.1 per esp32c6 senza errori né warning; il comportamento sulla scheda lo verifichi tu al banco.
Il corso è diviso in cinque moduli:
| Modulo | Puntate | Contenuti |
|---|---|---|
| 1. Fondamenti | 1-6 | ambiente, struttura di un progetto, avvio del chip, log ed errori, debug con il JTAG integrato |
| 2. FreeRTOS in ESP-IDF | 7-12 | task, code, semafori e mutex, notifiche, tempo, memoria |
| 3. Periferiche | 13-24 | GPIO, PWM e LED, UART, I2C, SPI, ADC, timer, RMT, I2S, USB, memorizzazione, risparmio energetico |
| 4. Connettività | 25-34 | Wi-Fi, socket, HTTP e HTTPS, web server, MQTT, Bluetooth LE, Thread e Matter, ESP-NOW |
| 5. Dal prototipo al prodotto | 35-40 | OTA, sicurezza, test, componenti riusabili, prestazioni, progetto finale |
Il corso spiega il framework; le schede pratiche della serie ESP32-C6/P4 del sito sono progetti applicativi completi e le citeremo come approfondimento (pubblicazione in arrivo), senza ripeterle.
Esercizi
★ Esercizio 01.1 — Ciao, chip
Scrivi un programma che, all’avvio, chiede al chip chi è e lo stampa sul monitor seriale: modello in forma leggibile (per esempio “ESP32-C6”), revisione nel formato vX.Y, numero di core, elenco delle funzionalità presenti (Wi-Fi, Bluetooth Classic, Bluetooth LE, 802.15.4, flash o PSRAM integrate nel chip) e versione di ESP-IDF con il target di compilazione. Usa esp_chip_info() ed esp_get_idf_version(). Serve solo la DevKit.
Risultato atteso
=== Ciao, chip ===
Modello: ESP32-C6
Revisione: v0.1
Core: 1
Funzionalita':
- Wi-Fi 2,4 GHz
- Bluetooth LE
- IEEE 802.15.4 (Thread, Zigbee)
ESP-IDF: v6.1 (target esp32c6)
La revisione dipende dal lotto della tua scheda (per il C6 può essere v0.0, v0.1 o v0.2). Se la copia locale di ESP-IDF ha modifiche, la versione può comparire come v6.1-dirty.
Suggerimenti
- I modelli sono i valori dell’enum
esp_chip_model_tinesp_chip_info.h: unswitchcon un ramodefaultbasta. - La revisione è
major * 100 + minor: divisione intera e resto per 100. - Per ogni funzionalità controlla un bit:
if (info.features & CHIP_FEATURE_BLE). - Il nome del target è la macro
CONFIG_IDF_TARGET, definita insdkconfig.h.
★★ Esercizio 01.2 — Carta d’identità
Stampa la “carta d’identità” della scheda: dimensione della flash sia come scritta nell’intestazione dell’immagine (esp_flash_get_size()) sia come letta dal chip di memoria (esp_flash_get_physical_size()), MAC di base (esp_read_mac() con ESP_MAC_BASE), motivo dell’ultimo reset (esp_reset_reason()) tradotto in italiano, heap libero e heap minimo dall’avvio. Se l’ultimo reset non è stato un riavvio software, dopo 5 secondi il programma chiama esp_restart(): al giro successivo il motivo deve cambiare. Controlla ogni esp_err_t con ESP_ERROR_CHECK. Serve solo la DevKit.
Risultato atteso
=== Carta d'identita' ===
Flash (intestazione immagine): 2 MB
Flash (chip fisico): 8 MB
MAC di base: xx:xx:xx:xx:xx:xx
Ultimo reset: accensione (1)
Heap libero: nnnnnn byte
Heap minimo dall'avvio: nnnnnn byte
Riavvio software tra 5 s...
(...messaggi di avvio...)
=== Carta d'identita' ===
(...)
Ultimo reset: riavvio software (esp_restart) (3)
(...)
Fine: per ricominciare premi il pulsante RESET.
MAC e valori dell’heap cambiano da scheda a scheda e da configurazione a configurazione. Il primo motivo di reset dipende da come hai avviato il programma (accensione, pulsante RESET, reset dopo il flash): annota quello che leggi e confrontalo con l’elenco di esp_reset_reason_t.
Suggerimenti
- Gli header sono
esp_flash.h(componentespi_flash, da aggiungere aPRIV_REQUIRES),esp_mac.hedesp_system.h. - Passando
NULLcome primo argomento, le funzioniesp_flash_*usano la flash principale. - Le macro
MACSTReMAC2STR()diesp_mac.hformattano il MAC senza fatica. - Per stampare un
uint32_tin modo portabile usaPRIu32di<inttypes.h>.
★★★ Esercizio 01.3 — Battito
Crea un “battito” che ogni secondo stampa il tempo trascorso dall’avvio, letto con esp_timer_get_time() e mostrato in secondi con tre decimali, e la temperatura interna del chip letta con il driver temperature_sensor (componente esp_driver_tsens). Accanto alla lettura stampa la media mobile delle ultime 8 letture, calcolata con un buffer circolare senza ricalcolare la somma a ogni giro. Il ritmo deve restare di un secondo esatto anche se la stampa richiede tempo. Serve solo la DevKit.
Risultato atteso
I (...) temperature_sensor: Range [-10°C ~ 80°C], error < 1°C
t = 0.xxx s T = xx.x C media(1) = xx.x C
t = 1.xxx s T = xx.x C media(2) = xx.x C
t = 2.xxx s T = xx.x C media(3) = xx.x C
...
t = 9.xxx s T = xx.x C media(8) = xx.x C
Le temperature dipendono dal chip e dall’ambiente; i millisecondi devono restare praticamente uguali da una riga all’altra. Il numero tra parentesi cresce fino a 8 e poi resta fermo.
Suggerimenti
- Lo schema del driver è:
TEMPERATURE_SENSOR_CONFIG_DEFAULT(),temperature_sensor_install(),temperature_sensor_enable(), poitemperature_sensor_get_celsius()a ogni giro. -
esp_timer_get_time()restituisce unint64_tin microsecondi: stampalo conPRId64. - Per il buffer circolare tieni la somma corrente: togli il valore più vecchio, aggiungi il nuovo, dividi per il numero di valori validi.
- Per un periodo regolare usa
xTaskDelayUntil()con il tick di partenza preso daxTaskGetTickCount(), invece divTaskDelay(). - Nel
CMakeLists.txtdimainservonoesp_timeredesp_driver_tsensinPRIV_REQUIRES.
Le soluzioni complete sono nello ZIP degli esercizi del corso, cartella 01-mappa-esp-idf.
Verifica
- Quali sono i due periodi in cui si divide il supporto di una versione maggiore o minore di ESP-IDF, quanto durano e quale dei due è consigliato per iniziare un progetto?
- Nella tabella dei chip supportati dalla v6.1, quale chip non ha nessuna radio e quali hanno l’802.15.4?
- Che rapporto c’è tra Arduino-ESP32 ed ESP-IDF?
- La DevKit ha 8 MB di flash, ma
esp_flash_get_size()restituisce 2 MB. Perché? - Perché nell’esercizio 01.3 si usa
xTaskDelayUntil()e nonvTaskDelay()?
Riepilogo
- ESP-IDF è il framework ufficiale e gratuito (Apache-2.0) di Espressif: codice per il chip diviso in componenti, FreeRTOS come base, strumenti sul PC comandati da
idf.py. - I componenti sono a strati: servizi, sistema e FreeRTOS, driver, HAL e LL, registri. Altri componenti arrivano dal registro tramite il Component Manager.
- La v6.1 supporta dieci famiglie di chip, dall’ESP32 all’ESP32-P4, più alcuni target in anteprima.
- Ogni versione maggiore o minore ha 30 mesi di supporto: 12 di Service e 18 di Maintenance. Usiamo la v6.1, l’ultima stabile, senza driver legacy.
- Arduino-ESP32 è costruito sopra ESP-IDF; ESP-IDF dà il controllo completo per arrivare a un prodotto.
- La ESP32-C6-DevKitC-1 ha due porte USB-C (ponte USB-UART e USB Serial/JTAG), LED RGB su GPIO8, pulsante BOOT su GPIO9, 8 MB di flash e un sensore di temperatura interno.
Nella prossima puntata
Puntata 2, “Installare l’ambiente”: installiamo ESP-IDF v6.1 sul PC, prepariamo l’estensione per VS Code e facciamo il primo giro completo con idf.py: creazione del progetto, build, flash e monitor. Alla fine potrai far girare sulla DevKit gli esercizi di oggi.
Per approfondire
- Get Started (ESP-IDF v6.1, ESP32-C6)
- ESP-IDF Versions: versionamento e periodi di supporto
- Hardware Abstraction: gli strati LL, HAL e driver
- Guida di migrazione dalla 5.x alla 6.0
- Miscellaneous System APIs: motivo del reset, MAC, heap
- Temperature Sensor: il driver dell’esercizio 01.3
- ESP32-C6-DevKitC-1, guida utente (Espressif)
Corso ESP-IDF di Web App Portal. Testi CC BY-NC-SA 4.0, codice MIT. ESP-IDF è un marchio di Espressif Systems; gli altri marchi appartengono ai rispettivi proprietari.
