ESP32 não conecta ao Wi-Fi? Códigos do WiFi.status() e soluções reais
ESP32 não conecta ao Wi-Fi? Entenda o WiFi.status() e os códigos reason, resolva problemas de 2,4 GHz e senha, brownout, setTxPower, reconexão, IP estático e eduroam.
ESP32 não conecta ao Wi-Fi e o Monitor Serial só fica imprimindo pontinhos? A causa quase nunca é uma placa com defeito. Os suspeitos de sempre são: tentar entrar em uma rede de 5 GHz, um pequeno erro de digitação no nome da rede ou na senha, uma fonte fraca cuja tensão despenca no instante em que o Wi-Fi liga, as configurações de segurança e de canal do roteador, ou uma rede corporativa na escola ou no trabalho. A boa notícia é que o ESP32 já diz o que deu errado. Você só precisa saber ler o valor de WiFi.status() e o código reason (motivo) que ele informa quando a conexão cai.
Neste guia você vai ver primeiro as etapas que o ESP32 percorre para entrar em uma rede e qual código de status ele informa em cada uma. Depois vêm um sketch de diagnóstico que imprime os códigos de status e reason, um scanner que lista as redes ao seu redor, a exigência de 2,4 GHz e os roteadores dual band, o brownout e a solução com setTxPower, um sketch de reconexão que se recupera sozinho, IP estático, uma conexão WPA2-Enterprise para redes de escola e o teste com o hotspot do celular, que mostra em poucos minutos se o problema está no roteador ou na placa. Os sketches funcionam com as versões 2.x e 3.x do core ESP32 para a Arduino IDE e, no final, há também um script de teste para o Raspberry Pi Pico W com MicroPython.

