ESP32 non si connette al WiFi: codici WiFi.status() e soluzioni
Il tuo ESP32 non si connette al WiFi? Codici WiFi.status() e reason, 2,4 GHz, password, brownout, setTxPower, riconnessione, IP statico ed eduroam spiegati.
Il tuo ESP32 non si connette al WiFi e il monitor seriale mostra solo una fila infinita di puntini? Quasi mai la colpa è di una scheda guasta. I soliti sospetti sono: una rete a 5 GHz, un piccolo errore di battitura nel nome della rete o nella password, un alimentatore debole la cui tensione crolla appena si accende il WiFi, le impostazioni di sicurezza e di canale del router, oppure una rete aziendale a scuola o al lavoro. La buona notizia è che l'ESP32 ti dice già che cosa è andato storto. Devi solo saper leggere il valore di WiFi.status() e il codice reason (motivo) che riporta quando la connessione cade.
In questa guida vedrai prima i passaggi con cui l'ESP32 si unisce a una rete e quale codice di stato restituisce in ognuno. Seguono uno sketch di diagnosi che stampa i codici di stato e di motivo, uno scanner che elenca le reti intorno a te, l'obbligo dei 2,4 GHz e i router dual band, il brownout e la soluzione con setTxPower, uno sketch di riconnessione che si ripristina da solo, l'IP statico, la connessione WPA2-Enterprise per le reti scolastiche e il test con l'hotspot del telefono, che in pochi minuti ti dice se il problema è nel router o nella scheda. Gli sketch funzionano con le versioni 2.x e 3.x del core ESP32 per l'Arduino IDE, e alla fine trovi anche uno script di prova per il Raspberry Pi Pico W e MicroPython.

Come si connette l'ESP32 a una rete WiFi?
Quando chiami WiFi.begin(), l'ESP32 esegue quattro passaggi in background. Prima scansiona i canali alla ricerca di una rete con il nome (SSID) che gli hai dato. Se la trova, si autentica e si associa al router. Nelle reti WPA2 arriva poi l'handshake a 4 vie, il momento in cui si scopre se la password è giusta. Infine chiede un indirizzo IP al server DHCP del router. WiFi.status() restituisce WL_CONNECTED solo quando è terminato anche quest'ultimo passaggio. Se sai a quale passaggio si blocca, conosci già in gran parte la causa:
| Passaggio | Che cosa succede? | Stato e motivo se si blocca |
|---|---|---|
| 1. Scansione | L'ESP32 cerca il nome della rete sui canali a 2,4 GHz | WL_NO_SSID_AVAIL (1), reason 201 |
| 2. Autenticazione e associazione | Il router accetta o rifiuta l'ESP32 | WL_CONNECT_FAILED (4) o WL_DISCONNECTED (6), reason 202 o 203 |
| 3. Handshake a 4 vie | Si confrontano le chiavi ricavate dalla password | WL_DISCONNECTED (6) con reason 15; con reason 204, WL_CONNECTION_LOST (5) |
| 4. DHCP | Il router assegna un indirizzo IP all'ESP32 | Resta bloccato su WL_IDLE_STATUS (0) |
| Dopo la connessione | Il router invia regolarmente pacchetti beacon | Se smettono di arrivare: WL_CONNECTION_LOST (5), reason 200 |
Che cosa significano i codici di WiFi.status()
WiFi.status() restituisce un valore di tipo wl_status_t. Se lo stampi direttamente sul monitor seriale vedi solo un numero. La tabella qui sotto mostra il significato di ogni numero nel core Arduino dell'ESP32. Attenzione: i valori da 0 a 6 hanno gli stessi nomi della vecchia libreria WiFi di Arduino, ma sull'ESP32 compaiono in situazioni un po' diverse. Subito dopo WiFi.begin(), per esempio, lo stato è 6 e non 0; passa a 0 quando la scheda si è associata al router e aspetta un IP, e a 3 quando lo ottiene.
| Codice | Costante | Significato | Cosa controllare prima |
|---|---|---|---|
| 0 | WL_IDLE_STATUS | Associato al router, ma ancora senza indirizzo IP | Normale per qualche secondo; se dura, il DHCP |
| 1 | WL_NO_SSID_AVAIL | Nessuna rete trovata con quel nome | Nome della rete, banda a 2,4 GHz, distanza |
| 2 | WL_SCAN_COMPLETED | Una scansione delle reti è terminata | Non riguarda la connessione |
| 3 | WL_CONNECTED | Connesso e con indirizzo IP | Tutto a posto |
| 4 | WL_CONNECT_FAILED | Il router ha rifiutato la connessione | Password, modalità di sicurezza, filtro MAC |
| 5 | WL_CONNECTION_LOST | Una connessione già stabilita è caduta | Intensità del segnale, alimentazione, antenna |
| 6 | WL_DISCONNECTED | Non connesso; tentativo in corso o fallito | Il codice reason |
| 254 | WL_STOPPED | La stazione WiFi è ferma (core 3.x) | Chiamare WiFi.mode(WIFI_STA) |
| 255 | WL_NO_SHIELD | Il WiFi non è ancora stato avviato (core 2.x) | Chiamare WiFi.mode() o WiFi.begin() |
Sketch di diagnosi: stampa lo stato e il codice reason sul monitor seriale
Lo sketch seguente prova a connettersi per 20 secondi, stampa il codice di stato con il suo nome ogni volta che cambia e mostra il codice reason di ESP-IDF a ogni caduta della connessione. Se si connette, stampa indirizzo IP, gateway, intensità del segnale (RSSI) e canale; in ogni caso mostra anche l'indirizzo MAC della scheda. Sostituisci nome della rete e password con i tuoi, carica lo sketch e apri il monitor seriale a 115200 baud. Se lo sketch non si carica nemmeno, leggi prima la guida sugli errori di caricamento.
1#include <WiFi.h>
2
3const char* WIFI_ADI = "EvAgi_2G"; // Wi-Fi adı, büyük-küçük harfe duyarlı / network name, case-sensitive
4const char* WIFI_SIFRE = "sifre1234"; // Wi-Fi şifresi / Wi-Fi password
5
6// Durum kodunu adına çevir / turn the status code into its name
7const char* durumAdi(wl_status_t durum) {
8 switch (durum) {
9 case WL_IDLE_STATUS: return "WL_IDLE_STATUS";
10 case WL_NO_SSID_AVAIL: return "WL_NO_SSID_AVAIL";
11 case WL_SCAN_COMPLETED: return "WL_SCAN_COMPLETED";
12 case WL_CONNECTED: return "WL_CONNECTED";
13 case WL_CONNECT_FAILED: return "WL_CONNECT_FAILED";
14 case WL_CONNECTION_LOST: return "WL_CONNECTION_LOST";
15 case WL_DISCONNECTED: return "WL_DISCONNECTED";
16 default: return "WL_NO_SHIELD / WL_STOPPED";
17 }
18}
19
20// Bağlantı her koptuğunda sebep kodunu yaz / print the reason code on every disconnect
21void koptugunda(arduino_event_id_t olay, arduino_event_info_t bilgi) {
22 Serial.printf("Koptu / Disconnected, reason: %d\n", (int)bilgi.wifi_sta_disconnected.reason);
23}
24
25void setup() {
26 Serial.begin(115200);
27 delay(1000);
28 WiFi.onEvent(koptugunda, ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
29 WiFi.mode(WIFI_STA); // istasyon modu / station mode
30 WiFi.begin(WIFI_ADI, WIFI_SIFRE); // begin() yalnızca bir kez / call begin() only once
31
32 wl_status_t onceki = WL_NO_SHIELD;
33 unsigned long baslangic = millis();
34 while (WiFi.status() != WL_CONNECTED && millis() - baslangic < 20000) {
35 wl_status_t simdi = WiFi.status();
36 if (simdi != onceki) { // yalnızca değişince yaz / print only when it changes
37 Serial.printf("Durum / Status: %d %s\n", (int)simdi, durumAdi(simdi));
38 onceki = simdi;
39 }
40 delay(500);
41 }
42
43 if (WiFi.status() == WL_CONNECTED) {
44 Serial.print("Bagli / Connected, IP: ");
45 Serial.println(WiFi.localIP());
46 Serial.print("Ag gecidi / Gateway: ");
47 Serial.println(WiFi.gatewayIP());
48 Serial.printf("RSSI: %d dBm, kanal / channel: %d\n", (int)WiFi.RSSI(), (int)WiFi.channel());
49 } else {
50 wl_status_t son = WiFi.status();
51 Serial.printf("Baglanamadi / Failed, son durum / last status: %d %s\n", (int)son, durumAdi(son));
52 }
53 Serial.print("MAC: ");
54 Serial.println(WiFi.macAddress()); // MAC filtresi için / for MAC filtering
55}
56
57void loop() {}È normale vedere per prima la riga Durum / Status: 6 WL_DISCONNECTED. Se la connessione riesce, lo stato passa brevemente a 0 e poi a 3. Se resta a 1, la rete non è mai stata trovata; se compaiono di continuo righe come Koptu / Disconnected, reason: 15, molto probabilmente la password è sbagliata. Per avere ancora più dettagli, imposta Strumenti > Core Debug Level su Warn o Info nell'Arduino IDE: a ogni disconnessione il core scriverà anche il nome del motivo, per esempio Reason: 201 - NO_AP_FOUND. Questi sono i codici reason che incontrerai più spesso:
| Reason | Nome | Che cosa significa? | Soluzione |
|---|---|---|---|
| 2 | AUTH_EXPIRE | L'autenticazione è scaduta | Segnale debole o router sovraccarico; avvicinati, riavvia il router |
| 5 | ASSOC_TOOMANY | Il router ha raggiunto il limite di dispositivi | Scollega i dispositivi inutilizzati o aumenta il limite |
| 8 | ASSOC_LEAVE | È stato l'ESP32 a lasciare la rete | Il tuo codice chiama WiFi.disconnect(); è normale |
| 15 | 4WAY_HANDSHAKE_TIMEOUT | L'handshake della password non si è concluso | Quasi sempre password sbagliata; controllala insieme alla modalità di sicurezza |
| 200 | BEACON_TIMEOUT | Non arrivano più beacon dal router | Segnale debole o calo di tensione; antenna, alimentazione, setTxPower |
| 201 | NO_AP_FOUND | Nessuna rete trovata con questo nome | Grafia dell'SSID, rete a 5 GHz, distanza, rete nascosta, canali 12 e 13 |
| 202 | AUTH_FAIL | L'autenticazione è stata rifiutata | Password o modalità di sicurezza incompatibile, come Enterprise |
| 203 | ASSOC_FAIL | Il router ha rifiutato l'associazione | Filtro MAC o una modalità wireless come solo 802.11ax |
| 204 | HANDSHAKE_TIMEOUT | L'handshake è andato in timeout | Password sbagliata o segnale molto debole |
| 210, 211 | NO_AP_FOUND_W_COMPATIBLE_SECURITY, NO_AP_FOUND_IN_AUTHMODE_THRESHOLD | Rete trovata, ma con una sicurezza incompatibile o sotto il minimo consentito (core 3.x) | Imposta il router su WPA2-Personal (AES) o abbassa il minimo con WiFi.setMinSecurity() |
Solo 2,4 GHz: l'ESP32 non vede le reti a 5 GHz
L'ESP32 classico, l'ESP32-S2, l'ESP32-S3, l'ESP32-C3 e l'ESP32-C6 funzionano solo sulla banda dei 2,4 GHz. Non vedono mai nella scansione una rete che trasmette a 5 GHz, e il risultato è sempre WL_NO_SSID_AVAIL. La maggior parte dei router di casa trasmette su entrambe le bande. Se il tuo router usa un nome diverso per ciascuna banda (per esempio MioWiFi e MioWiFi_5G), dai sempre all'ESP32 il nome della rete a 2,4 GHz. Se le due bande hanno lo stesso nome (Smart Connect, band steering o sistemi mesh), di solito l'ESP32 si collega senza problemi alla parte a 2,4 GHz, perché il segnale a 5 GHz non lo vede comunque. I guai iniziano quando la banda a 2,4 GHz è spenta o quando il router cerca di spingere i dispositivi verso i 5 GHz: l'ESP32 si connette, cade dopo qualche secondo e il ciclo si ripete. In questo caso separa le bande nelle impostazioni del router oppure crea una rete ospiti che trasmetta solo a 2,4 GHz.
| Scheda | Banda WiFi | Nota |
|---|---|---|
| ESP32 (WROOM-32, DevKit), ESP32-S2, ESP32-S3 | Solo 2,4 GHz | 802.11 b/g/n |
| ESP32-C3 | Solo 2,4 GHz | Le schede Super Mini economiche possono richiedere una potenza di trasmissione ridotta |
| ESP32-C6 | Solo 2,4 GHz | Supporta il Wi-Fi 6 (802.11ax), ma sempre e solo a 2,4 GHz |
| ESP32-C5 | 2,4 GHz e 5 GHz | Il primo chip dual band di Espressif |
| ESP8266 (NodeMCU, Wemos D1 mini, ESP-01) | Solo 2,4 GHz | 802.11 b/g/n |
| Raspberry Pi Pico W e Pico 2 W | Solo 2,4 GHz | Chip wireless CYW43439 |
| Arduino Uno R4 WiFi | Solo 2,4 GHz | Del WiFi si occupa l'ESP32-S3 montato sulla scheda |
Se la banda è giusta e la rete continua a non essere trovata, controlla le impostazioni di canale e di modalità del router. Con l'impostazione regionale predefinita dell'ESP32, i canali da 1 a 11 vengono scansionati in modo attivo, mentre i canali 12 e 13 vengono solo ascoltati in modo passivo. Le reti visibili su questi canali di solito vengono trovate lo stesso, ma l'ESP32 non troverà una rete nascosta (con la trasmissione dell'SSID disattivata) sul canale 12 o 13. La scelta più sicura è passare il canale da automatico a un valore fisso: 1, 6 o 11. L'ESP32 classico, l'S2, l'S3 e il C3 non riescono a collegarsi a un router impostato solo su 802.11ax (Wi-Fi 6); passa la modalità a b/g/n o alla mista b/g/n/ax. Per la sicurezza, le opzioni più compatibili sono WPA2-Personal (AES) o la modalità mista WPA2/WPA3. Per impostazione predefinita il core Arduino rifiuta tutto ciò che è più debole del WPA2 (WEP e il vecchio WPA-TKIP); se devi proprio collegarti a una rete molto vecchia, aggiungi WiFi.setMinSecurity(WIFI_AUTH_WEP) prima di begin(). Prima di cambiare qualsiasi impostazione, guarda con questo scanner che cosa vede davvero l'ESP32:
1#include <WiFi.h>
2
3// Güvenlik türünü yazıya çevir / turn the security type into text
4const char* guvenlikAdi(wifi_auth_mode_t tur) {
5 switch (tur) {
6 case WIFI_AUTH_OPEN: return "Acik / Open";
7 case WIFI_AUTH_WEP: return "WEP";
8 case WIFI_AUTH_WPA_PSK: return "WPA";
9 case WIFI_AUTH_WPA2_PSK: return "WPA2";
10 case WIFI_AUTH_WPA_WPA2_PSK: return "WPA/WPA2";
11 case WIFI_AUTH_WPA3_PSK: return "WPA3";
12 case WIFI_AUTH_WPA2_WPA3_PSK: return "WPA2/WPA3";
13 default: return "Diger / Other (Enterprise)";
14 }
15}
16
17void setup() {
18 Serial.begin(115200);
19 WiFi.mode(WIFI_STA);
20 WiFi.disconnect(); // temiz tarama için bağlantıyı kes / disconnect for a clean scan
21 delay(100);
22}
23
24void loop() {
25 Serial.println("Taraniyor / Scanning...");
26 int adet = WiFi.scanNetworks(); // engelleyen tarama, 2-4 sn / blocking scan, 2-4 s
27 if (adet <= 0) {
28 Serial.println("Ag bulunamadi / No networks found");
29 }
30 for (int i = 0; i < adet; i++) {
31 Serial.printf("%2d | %-32s | %4d dBm | kanal/ch %2d | %s\n",
32 i + 1, WiFi.SSID(i).c_str(), (int)WiFi.RSSI(i),
33 (int)WiFi.channel(i), guvenlikAdi(WiFi.encryptionType(i)));
34 }
35 WiFi.scanDelete(); // sonuçları bellekten sil / free the results
36 Serial.println();
37 delay(10000); // 10 sn sonra yeniden tara / scan again in 10 s
38}Se il nome della tua rete non compare affatto nell'elenco, il problema sta a monte del codice: la rete è a 5 GHz, è nascosta oppure l'ESP32 è troppo lontano. Se il nome compare, guarda il suo RSSI: da -30 a -60 dBm è ottimo, da -60 a -70 dBm è buono; tra -70 e -80 dBm si connette ma può cadere, e sotto i -80 dBm non aspettarti una connessione affidabile. Se vedi lo stesso nome più volte, il tuo router o sistema mesh ha più punti di accesso. Con la scansione rapida predefinita l'ESP32 si collega alla prima corrispondenza che trova; se vuoi che scelga il segnale più forte, aggiungi WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN) prima di begin(). Copiare il nome esattamente come appare nella scansione e incollarlo nello sketch elimina gli errori di battitura una volta per tutte.
Errori nel nome della rete (SSID) e nella password
Se lo sketch di diagnosi restituisce reason 201 o 15, il problema di solito sta in due righe del tuo codice. Un SSID può essere lungo fino a 32 byte, una password WPA2 da 8 a 63 caratteri, ed entrambi distinguono tra maiuscole e minuscole. Ecco gli errori che sfuggono più spesso:
- Maiuscole e minuscole: Non puoi collegarti a una rete che nel router si chiama MioWiFi scrivendo miowifi. La stessa regola vale per la password.
- Spazi invisibili: Uno spazio alla fine del nome della rete o della password, o un carattere nascosto finito lì copiando il testo da qualche parte, impedisce la corrispondenza.
- Lettere accentate: Lettere come à, è o ì nel nome della rete possono essere salvate dal router con una codifica diversa. Rinominare la rete usando solo lettere non accentate e numeri è la soluzione più sicura.
- Apostrofo tipografico: Sull'iPhone il nome dell'hotspot è il nome del telefono, che spesso contiene un apostrofo curvo ’ al posto di quello dritto ' della tastiera, quindi il nome nel tuo codice non corrisponde.
- Barra rovesciata e virgolette: Se la password contiene \ o ", scrivili come \\ e \" nella stringa C++; altrimenti il compilatore modifica la password o lo sketch non compila.
- Rete aperta: Per una rete senza password non indicare affatto il parametro della password; basta WiFi.begin(nome). Se passi una password per una rete aperta, il core cerca il WPA2 e non trova la rete.
- Rete nascosta: Puoi collegarti a reti con la trasmissione dell'SSID disattivata scrivendo il nome esatto, ma non compaiono nelle scansioni; se hai problemi, riattiva la trasmissione durante i test.
Alimentazione e brownout: perché la scheda si riavvia quando si accende il WiFi?
Un modulo ESP32 assorbe in media circa 80 mA, ma mentre il trasmettitore WiFi è attivo la corrente sale per un attimo a picchi di 250–400 mA. I picchi maggiori si verificano di solito durante la calibrazione radio all'avvio e durante la prima connessione. Per questo Espressif consiglia un alimentatore in grado di erogare almeno 500 mA. Se l'alimentazione non regge questi picchi, la linea a 3,3 V crolla per un istante, interviene il rilevatore di brownout del chip e la scheda si riavvia con il messaggio Brownout detector was triggered nel monitor seriale. Il sintomo è molto noto: il codice funziona fino alla riga del WiFi, la scheda si resetta su WiFi.begin() e tutto si trasforma in un ciclo infinito. Trattiamo questo errore in dettaglio nell'articolo sugli errori Brownout e Guru Meditation dell'ESP32.