Como o ESP32 se conecta a uma rede Wi-Fi?
Quando você chama WiFi.begin(), o ESP32 executa quatro etapas em segundo plano. Primeiro ele varre os canais em busca de uma rede com o nome (SSID) que você informou. Se encontrar, ele faz a autenticação e a associação com o roteador. Em redes WPA2, vem em seguida o 4-way handshake (aperto de mão em quatro etapas), o momento em que fica claro se a senha está certa. Por fim, ele pede um endereço IP ao servidor DHCP do roteador. WiFi.status() só retorna WL_CONNECTED quando esta última etapa também termina. Se você sabe em qual etapa ele travou, já sabe boa parte da causa:
| Etapa | O que acontece? | Status e reason se travar |
|---|---|---|
| 1. Varredura | O ESP32 procura o nome da rede nos canais de 2,4 GHz | WL_NO_SSID_AVAIL (1) e reason 201 |
| 2. Autenticação e associação | O roteador aceita ou rejeita o ESP32 | WL_CONNECT_FAILED (4) ou WL_DISCONNECTED (6), reason 202 ou 203 |
| 3. 4-way handshake | As chaves derivadas da senha são comparadas | WL_DISCONNECTED (6) com reason 15; WL_CONNECTION_LOST (5) com reason 204 |
| 4. DHCP | O roteador dá um endereço IP ao ESP32 | Fica travado em WL_IDLE_STATUS (0) |
| Depois de conectar | O roteador continua enviando pacotes beacon | Se pararem: WL_CONNECTION_LOST (5), reason 200 |
O que significam os códigos do WiFi.status()
WiFi.status() retorna um valor do tipo wl_status_t. Se você o imprimir direto no Monitor Serial, verá apenas um número. A tabela abaixo mostra o que cada número significa no core ESP32 para Arduino. Atenção: os valores de 0 a 6 têm os mesmos nomes da antiga biblioteca WiFi do Arduino, mas no ESP32 eles aparecem em situações um pouco diferentes. Por exemplo, logo depois de WiFi.begin() o status é 6, e não 0; ele muda para 0 quando a placa já entrou no roteador e está esperando um IP, e para 3 quando recebe o IP.
| Código | Constante | Significado | Verifique primeiro |
|---|---|---|---|
| 0 | WL_IDLE_STATUS | Entrou no roteador, mas ainda não tem endereço IP | Normal por alguns segundos; se demorar, DHCP |
| 1 | WL_NO_SSID_AVAIL | Nenhuma rede com esse nome foi encontrada | Nome da rede, banda de 2,4 GHz, distância |
| 2 | WL_SCAN_COMPLETED | Uma varredura de redes terminou | Não tem relação com a conexão |
| 3 | WL_CONNECTED | Conectado e com endereço IP | Tudo certo |
| 4 | WL_CONNECT_FAILED | O roteador rejeitou a conexão | Senha, modo de segurança, filtro de MAC |
| 5 | WL_CONNECTION_LOST | Uma conexão já estabelecida caiu | Intensidade do sinal, fonte de alimentação, antena |
| 6 | WL_DISCONNECTED | Não conectado; ainda tentando ou a tentativa falhou | O código reason |
| 254 | WL_STOPPED | A estação Wi-Fi está parada (core 3.x) | Chame WiFi.mode(WIFI_STA) |
| 255 | WL_NO_SHIELD | O Wi-Fi ainda não foi iniciado (core 2.x) | Chame WiFi.mode() ou WiFi.begin() |
Sketch de diagnóstico: imprima o status e o código reason no Monitor Serial
O sketch abaixo tenta conectar por 20 segundos, imprime o código de status com o nome sempre que ele muda e mostra o código reason do ESP-IDF toda vez que a conexão cai. Se conectar, imprime o endereço IP, o gateway, a intensidade do sinal (RSSI) e o canal; em todos os casos mostra também o endereço MAC da placa. Troque o nome da rede e a senha pelos seus, carregue o sketch e abra o Monitor Serial em 115200 baud. Se o sketch nem chega a carregar, leia primeiro o guia de erro ao carregar código.
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() {}É normal ver primeiro Durum / Status: 6 WL_DISCONNECTED. Se a conexão der certo, o status muda rapidamente para 0 e depois para 3. Se ficar em 1, a rede nunca foi encontrada; se linhas como Koptu / Disconnected, reason: 15 continuarem chegando, a senha provavelmente está errada. Para ter ainda mais detalhes, ajuste Ferramentas > Core Debug Level na Arduino IDE para Warn ou Info: o core passa a imprimir também o nome do motivo a cada desconexão, por exemplo Reason: 201 - NO_AP_FOUND. Estes são os códigos reason que você vai encontrar com mais frequência:
| Reason (motivo) | Nome | O que significa? | Solução |
|---|---|---|---|
| 2 | AUTH_EXPIRE | A autenticação expirou (tempo esgotado) | Sinal fraco ou roteador sobrecarregado; aproxime-se, reinicie o roteador |
| 5 | ASSOC_TOOMANY | O limite de clientes do roteador está cheio | Remova dispositivos que você não usa ou aumente o limite |
| 8 | ASSOC_LEAVE | O próprio ESP32 saiu da rede | Seu código chama WiFi.disconnect(); isso é normal |
| 15 | 4WAY_HANDSHAKE_TIMEOUT | O handshake da senha não pôde ser concluído | Na maioria das vezes, senha errada; confira a senha e o modo de segurança |
| 200 | BEACON_TIMEOUT | Os beacons do roteador pararam de chegar | Sinal fraco ou queda de tensão; antena, fonte de alimentação, setTxPower |
| 201 | NO_AP_FOUND | Nenhuma rede com esse nome foi encontrada | Grafia do SSID, rede de 5 GHz, distância, rede oculta, canais 12 e 13 |
| 202 | AUTH_FAIL | A autenticação foi rejeitada | Senha ou um modo de segurança incompatível, como Enterprise |
| 203 | ASSOC_FAIL | O roteador rejeitou a associação | Filtro de MAC ou um modo sem fio como só 802.11ax |
| 204 | HANDSHAKE_TIMEOUT | O handshake expirou | Senha errada ou sinal muito fraco |
| 210, 211 | NO_AP_FOUND_W_COMPATIBLE_SECURITY, NO_AP_FOUND_IN_AUTHMODE_THRESHOLD | Rede encontrada, mas o modo de segurança é incompatível ou está abaixo do mínimo permitido (core 3.x) | Configure o roteador para WPA2-Personal (AES) ou reduza o mínimo com WiFi.setMinSecurity() |
Exigência de 2,4 GHz: o ESP32 não enxerga redes de 5 GHz
O ESP32 clássico, o ESP32-S2, o ESP32-S3, o ESP32-C3 e o ESP32-C6 funcionam só na banda de 2,4 GHz. Numa varredura, eles nunca enxergam uma rede que transmite em 5 GHz, e o resultado é sempre WL_NO_SSID_AVAIL. A maioria dos roteadores domésticos transmite nas duas bandas. Se o seu roteador usa um nome diferente para cada banda (por exemplo MinhaRede e MinhaRede_5G), informe sempre ao ESP32 o nome da rede de 2,4 GHz. Se as duas bandas têm o mesmo nome (Smart Connect, band steering ou sistemas mesh), o ESP32 normalmente entra no lado de 2,4 GHz sem problemas, porque de qualquer forma ele não enxerga o sinal de 5 GHz. Os problemas começam quando a banda de 2,4 GHz está desligada ou quando o roteador tenta empurrar os clientes para os 5 GHz: o ESP32 conecta, cai alguns segundos depois e o ciclo se repete. Nesse caso, separe as bandas nas configurações do roteador ou crie uma rede de convidados que transmita só em 2,4 GHz.
| Placa | Banda Wi-Fi | Observação |
|---|---|---|
| ESP32 (WROOM-32, DevKit), ESP32-S2, ESP32-S3 | Só 2,4 GHz | 802.11 b/g/n |
| ESP32-C3 | Só 2,4 GHz | Placas Super Mini baratas podem precisar de uma potência de transmissão menor |
| ESP32-C6 | Só 2,4 GHz | Suporta Wi-Fi 6 (802.11ax), mas ainda só em 2,4 GHz |
| ESP32-C5 | 2,4 GHz e 5 GHz | O primeiro chip dual band da Espressif |
| ESP8266 (NodeMCU, Wemos D1 mini, ESP-01) | Só 2,4 GHz | 802.11 b/g/n |
| Raspberry Pi Pico W e Pico 2 W | Só 2,4 GHz | Chip sem fio CYW43439 |
| Arduino Uno R4 WiFi | Só 2,4 GHz | O ESP32-S3 da própria placa cuida do Wi-Fi |
Se a banda está certa e a rede ainda não é encontrada, confira as configurações de canal e de modo do roteador. Com a configuração de região padrão do ESP32, os canais 1 a 11 são varridos de forma ativa, enquanto os canais 12 e 13 são apenas escutados de forma passiva. Redes visíveis nesses canais normalmente ainda são encontradas, mas uma rede oculta (transmissão do SSID desligada) no canal 12 ou 13 não será encontrada pelo ESP32. A escolha mais segura é trocar o canal de automático para um valor fixo: 1, 6 ou 11. O ESP32 clássico, o S2, o S3 e o C3 não conseguem entrar em um roteador configurado só em 802.11ax (Wi-Fi 6); mude o modo para b/g/n ou para o misto b/g/n/ax. Em segurança, as opções mais compatíveis são WPA2-Personal (AES) ou o modo misto WPA2/WPA3. Por padrão, o core Arduino rejeita qualquer coisa mais fraca que WPA2 (WEP e o antigo WPA-TKIP); se você realmente precisar entrar em uma rede muito antiga, adicione WiFi.setMinSecurity(WIFI_AUTH_WEP) antes de begin(). Antes de mudar qualquer configuração, use este scanner para ver o que o ESP32 realmente enxerga:
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 o nome da sua rede nem aparece na lista, o problema vem antes do código: a rede é de 5 GHz, está oculta ou o ESP32 está longe demais. Se o nome está lá, olhe o RSSI ao lado dele: de -30 a -60 dBm é excelente e de -60 a -70 dBm é bom; entre -70 e -80 dBm conecta, mas pode cair, e abaixo de -80 dBm não espere uma conexão confiável. Se o mesmo nome aparece várias vezes, o seu roteador ou sistema mesh tem mais de um ponto de acesso. Com a varredura rápida padrão, o ESP32 entra no primeiro que encontra; se você quer que ele escolha o sinal mais forte, adicione WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN) antes de begin(). Copiar o nome exatamente como aparece na varredura e colar no seu sketch elimina de vez os erros de digitação.
Erros no nome da rede (SSID) e na senha
Se o sketch de diagnóstico informa reason 201 ou 15, o problema geralmente está em duas linhas do seu código. Um SSID pode ter até 32 bytes, uma senha WPA2 precisa ter de 8 a 63 caracteres, e os dois diferenciam maiúsculas de minúsculas. Estes são os erros que mais passam despercebidos:
- Maiúsculas e minúsculas: Você não consegue entrar em uma rede que aparece como MinhaRede no roteador digitando minharede. A mesma regra vale para a senha.
- Espaços invisíveis: Um espaço no final do nome da rede ou da senha, ou um caractere oculto que veio junto ao copiar de algum lugar, quebra a correspondência.
- Caracteres especiais: Letras acentuadas (como ç, ã, é) ou símbolos no nome da rede podem estar gravados no roteador com outra codificação. Renomear a rede usando só letras sem acento e números é a solução mais garantida.
- Apóstrofo curvo: No iPhone, o nome do hotspot é o nome do celular; se ele tiver um apóstrofo, muitas vezes é um ’ curvo em vez do ' reto do seu teclado, e por isso o nome no seu código não bate.
- Barra invertida e aspas: Se a senha contém \ ou ", escreva-os como \\ e \" na string C++; caso contrário, o compilador altera a senha ou o sketch não compila.
- Rede aberta: Para entrar em uma rede sem senha, omita a senha por completo; WiFi.begin(nome) basta. Se você passar uma senha para uma rede aberta, o core procura WPA2 e não encontra a rede.
- Rede oculta: Você consegue entrar em redes com a transmissão do SSID desligada digitando o nome exato, mas elas não aparecem nas varreduras; se tiver problemas, ligue a transmissão durante os testes.
Fonte de alimentação e brownout: por que a placa reinicia quando o Wi-Fi liga?
Um módulo ESP32 consome em média cerca de 80 mA, mas enquanto o transmissor Wi-Fi está ativo a corrente tem picos breves de 250–400 mA. Os maiores picos costumam acontecer durante a calibração do rádio na inicialização e durante a primeira conexão. Por isso a Espressif recomenda uma fonte capaz de fornecer pelo menos 500 mA. Se a fonte não acompanha esses picos, a linha de 3,3 V despenca por um instante, o detector de brownout do chip entra em ação e a placa reinicia com a mensagem Brownout detector was triggered no Monitor Serial. O sintoma é bem conhecido: o código roda bem até a linha do Wi-Fi, a placa reinicia em WiFi.begin() e isso vira um loop infinito. Tratamos esse erro em todos os detalhes no artigo sobre brownout e erros Guru Meditation no ESP32.