| Fonte di alimentazione | Va bene? | Perché? |
|---|---|---|
| Porta USB sul retro del computer, cavo corto e spesso | Di solito sì | Una porta USB 2.0 eroga 500 mA; un cavo corto riduce la caduta di tensione |
| USB frontale, hub USB o cavo lungo e sottile | Può dare problemi | La resistenza del cavo e dei contatti abbassa la tensione durante i picchi di corrente |
| Caricatore da telefono da 5 V di almeno 1 A | Sì | Lascia ampio margine per i picchi di corrente |
| Pin 3.3V dell'Arduino Uno | No | Questo pin eroga solo circa 50 mA |
| Batteria Li-ion da 3,7 V collegata direttamente al pin 5V della scheda | No | A causa della caduta dell'AMS1117 l'uscita scende sotto i 3 V |
| Batteria Li-ion con step-up a 5 V o regolatore da 3,3 V a bassa caduta | Sì | Fornisce 3,3 V stabili anche mentre la batteria si scarica |
| Uscita a 3,3 V di un modulo di alimentazione MB102 per breadboard | Quasi sempre | Alimentalo con un adattatore che dia corrente sufficiente e aggiungi un condensatore |
La soluzione setTxPower: ridurre la potenza di trasmissione
Su alcune schede, anche con un buon alimentatore, l'ESP32 vede la rete ma non riesce a collegarsi, oppure la connessione cade di continuo. Soprattutto sulle economiche ESP32-C3 Super Mini e su alcuni cloni di ESP32, il circuito d'antenna e il regolatore vanno in difficoltà alla massima potenza di trasmissione. Per impostazione predefinita l'ESP32 trasmette a circa 19,5–20 dBm. Ridurre questa potenza con WiFi.setTxPower() abbassa i picchi di corrente e su queste schede spesso sistema la connessione all'istante. Chiama la funzione subito dopo WiFi.begin(); se la chiami prima che il WiFi sia avviato, cioè prima di WiFi.mode() o di begin(), non ha effetto.
| Costante | Potenza | Quando usarla? |
|---|---|---|
| WIFI_POWER_19_5dBm | 19,5 dBm | Vicino al valore predefinito; portata massima |
| WIFI_POWER_15dBm | 15 dBm | Primo tentativo per problemi lievi |
| WIFI_POWER_11dBm | 11 dBm | Di solito basta se il router è nella stessa stanza |
| WIFI_POWER_8_5dBm | 8,5 dBm | Il valore più consigliato per l'ESP32-C3 Super Mini |
| WIFI_POWER_5dBm | 5 dBm | Per test proprio accanto al router |
Ogni riduzione di 3 dB dimezza la potenza di trasmissione, quindi si accorcia anche la portata. Parti da 15 dBm; se il problema persiste, scendi a 11 e poi a 8,5 dBm. Se abbassando la potenza la connessione torna a funzionare, la vera causa di solito è l'alimentazione o il progetto dell'antenna; nel lungo periodo aggiungi quindi anche un alimentatore migliore e un condensatore. Puoi leggere l'impostazione attuale della scheda con WiFi.getTxPower(); il valore è espresso in unità da 0,25 dBm, quindi 78 corrisponde a 19,5 dBm.
Sketch di riconnessione automatica
L'ESP32 perde la connessione quando il router si riavvia, quando torna la corrente dopo un blackout o quando il segnale si indebolisce per un po'. Nel core dell'ESP32 WiFi.setAutoReconnect(true) è attivo per impostazione predefinita e, dopo la maggior parte delle cadute, la scheda si ricollega da sola. Con alcuni motivi, però, come 202 AUTH_FAIL, il core si arrende dopo un solo tentativo e la scheda resta senza rete finché non la resetti. In un progetto che deve funzionare per mesi conviene quindi aggiungere un tuo controllo. Lo sketch seguente non usa delay(): con millis() controlla la connessione ogni 15 secondi, si ricollega se è caduta e riavvia la scheda se per 5 minuti non riesce a connettersi:
1#include <WiFi.h>
2
3const char* WIFI_ADI = "EvAgi_2G"; // Wi-Fi adı / network name
4const char* WIFI_SIFRE = "sifre1234"; // Wi-Fi şifresi / Wi-Fi password
5
6const unsigned long KONTROL_ARALIGI = 15000; // 15 sn'de bir kontrol / check every 15 s
7const int EN_FAZLA_DENEME = 20; // 20 x 15 sn = 5 dk / 20 x 15 s = 5 min
8unsigned long sonKontrol = 0;
9int basarisizSayac = 0; // üst üste başarısız kontrol / consecutive failed checks
10
11void wifiBaslat() {
12 WiFi.mode(WIFI_STA);
13 WiFi.setAutoReconnect(true); // çekirdeğin kendi yeniden bağlanması / core auto-reconnect
14 WiFi.begin(WIFI_ADI, WIFI_SIFRE);
15 WiFi.setTxPower(WIFI_POWER_15dBm); // gerekirse 8_5dBm'e kadar düşür / lower to 8_5dBm if needed
16 WiFi.setSleep(false); // modem uykusunu kapat / disable modem sleep
17}
18
19void setup() {
20 Serial.begin(115200);
21 wifiBaslat();
22}
23
24void loop() {
25 if (millis() - sonKontrol >= KONTROL_ARALIGI) {
26 sonKontrol = millis();
27 if (WiFi.status() == WL_CONNECTED) {
28 basarisizSayac = 0;
29 Serial.printf("Bagli / Connected, IP: %s, RSSI: %d dBm\n",
30 WiFi.localIP().toString().c_str(), (int)WiFi.RSSI());
31 } else {
32 basarisizSayac++;
33 Serial.printf("Bagli degil / Not connected (%d/%d), yeniden baglaniyor / reconnecting\n",
34 basarisizSayac, EN_FAZLA_DENEME);
35 WiFi.disconnect();
36 WiFi.reconnect();
37 if (basarisizSayac >= EN_FAZLA_DENEME) {
38 Serial.println("Yeniden baslatiliyor / Restarting");
39 delay(100);
40 ESP.restart(); // son çare: kartı yeniden başlat / last resort: restart the board
41 }
42 }
43 }
44
45 // Projenin kodu buraya; uzun delay() kullanma / your project code here; avoid long delay()
46}La riga WiFi.setSleep(false) disattiva il modem sleep, in cui l'ESP32 spegne brevemente la radio a intervalli regolari mentre è connesso. Questo riduce le cadute con alcuni router e la latenza del web server; in cambio la scheda assorbe qualche decina di mA in più. Nei progetti a batteria puoi eliminare questa riga e calcolare quanto durerà la batteria con il calcolatore di durata della batteria. Lascia la riga di setTxPower solo se hai i problemi della sezione precedente. Quando aggiungi il codice del tuo progetto in loop(), evita i delay() lunghi, perché il controllo della connessione funziona solo finché loop() continua a girare. Se preferisci inserire le credenziali WiFi dal telefono invece di scriverle nel codice, dai un'occhiata alla libreria WiFiManager.
Impostare un IP statico sull'ESP32
Normalmente il router assegna all'ESP32 tramite DHCP un indirizzo che può cambiare ogni volta. Se stai costruendo un web server che aprirai sempre allo stesso indirizzo dal telefono, o se il DHCP del router fa i capricci (lo stato resta bloccato a 0), un IP statico ti semplifica la vita. Rispetta tre regole: WiFi.config() va chiamato prima di WiFi.begin(); l'indirizzo scelto deve stare nella rete del router ma fuori dal suo intervallo DHCP (se il router assegna da 192.168.1.2 a 100, usa per esempio 192.168.1.200); e il gateway è l'indirizzo del router stesso. Per scoprire l'indirizzo del tuo router, esegui una volta lo sketch di diagnosi con il DHCP; stampa anche il gateway.
1#include <WiFi.h>
2
3const char* WIFI_ADI = "EvAgi_2G"; // Wi-Fi adı / network name
4const char* WIFI_SIFRE = "sifre1234"; // Wi-Fi şifresi / Wi-Fi password
5
6IPAddress sabitIP(192, 168, 1, 200); // DHCP havuzunun dışında bir adres / an address outside the DHCP pool
7IPAddress agGecidi(192, 168, 1, 1); // modemin adresi / router address
8IPAddress altAgMaskesi(255, 255, 255, 0); // alt ağ maskesi / subnet mask
9IPAddress dns1(1, 1, 1, 1); // birinci DNS / primary DNS
10IPAddress dns2(8, 8, 8, 8); // ikinci DNS / secondary DNS
11
12void setup() {
13 Serial.begin(115200);
14 WiFi.mode(WIFI_STA);
15 // config() mutlaka begin()'den önce / config() must come before begin()
16 if (!WiFi.config(sabitIP, agGecidi, altAgMaskesi, dns1, dns2)) {
17 Serial.println("Statik IP ayarlanamadi / Static IP config failed");
18 }
19 WiFi.begin(WIFI_ADI, WIFI_SIFRE);
20
21 unsigned long baslangic = millis();
22 while (WiFi.status() != WL_CONNECTED && millis() - baslangic < 15000) {
23 delay(500);
24 Serial.print('.');
25 }
26 Serial.println();
27 Serial.print("IP: ");
28 Serial.println(WiFi.localIP()); // 192.168.1.200 olmalı / should be 192.168.1.200
29}
30
31void loop() {}Reti scolastiche e aziendali: connessione WPA2-Enterprise (eduroam)
eduroam nelle università, le reti aziendali e alcune reti scolastiche usano il WPA2-Enterprise (802.1X), che assegna a ogni utente un proprio nome utente e una propria password invece di un'unica password condivisa. Un normale WiFi.begin(nome, password) su queste reti fallisce sempre, e nello scanner il loro tipo di sicurezza appare come Diger / Other (Enterprise). Le versioni 2.x e 3.x del core Arduino dell'ESP32 offrono una variante di begin() già pronta per il PEAP, il metodo più diffuso:
1#include <WiFi.h>
2
3const char* AG_ADI = "eduroam"; // kurum ağının adı / enterprise network name
4const char* EAP_KIMLIK = "[email protected]"; // kimlik, çoğu zaman kullanıcı adıyla aynı / identity, usually same as username
5const char* EAP_KULLANICI = "[email protected]"; // kullanıcı adı / username
6const char* EAP_SIFRE = "kurum_sifren"; // kurum şifresi / enterprise password
7
8void setup() {
9 Serial.begin(115200);
10 WiFi.disconnect(true); // önceki bağlantıyı kapat / close any previous connection
11 WiFi.mode(WIFI_STA);
12 // PEAP (MSCHAPv2) ile bağlan, CA doğrulaması yok / connect with PEAP (MSCHAPv2), no CA check
13 WiFi.begin(AG_ADI, WPA2_AUTH_PEAP, EAP_KIMLIK, EAP_KULLANICI, EAP_SIFRE);
14
15 unsigned long baslangic = millis();
16 while (WiFi.status() != WL_CONNECTED && millis() - baslangic < 30000) {
17 delay(500);
18 Serial.print('.');
19 }
20 Serial.println();
21 if (WiFi.status() == WL_CONNECTED) {
22 Serial.print("Bagli / Connected, IP: ");
23 Serial.println(WiFi.localIP());
24 } else {
25 Serial.printf("Baglanamadi / Failed, durum / status: %d\n", (int)WiFi.status());
26 }
27}
28
29void loop() {}Nella maggior parte degli enti l'identità (identity) coincide con il nome utente; alcuni chiedono un'identità esterna anonima come [email protected]. Questo sketch non verifica il certificato del server (CA): la connessione funziona, ma un falso punto di accesso potrebbe catturare la tua password. Prima di scrivere la tua password personale in un ESP32, quindi, chiedi al servizio informatico e, se possibile, fatti dare un account o una rete dedicati ai dispositivi. Se il tuo ente richiede un certificato, puoi passare il file CA come sesto parametro di begin(). Le reti che aprono una pagina di accesso nel browser (captive portal), come quelle di hotel, studentati e bar, sono un problema a parte, perché l'ESP32 non può compilare quella pagina. Alcune scuole chiedono inoltre di registrare in anticipo l'indirizzo MAC dei dispositivi; comunica al servizio informatico il MAC stampato dallo sketch di diagnosi. Su queste reti la soluzione più pratica è l'hotspot del telefono o un piccolo router tascabile.
Test con l'hotspot del telefono: è colpa del router o dell'ESP32?
Il modo più rapido per individuare la causa è collegare l'ESP32 a una rete di cui controlli completamente le impostazioni. L'hotspot del tuo telefono è perfetto per questo:
- Dai all'hotspot un nome breve, fatto solo di lettere non accentate e numeri (per esempio esptest), e una password semplice di almeno 8 caratteri (per esempio test12345).
- Su Android, imposta l'opzione della banda nelle impostazioni dell'hotspot (su alcuni telefoni si chiama banda AP o Velocità e compatibilità) su 2,4 GHz e scegli WPA2-Personal come tipo di sicurezza.
- Sull'iPhone, vai in Impostazioni > Hotspot personale e attiva Consenti accesso ad altri. Sui modelli più recenti attiva anche Massimizza compatibilità; così l'hotspot passa ai 2,4 GHz. Il nome dell'hotspot è il nome del telefono: semplificalo in Impostazioni > Generali > Info > Nome e tieni aperta la schermata Hotspot personale finché l'ESP32 non si è connesso.
- Sostituisci nome della rete e password nello sketch di diagnosi con i dati dell'hotspot, metti il telefono a 1–2 metri dall'ESP32 e carica lo sketch.
- Leggi i codici di stato e di motivo nel monitor seriale, poi prova lo stesso sketch con i dati del router di casa.
Interpreta il risultato così: se l'ESP32 si collega all'hotspot ma non al router di casa, il tuo codice, la scheda e l'alimentazione sono a posto; il problema sta nelle impostazioni di banda, canale, sicurezza, filtro MAC o limite di dispositivi del router. Se non si collega nemmeno all'hotspot, il problema è dalla parte dell'ESP32: cambia alimentatore e cavo, abbassa la potenza con setTxPower, assicurati che non ci sia metallo davanti all'antenna e ricontrolla il codice. Il test dell'hotspot è anche il modo più veloce per dimostrare che un progetto che a scuola non si connette in realtà funziona.
Test WiFi con il Raspberry Pi Pico W e MicroPython
Anche il Raspberry Pi Pico W e il Pico 2 W supportano solo i 2,4 GHz; tutti i consigli di questo articolo su banda, password, alimentazione e hotspot valgono anche per queste schede. In MicroPython i codici di stato si leggono con le costanti del modulo network. Lo script seguente funziona senza modifiche in Thonny sia sull'ESP32 sia sul Pico W. Sul Pico W smette subito di aspettare se la rete non viene trovata o la password è sbagliata; sull'ESP32 MicroPython continua a riprovare dopo alcuni errori, quindi lo script mostra l'ultimo stato dopo 20 secondi:
1import network, time
2
3AG_ADI = "EvAgi_2G" # Wi-Fi adı / network name
4SIFRE = "sifre1234" # Wi-Fi şifresi / Wi-Fi password
5
6wlan = network.WLAN(network.STA_IF)
7wlan.active(True)
8if wlan.isconnected():
9 wlan.disconnect() # eski bağlantıyı kapat / close the previous connection
10 time.sleep(1)
11wlan.connect(AG_ADI, SIFRE)
12
13durum = wlan.status()
14for saniye in range(20): # en fazla 20 sn bekle / wait up to 20 s
15 durum = wlan.status()
16 print(saniye, "durum / status:", durum)
17 if durum in (network.STAT_GOT_IP, network.STAT_NO_AP_FOUND, network.STAT_WRONG_PASSWORD):
18 break # sonuç belli, beklemeyi bırak / result is known, stop waiting
19 time.sleep(1)
20
21if durum == network.STAT_GOT_IP:
22 print("Bagli / Connected, IP:", wlan.ifconfig()[0])
23 print("RSSI:", wlan.status("rssi"), "dBm")
24elif durum == network.STAT_NO_AP_FOUND:
25 print("Ag bulunamadi / Network not found (SSID, 2.4 GHz)")
26elif durum == network.STAT_WRONG_PASSWORD:
27 print("Sifre yanlis / Wrong password")
28else:
29 print("Baglanamadi / Failed, durum / status:", durum)Sul Pico W i valori numerici sono diversi: 3 significa connesso con IP, 2 connesso ma in attesa di IP, -1 errore generico, -2 rete non trovata e -3 password sbagliata. Sull'ESP32 vedrai invece 1001 durante la connessione, 1010 quando ottiene l'IP e, in caso di problemi, codici reason di ESP-IDF come 201 e 202. Per evitare problemi con i canali 12 e 13 sul Pico W, imposta il codice del paese prima di connetterti (rp2.country('IT'), oppure network.country('IT') nei firmware più recenti); se la connessione cade ogni tanto, puoi disattivare il risparmio energetico con wlan.config(pm=0xa11140). Per creare un web server con il Pico W leggi l'articolo web server WiFi con il Pico W, e se sei alle prime armi con MicroPython dai un'occhiata alla guida sulle basi di MicroPython.
Errori frequenti e soluzioni
| Sintomo | Causa probabile | Soluzione |
|---|---|---|
| Caratteri senza senso nel monitor seriale | Il baud rate non corrisponde | Imposta il monitor seriale a 115200 baud |
| Stato 1, reason 201 | Nome della rete sbagliato, rete a 5 GHz o troppo lontano | Avvia lo scanner e copia esattamente il nome della rete a 2,4 GHz |
| Stato 6, reason 15 a ripetizione | Password sbagliata | Riscrivi la password facendo attenzione a maiuscole e caratteri speciali |
| Stato 4 o 6; reason 202, 210 o 211 | Modalità di sicurezza incompatibile | Imposta il router su WPA2-Personal (AES) o sulla modalità mista WPA2/WPA3 |
| Resta bloccato sullo stato 0 | Associato al router ma non riceve un IP dal DHCP | Riavvia il router, amplia l'intervallo DHCP o usa un IP statico |
| Reset su WiFi.begin() con Brownout detector was triggered | L'alimentatore non regge i picchi di corrente | Cavo corto, adattatore da almeno 1 A, 470 µF tra 3V3 e GND |
| Si connette e cade dopo qualche minuto (reason 200) | Segnale debole, modem sleep o problema di alimentazione | setSleep(false), setTxPower, sketch di riconnessione, avvicinare al router |
| Funziona sul tavolo, ma non dentro la scatola | Scatola metallica o batteria davanti all'antenna | Posiziona l'antenna sul bordo della scatola rivolta verso l'esterno, usa una scatola di plastica |
| Connesso, ma la pagina web non si apre sul telefono | Il telefono è su un'altra rete o la rete ospiti isola i dispositivi | Collega entrambi alla stessa rete e leggi l'IP nel monitor seriale |
| I valori di analogRead() impazziscono con il WiFi attivo | Il sensore è su un pin ADC2, e il WiFi usa l'ADC2 | Sposta il sensore sui pin ADC1, GPIO 32–39 |
| Portata di pochi centimetri su un ESP32-CAM o una scheda con antenna esterna | La selezione dell'antenna è su esterna, ma nessuna antenna è collegata | Collega un'antenna al connettore IPEX o controlla la resistenza da 0 Ω che seleziona l'antenna |
Connesso: che cosa puoi costruire adesso?
- Web server e dashboard in tempo reale: Realizza un web server ESP32 con WebSocket che mostri i valori dei sensori sul telefono in tempo reale.
- Orologio via internet: Prendi l'ora da un server NTP e mostrala su un display.
- Display meteo: Recupera temperatura e umidità della tua città con un'API meteo.
- Notifiche sul telefono: Invia un messaggio con un bot Telegram quando si apre la porta.
- Casa intelligente: Collega l'ESP32 a Home Assistant tramite MQTT.
- Comunicazione senza router: Fai parlare due ESP32 con ESP-NOW senza collegarli a nessuna rete.
- Caricamento senza fili: Quando la scheda è già chiusa nella sua scatola, invia il nuovo codice via WiFi con un aggiornamento OTA.
Un ESP32 che non si connette al WiFi all'inizio confonde, ma i codici di stato e di motivo ti dicono sempre in quale passaggio si trova il problema: 1 e 201 indicano che la rete non è stata trovata, 15 e 202 puntano alla password o alla modalità di sicurezza, 0 al DHCP, e 200 o i reset improvvisi al segnale o all'alimentazione. Se hai appena scoperto l'ESP32, trovi le basi in Che cos'è l'ESP32?. Nell'app BlueGrays puoi anche esplorare progetti come la connessione WiFi dell'ESP32, web server, mDNS, orologio NTP, stazione meteo, aggiornamento OTA e allarme Telegram, con schemi di collegamento passo passo e codice pronto all'uso.
Domande frequenti
Perché il mio ESP32 non si connette al WiFi?
Le cause più comuni sono una rete a 5 GHz, un errore di battitura nel nome della rete o nella password, un alimentatore debole la cui tensione crolla all'avvio del WiFi e le impostazioni di sicurezza del router. Stampa il valore di WiFi.status() e il codice reason alla disconnessione e vedrai subito quale delle due è la causa. Se la rete non viene trovata vedrai 1 e 201; con una password sbagliata, di solito 6 e 15.
L'ESP32 si può connettere al WiFi a 5 GHz?
L'ESP32 classico, l'ESP32-S2, S3, C3 e C6 supportano solo i 2,4 GHz e nella scansione non vedono affatto le reti a 5 GHz. Il modello dual band è l'ESP32-C5. Se il tuo router trasmette le due bande con nomi diversi, dai all'ESP32 il nome della rete a 2,4 GHz.
Che cosa significa WiFi.status() 6 sull'ESP32?
6 corrisponde a WL_DISCONNECTED: la scheda non è connessa e il tentativo di connessione è ancora in corso oppure è fallito. Sull'ESP32 una password sbagliata dà spesso questo valore invece di 4 (WL_CONNECT_FAILED). Per vedere la vera causa, guarda il codice reason dell'evento ARDUINO_EVENT_WIFI_STA_DISCONNECTED.
Perché il mio ESP32 si disconnette continuamente dal WiFi?
Le cause principali delle cadute continue sono un segnale debole, un alimentatore che non regge i picchi di corrente del WiFi, metallo o una batteria davanti all'antenna e il band steering del router. Avvicina la scheda al router, aggiungi un condensatore da 100–470 µF tra 3V3 e GND e disattiva il modem sleep con WiFi.setSleep(false). Scrivi inoltre il codice in modo che si ricolleghi da solo dopo una caduta.
Un ESP32 si può connettere all'hotspot del telefono?
Sì, purché l'hotspot trasmetta a 2,4 GHz. Su Android imposta la banda dell'hotspot su 2,4 GHz, sull'iPhone attiva Massimizza compatibilità e usa un nome semplice. Il test dell'hotspot è il modo più rapido per capire se il problema è nel router di casa o nell'ESP32.
Un ESP32 si può connettere a eduroam o alla rete della scuola?
L'ESP32 può collegarsi a reti WPA2-Enterprise come eduroam con la variante WiFi.begin(nome, WPA2_AUTH_PEAP, identità, utente, password) del core Arduino dell'ESP32. Sulle reti che aprono una pagina di accesso nel browser (captive portal), invece, l'ESP32 non può compilare quella pagina. La cosa migliore è chiedere prima al servizio informatico e, se possibile, farsi dare un account separato per i dispositivi.
Progetti da realizzare dopo questo articolo
Vedi tutti i progetti
Connessione Wi-Fi STA con ESP32 (con display LCD)
In questo progetto colleghiamo l'ESP32 alla rete Wi-Fi domestica in modalità Station (STA) in modo sicuro e tollerante agli errori. Separiamo SSID e password in un file `secrets.h` per impedire fughe su Git, impostiamo un meccanismo di riconnessione automatica e visualizziamo il livello del segnale RSSI e l'indirizzo IP su un display LCD I2C. Il LED interno funge da indicatore di stato.