| Fonte de alimentação | Serve? | Por quê? |
|---|---|---|
| Porta USB na traseira do computador, cabo curto e grosso | Geralmente sim | Uma porta USB 2.0 fornece 500 mA; um cabo curto reduz a perda de tensão |
| USB do painel frontal, hub USB ou cabo longo e fino | Pode dar problema | A resistência do cabo e dos contatos derruba a tensão nos picos de corrente |
| Carregador de celular de 5 V com pelo menos 1 A | Sim | Deixa bastante folga para os picos de corrente |
| Pino 3.3V do Arduino Uno | Não | Esse pino só fornece cerca de 50 mA |
| Célula Li-ion de 3,7 V ligada direto no pino 5V da placa | Não | Por causa do dropout do AMS1117, a saída cai abaixo de 3 V |
| Célula Li-ion com conversor elevador (boost) de 5 V ou regulador de 3,3 V de baixo dropout (LDO) | Sim | Fornece 3,3 V estáveis mesmo enquanto a bateria descarrega |
| Saída de 3,3 V de um módulo de alimentação para protoboard MB102 | Na maioria das vezes, sim | Alimente-o com um adaptador com corrente suficiente e adicione um capacitor |
A solução setTxPower: reduzir a potência de transmissão
Em algumas placas, mesmo com uma boa fonte, o ESP32 enxerga a rede mas não consegue conectar, ou a conexão cai o tempo todo. Principalmente nas placas baratas ESP32-C3 Super Mini e em alguns clones de ESP32, o circuito da antena e o regulador sofrem na potência máxima de transmissão. Por padrão, o ESP32 transmite com cerca de 19,5–20 dBm. Reduzir esse valor com WiFi.setTxPower() diminui os picos de corrente e muitas vezes resolve a conexão nessas placas na hora. Chame logo depois de WiFi.begin(); não funciona se for chamado antes de o Wi-Fi ser iniciado, ou seja, antes de WiFi.mode() ou begin().
| Constante | Potência | Quando usar |
|---|---|---|
| WIFI_POWER_19_5dBm | 19,5 dBm | Perto do padrão; maior alcance |
| WIFI_POWER_15dBm | 15 dBm | Primeira tentativa para problemas leves |
| WIFI_POWER_11dBm | 11 dBm | Geralmente basta se o roteador está no mesmo cômodo |
| WIFI_POWER_8_5dBm | 8,5 dBm | O valor mais recomendado para o ESP32-C3 Super Mini |
| WIFI_POWER_5dBm | 5 dBm | Para testes bem ao lado do roteador |
Cada redução de 3 dB corta a potência de transmissão pela metade, então o alcance também diminui. Comece com 15 dBm; se o problema continuar, desça para 11 e depois para 8,5 dBm. Se reduzir a potência resolve a conexão, a causa real geralmente é a fonte de alimentação ou o projeto da antena; por isso, a longo prazo, adicione também uma fonte melhor e um capacitor. Você pode ler a configuração atual da placa com WiFi.getTxPower(); o valor vem em unidades de 0,25 dBm, então 78 significa 19,5 dBm.
Sketch de reconexão automática
O ESP32 perde a conexão quando o roteador reinicia, quando a energia volta depois de uma queda ou quando o sinal enfraquece por um tempo. No core ESP32, WiFi.setAutoReconnect(true) vem ligado por padrão, e depois da maioria das quedas a placa reconecta sozinha. Para alguns motivos, porém, como 202 AUTH_FAIL, o core desiste depois de uma única nova tentativa e a placa fica fora da rede até você reiniciá-la. Em um projeto que precisa rodar por meses, vale a pena acrescentar a sua própria verificação. O sketch abaixo evita delay() e usa millis() para verificar a conexão a cada 15 segundos, reconecta se ela caiu e reinicia a placa se não conseguir conectar por 5 minutos:
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}A linha WiFi.setSleep(false) desliga o modem sleep, modo em que o ESP32, mesmo conectado, desliga o rádio por breves intervalos. Isso reduz as quedas com alguns roteadores e a latência de um servidor web; em troca, a placa consome algumas dezenas de mA a mais. Em projetos a bateria, você pode remover essa linha e calcular quanto tempo a bateria vai durar com a calculadora Autonomia da bateria. Mantenha a linha do setTxPower só se você tiver os problemas da seção anterior. Ao adicionar o código do seu projeto ao loop(), evite delay() longos, porque a verificação da conexão só roda enquanto o loop() continua girando. Se preferir digitar os dados do Wi-Fi pelo celular em vez de deixá-los fixos no código, dê uma olhada na biblioteca WiFiManager.
IP estático no ESP32
Normalmente o roteador atribui ao ESP32, via DHCP, um endereço que pode mudar a cada vez. Se você está montando um servidor web que vai abrir sempre no mesmo endereço pelo celular, ou se o DHCP do roteador está com problema (o status fica travado em 0), um IP estático facilita a vida. Lembre-se de três regras: WiFi.config() precisa ser chamado antes de WiFi.begin(); o endereço escolhido precisa estar na rede do roteador, mas fora da faixa do DHCP (se o roteador distribui 192.168.1.2–100, use algo como 192.168.1.200); e o gateway é o endereço do próprio roteador. Para descobrir o endereço do seu roteador, rode o sketch de diagnóstico uma vez com DHCP; ele também imprime o 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() {}Redes de escola e de empresa: conectando ao WPA2-Enterprise (eduroam)
O eduroam das universidades, as redes de empresas e algumas redes de escola usam WPA2-Enterprise (802.1X), que dá a cada usuário seu próprio nome de usuário e senha em vez de uma única senha compartilhada. Um WiFi.begin(nome, senha) comum sempre falha nessas redes, e no scanner o tipo de segurança delas aparece como Diger / Other (Enterprise). As versões 2.x e 3.x do core ESP32 para Arduino oferecem uma forma pronta de begin() para o PEAP, o método mais comum:
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() {}Na maioria das instituições, a identidade (identity) é igual ao nome de usuário; algumas pedem uma identidade externa anônima, como [email protected]. Este sketch não valida o certificado do servidor (CA): a conexão funciona, mas um ponto de acesso falso poderia capturar a sua senha. Por isso, antes de colocar a sua senha pessoal em um ESP32, fale com o setor de TI e, se possível, peça uma conta ou uma rede destinada a dispositivos. Se a sua instituição exige certificado, você pode passar o arquivo da CA como sexto parâmetro de begin(). Redes que abrem uma página de login no navegador (captive portals), como em hotéis, alojamentos estudantis e cafés, são outro problema, porque o ESP32 não consegue preencher essa página. Algumas escolas também exigem que o endereço MAC dos dispositivos seja cadastrado antes; envie à TI o endereço MAC impresso pelo sketch de diagnóstico. Nessas redes, a solução mais prática é o hotspot do celular ou um pequeno roteador portátil.
Teste com o hotspot do celular: o problema é o roteador ou o ESP32?
A forma mais rápida de isolar a causa é conectar o ESP32 a uma rede cujas configurações você controla por completo. O hotspot do seu celular é perfeito para isso:
- Dê ao hotspot um nome curto, feito só de letras sem acento e números (por exemplo esptest), e defina uma senha simples de pelo menos 8 caracteres (por exemplo test12345).
- No Android, ajuste a opção de banda nas configurações do hotspot (chamada de Banda AP ou Velocidade e compatibilidade em alguns celulares) para 2,4 GHz e escolha WPA2-Personal como tipo de segurança.
- No iPhone, vá em Ajustes > Acesso Pessoal e ative Permitir Que Outros Acessem. Nos modelos mais novos, ative também Maximizar Compatibilidade; isso passa o hotspot para 2,4 GHz. O nome do hotspot é o nome do celular, então simplifique-o em Ajustes > Geral > Sobre > Nome e mantenha a tela de Acesso Pessoal aberta até o ESP32 conectar.
- Troque o nome da rede e a senha no sketch de diagnóstico pelos dados do hotspot, coloque o celular a 1–2 metros do ESP32 e carregue o sketch.
- Leia os códigos de status e reason no Monitor Serial e depois teste o mesmo sketch com os dados do roteador da sua casa.
Interprete o resultado assim: se o ESP32 conecta no hotspot, mas não no roteador de casa, o seu código, a placa e a fonte estão bem; o problema está nas configurações de banda, canal, segurança, filtro de MAC ou limite de clientes do roteador. Se ele também não conecta no hotspot, o problema está do lado do ESP32: troque a fonte e o cabo, reduza a potência com setTxPower, garanta que não há metal na frente da antena e revise o código. O teste com o hotspot também é o jeito mais rápido de provar que um projeto que não conecta na escola na verdade funciona.
Teste de Wi-Fi com Raspberry Pi Pico W e MicroPython
O Raspberry Pi Pico W e o Pico 2 W também suportam só 2,4 GHz; todas as dicas deste artigo sobre banda, senha, alimentação e hotspot valem também para essas placas. No MicroPython, os códigos de status são lidos com constantes do módulo network. O script abaixo roda sem alterações no Thonny, tanto no ESP32 quanto no Pico W. No Pico W, ele para de esperar na hora se a rede não for encontrada ou se a senha estiver errada; no ESP32, o MicroPython continua tentando depois de alguns erros, então o script imprime o último status após 20 segundos:
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)No Pico W, os valores numéricos de status são diferentes: 3 significa conectado com IP, 2 conectado mas esperando IP, -1 falha geral, -2 rede não encontrada e -3 senha errada. No ESP32, por outro lado, você verá 1001 durante a conexão, 1010 quando ele já tem IP e códigos reason do ESP-IDF, como 201 e 202, quando algo dá errado. Para evitar problemas com os canais 12 e 13 no Pico W, defina o código do seu país antes de conectar (rp2.country('BR'), ou network.country('BR') em firmwares mais novos; troque BR pelo código do seu país se não estiver no Brasil); se a conexão cair de vez em quando, você pode desligar a economia de energia com wlan.config(pm=0xa11140). Para montar um servidor web com o Pico W, veja o artigo servidor web Wi-Fi com Pico W e, se você está começando no MicroPython, dê uma olhada no guia fundamentos de MicroPython.
Problemas comuns e soluções
| Sintoma | Causa provável | Solução |
|---|---|---|
| Caracteres estranhos no Monitor Serial | Baud rate diferente | Ajuste o Monitor Serial para 115200 baud |
| Status 1 e reason 201 | Nome da rede errado, rede de 5 GHz ou longe demais | Rode o scanner e copie exatamente o nome da rede de 2,4 GHz |
| Status 6 e reason 15 repetidas vezes | Senha errada | Digite a senha de novo, prestando atenção a maiúsculas, minúsculas e caracteres especiais |
| Status 4 ou 6; reason 202, 210 ou 211 | Modo de segurança incompatível | Mude o roteador para WPA2-Personal (AES) ou para o modo misto WPA2/WPA3 |
| Travado no status 0 | Entrou no roteador, mas não recebe IP do DHCP | Reinicie o roteador, aumente a faixa do DHCP ou use IP estático |
| Reinicia em WiFi.begin() com Brownout detector was triggered | A fonte não aguenta os picos de corrente | Cabo curto, adaptador de pelo menos 1 A, 470 µF entre 3V3 e GND |
| Conecta e cai depois de alguns minutos (reason 200) | Sinal fraco, modem sleep ou problema de alimentação | setSleep(false), setTxPower, sketch de reconexão, aproximar do roteador |
| Funciona na bancada, mas não conecta dentro da caixa | Caixa metálica ou bateria na frente da antena | Posicione a antena na borda da caixa, voltada para fora, e use uma caixa plástica |
| Conectado, mas a página web não abre no celular | O celular está em outra rede, ou a rede de convidados usa isolamento de clientes | Conecte os dois à mesma rede e leia o IP no Monitor Serial |
| Os valores de analogRead() ficam errados quando o Wi-Fi liga | O sensor está em um pino do ADC2, e o Wi-Fi usa o ADC2 | Passe o sensor para os pinos do ADC1, GPIO 32–39 |
| Alcance de poucos centímetros em um ESP32-CAM ou em uma placa com antena externa | A seleção de antena está configurada para externa, mas não há antena instalada | Conecte uma antena no conector IPEX ou verifique o resistor de 0 Ω de seleção da antena na placa |
Conectou: o que dá para montar agora?
- Servidor web e painel ao vivo: Monte um servidor web com WebSocket no ESP32 que mostra os valores dos sensores no celular em tempo real.
- Relógio pela internet: Pegue a hora de um servidor NTP e mostre em um display.
- Display de previsão do tempo: Busque a temperatura e a umidade da sua cidade com uma API de previsão do tempo.
- Notificações no celular: Envie uma mensagem com um bot do Telegram quando a porta abrir.
- Casa inteligente: Conecte o ESP32 ao Home Assistant via MQTT.
- Comunicação sem roteador: Faça duas placas ESP32 conversarem com ESP-NOW sem entrar em nenhuma rede.
- Envio de código sem fio: Depois que a placa estiver fechada na caixa, envie código novo pelo Wi-Fi com uma atualização OTA.
Um ESP32 que não conecta ao Wi-Fi confunde no começo, mas os códigos de status e reason sempre dizem em qual etapa está o problema: 1 e 201 significam que a rede não foi encontrada, 15 e 202 apontam para a senha ou o modo de segurança, 0 para o DHCP, e 200 ou reinicializações repentinas para o sinal ou a fonte de alimentação. Se você está começando com o ESP32, encontra o básico em O que é o ESP32?. No app BlueGrays você também pode explorar projetos como conexão Wi-Fi com ESP32, servidor web, mDNS, relógio NTP, estação meteorológica, atualização OTA e alarme pelo Telegram, cada um com esquemas do circuito passo a passo e código pronto.
Perguntas frequentes
Por que meu ESP32 não conecta ao Wi-Fi?
As causas mais comuns são tentar entrar em uma rede de 5 GHz, um erro de digitação no nome da rede ou na senha, uma fonte fraca cuja tensão despenca quando o Wi-Fi liga e as configurações de segurança do roteador. Imprima o valor de WiFi.status() e o código reason informado na desconexão e você verá na hora qual é o caso. Se a rede não for encontrada, você verá 1 e 201; com senha errada, normalmente verá 6 e 15.
O ESP32 conecta em Wi-Fi de 5 GHz?
O ESP32 clássico, o ESP32-S2, o S3, o C3 e o C6 suportam só 2,4 GHz e nunca enxergam redes de 5 GHz em uma varredura. O modelo dual band é o ESP32-C5. Se o seu roteador transmite as duas bandas com nomes separados, informe ao ESP32 o nome da rede de 2,4 GHz.
O que significa WiFi.status() 6 no ESP32?
6 significa WL_DISCONNECTED: a placa não está conectada, e a tentativa de conexão ainda está em andamento ou falhou. No ESP32, uma senha errada muitas vezes dá esse valor em vez de 4 (WL_CONNECT_FAILED). Para ver a causa real, confira o código reason no evento ARDUINO_EVENT_WIFI_STA_DISCONNECTED.
Por que meu ESP32 fica desconectando do Wi-Fi?
As principais causas de quedas repetidas são sinal fraco, uma fonte que não aguenta os picos de corrente do Wi-Fi, metal ou bateria na frente da antena e as configurações de band steering do roteador. Aproxime a placa do roteador, adicione um capacitor de 100–470 µF entre 3V3 e GND e desligue o modem sleep com WiFi.setSleep(false). Escreva também o seu código para que ele se recupere sozinho de uma queda de conexão.
O ESP32 conecta no hotspot do celular?
Sim, desde que o hotspot transmita em 2,4 GHz. No Android, ajuste a banda do hotspot para 2,4 GHz; no iPhone, ative Maximizar Compatibilidade; e mantenha o nome do hotspot simples. O teste com o hotspot é o jeito mais rápido de saber se o problema está no roteador de casa ou no ESP32.
O ESP32 conecta no eduroam ou na rede da escola?
O ESP32 consegue entrar em redes WPA2-Enterprise como o eduroam usando a forma WiFi.begin(nome, WPA2_AUTH_PEAP, identidade, usuario, senha) do core ESP32 para Arduino. Em redes que abrem uma página de login no navegador (captive portals), porém, o ESP32 não consegue preencher essa página. O melhor é falar com o setor de TI antes de usar uma rede institucional e, se possível, pedir uma conta separada para dispositivos.
Projetos para montar depois desta leitura
Ver todos os projetos
Conexão Wi-Fi STA com ESP32 e display LCD
Neste projeto, conectamos o ESP32 à rede Wi-Fi de casa no modo estação (STA), de forma segura e tolerante a falhas. Guardamos o SSID e a senha em um arquivo secrets.h separado para evitar que sejam expostos no Git, configuramos um mecanismo de reconexão automática e exibimos o nível de sinal RSSI e o endereço IP em um display LCD I2C. O LED integrado funciona como indicador de status. É um gerenciador de conexão pronto para uso em produção.

Servidor web assíncrono com ESP32 (IP no LCD)
Neste projeto, transformamos o ESP32 em um servidor web assíncrono que você pode controlar pelo celular ou computador na mesma rede Wi-Fi. Com a biblioteca ESPAsyncWebServer, o servidor processa várias requisições ao mesmo tempo (ao contrário do WebServer.h tradicional, que bloqueia a execução ao processar uma requisição). Você poderá abrir o endereço IP do ESP32 no navegador e clicar nos botões ON/OFF (as rotas /on e /off) para ligar e desligar o LED conectado ao GPIO 5.

ESP32 mDNS: acesso via bluegrays-esp.local (com display LCD)
Neste projeto, adicionamos o serviço mDNS (Multicast DNS) ao ESP32 para acessar o dispositivo por um nome de host fácil de ler, como bluegrays-esp.local, em vez de um endereço IP. Mesmo que o IP atribuído pelo DHCP mude, você pode acessar o dispositivo pelo mesmo nome. Também executamos um pequeno servidor web no dispositivo para enviar comandos de controle do LED pelo navegador no endereço http://bluegrays-esp.local/.

Hora exata pela internet com ESP32 e NTP
O ESP32 se conecta ao Wi-Fi e obtém a hora exata com precisão de milissegundos de servidores NTP (Network Time Protocol). Com a função configTzTime(), o fuso horário configurado (TRT, UTC+3 neste exemplo) é aplicado automaticamente, e as mudanças nos países que adotam horário de verão são gerenciadas automaticamente por uma string POSIX TZ. A hora é exibida tanto no Monitor Serial quanto em um LCD I2C opcional.