Server web asincrono ESP32 (con indicazione dell'IP sul display LCD)
In questo progetto trasformiamo l'ESP32 in un **server web asincrono** che potrete controllare dal vostro telefono o computer collegato alla stessa rete Wi-Fi. Grazie alla libreria ESPAsyncWebServer, il server è in grado di elaborare più richieste contemporaneamente (a differenza del classico `WebServer.h`, che si blocca su una singola richiesta).

ESP32 mDNS: accesso al dispositivo tramite bluegrays-esp.local (con schermo LCD)
In questo progetto, aggiungendo il servizio mDNS (Multicast DNS) all'ESP32, consentiamo l'accesso tramite un nome host leggibile, come `bluegrays-esp.local`, anziché tramite l'indirizzo IP. Anche se l'IP assegnato dal DHCP dovesse cambiare, potrete sempre raggiungere il dispositivo con lo stesso nome. Eseguendo anche un piccolo server web, inviamo comandi di controllo dei LED dal browser all’indirizzo `http://bluegrays-esp.local/`. Sul display LCD I2C vengono visualizzati il nome host, l’IP e lo

ESP32: ora reale da Internet tramite NTP
L'ESP32 si connette al Wi-Fi e recupera l'ora reale con precisione al millisecondo dai server NTP (Network Time Protocol). Grazie a `configTzTime()`, il fuso orario della Turchia (TRT, UTC+3) viene applicato automaticamente e il passaggio all'ora legale è gestito tramite la stringa POSIX TZ. L'ora viene mostrata sul Serial Monitor e su un display LCD I2C opzionale. `configTzTime()` avvia il servizio SNTP; vengono eseguite risincronizzazioni periodiche finché è disponibile l'accesso alla rete, e

ESP32 HTTPClient + API meteo (con schermo LCD)
In questo progetto, utilizzando l'ESP32, effettuiamo una chiamata REST all'API meteo (wttr.in) tramite Internet utilizzando `HTTPClient.h`. Analizziamo la risposta JSON restituita tramite ArduinoJson v7 e visualizziamo le informazioni relative a città, temperatura, umidità, condizioni meteorologiche e vento sul display LCD I2C sia in turco che in inglese. wttr.in è gratuito e non richiede una chiave API: basta digitare il nome di una città qualsiasi per ottenere le condizioni meteorologiche in t

Aggiornamento OTA dell'ESP32 — Installazione wireless del firmware (con display LCD)
In questo progetto imparerai a installare il nuovo firmware sull'ESP32 tramite Wi-Fi, senza bisogno di un cavo USB. Grazie alla libreria `ArduinoOTA`, l'ESP32 diventa visibile sulla rete e viene automaticamente elencato come `bluegrays-ota` nella scheda "Network port" dell'IDE di Arduino. Il primo caricamento avviene tramite USB, mentre tutti gli aggiornamenti successivi saranno wireless — una caratteristica fondamentale per i dispositivi sul campo. Sul display LCD I2C vengono visualizzati, sia

Contatore WebSocket ESP32 (2 pulsanti + LCD + Web in tempo reale)
In questo progetto due pulsanti collegati all'ESP32 (GPIO 5 incrementa, GPIO 4 decrementa) modificano un contatore. Il valore si aggiorna all'istante su un display LCD I2C 16x2 e, grazie al supporto WebSocket di ESPAsyncWebServer, in tutti i browser collegati senza ricaricare la pagina. Al posto del polling HTTP si usa un'unica connessione persistente e l'ESP32 invia il nuovo valore a tutti con ws.textAll().

Sistema di Allarme Movimento ESP32 (PIR + Buzzer + LED + Telegram)
Un sistema di allarme di sicurezza intelligente che attiva buzzer e LED quando il sensore PIR rileva movimento, inviando contemporaneamente una notifica istantanea al proprietario tramite Telegram. Dispone di un tempo di attesa di 30 secondi per limitare la frequenza degli allarmi ripetuti; questo meccanismo non verifica la validità dei rilevamenti del sensore PIR né elimina le false attivazioni. Adatto a sicurezza domestica, monitoraggio di garage, magazzini o studi. Con l'ESP32-CAM è possibile
Altri articoli
App BlueGrays
Costruisci questo circuito passo passo sul telefono
Schema, codice ed elenco componenti in un’unica schermata. Oltre 160 progetti Arduino, ESP32 e Pico da realizzare.
Inquadra con il telefono
Punta la fotocamera sul codice: si apre lo store del tuo telefono.
oppure apri lo store