ESP32 HTTPClient + API de clima (com display LCD)
Neste projeto, usamos o ESP32 para fazer uma chamada REST à API de clima wttr.in pela internet com HTTPClient.h. Interpretamos a resposta JSON com ArduinoJson v7 e mostramos cidade, temperatura, umidade, condições do tempo e vento em um display LCD I2C, em turco e inglês. O wttr.in é grátis e não exige chave de API — basta informar o nome de uma cidade para consultar o clima atual. Os dados se atualizam sozinhos a cada 30 minutos, e o LED dá um retorno visual diferente para cada tela.

Atualização OTA no ESP32 — firmware sem fio (com display LCD)
Neste projeto, você aprende a carregar um novo firmware no ESP32 por Wi-Fi, sem cabo USB. Com a biblioteca ArduinoOTA, o ESP32 fica visível na rede e aparece automaticamente como bluegrays-ota na aba "Porta de rede" do Arduino IDE. A primeira carga é feita por USB, e todas as atualizações seguintes são sem fio — um recurso essencial para dispositivos em campo. O LCD I2C mostra o estado do Wi-Fi, o IP, o nome do host, a porcentagem de envio por OTA e as mensagens de erro em turco e inglês.

Contador WebSocket com ESP32 (2 botões + LCD + web em tempo real)
Neste projeto, dois botões conectados ao ESP32 (GPIO 5 aumenta, GPIO 4 diminui) alteram um contador. O valor é atualizado instantaneamente no LCD I2C 16x2 e, com o suporte a WebSocket do ESPAsyncWebServer, em todos os navegadores conectados, sem recarregar a página. Em vez de consultas periódicas por HTTP, usamos uma única conexão persistente, e o ESP32 envia o novo valor a todos com ws.textAll().

Alarme de movimento com ESP32 (PIR + buzzer + LED + Telegram)
Um sistema de alarme de segurança inteligente que aciona o buzzer e o LED quando o sensor PIR detecta movimento e, ao mesmo tempo, envia uma notificação instantânea ao proprietário pelo Telegram. Inclui um intervalo de espera de 30 segundos para limitar a frequência dos alarmes repetidos; esse mecanismo não valida as detecções do PIR nem elimina disparos falsos. Pode ser usado na segurança de casas, no monitoramento de garagens, depósitos ou salas de trabalho.
Mais artigos
App BlueGrays
Monte este circuito passo a passo pelo celular
Esquema do circuito, código e lista de componentes em uma só tela. Mais de 200 projetos com Arduino, ESP32 e Pico prontos para montar.
Escaneie com seu celular
Aponte a câmera para o código para abrir a loja de aplicativos do seu celular.
ou abrir a loja

