Como programar o ESP32 por Wifi usando OTA
Não seria ótimo se livrar dos cabos e programar o seu módulo ESP32 por wifi? Isso é possível com o OTA (Over-The-Air), um modo de programação onde você utiliza a rede wireless para transferir remotamente o sketch (programa) para a sua placa.
O uso do OTA leva os seu projeto de Internet das Coisas (IoT) para um outro patamar, minimizando erros causados por remontagem de circuitos e permitindo a atualização de um programa em poucos minutos.
O que é e por que você precisa do OTA
O OTA está disponível em várias placas do mercado, como a linha ESP8266 e a ESP32, e permite que você (re)programe o módulo remotamente via wifi, sem a necessidade de conectar o módulo em um computador.
Isso é muito útil quando o módulo está em um local de difícil acesso e você precisa alterar alguma coisa na programação. Em condições “normais”, você teria que retirar por exemplo o ESP32 do circuito, conectá-lo em um computador, reprogramá-lo e depois devolver o módulo para o circuito.
Um grande transtorno se o seu módulo estiver dentro de algum equipamento, no meio de uma plantação coletando dados ou em algum outro local onde montar e desmontar um circuito não seja uma tarefa fácil.
Com o OTA, basta que o módulo esteja na mesma rede do computador, e toda a programação será feita via rede wireless.
Preparação do módulo ESP32 na IDE Arduino
Antes de mais nada, precisamos preparar a IDE do Arduino para utilização com o ESP32. Entre na IDE e no menu Arquivo -> Preferências, adicione a URL abaixo no campo URLs Adicionais para Gerenciadores de Placas:
https://dl.espressif.com/dl/package_esp32_index.json
Sua tela ficará assim:
Clique em OK e em seguida vá até o menu Ferramentas -> Placa -> Gerenciador de Placas e procure por ESP32, selecionando ESP32 by Espressif Systems e clique em Instalar:
Aguarde alguns instantes e as placas da linha ESP32 serão instaladas na IDE do Arduino. Novamente no menu Ferramentas -> Placa, selecione agora ESP32 Dev Module, conforme a imagem abaixo:
Com a seleção desta placa, serão adicionados novos exemplos na IDE do Arduino específicos para utilização com o ESP32.
Atenção: Recomendo a instalação do Python e da biblioteca pyserial para evitar erros de compilação do programa. A versão mais recente do Python para instalação você encontra neste link. Caso ainda esteja enfrentando problemas, recomendo seguir o tutorial Como programar o módulo ESP32 com IDE Arduino aqui mesmo no Arduino e Cia.
Carregando o BasicOTA no módulo ESP32 wifi
Um desses exemplos é o que vamos utilizar para configurar o módulo ESP32 para que ele fique “esperando” uma conexão via rede wifi para atualização do programa. Esse exemplo é o BasicOTA, e você pode carregá-lo no menu Arquivo -> Exemplos -> ArduinoOTA -> BasicOTA:
No programa BasicOTA, que eu reproduzo abaixo, configure nas linhas 6 e 7 o nome e senha, respectivamente, da sua rede wifi. É a única alteração no programa:
#include <WiFi.h> #include <ESPmDNS.h> #include <WiFiUdp.h> #include <ArduinoOTA.h> const char* ssid = "SUA-REDE-WIFI"; const char* password = "SUA-SENHA-WIFI-AQUI"; void setup() { Serial.begin(115200); Serial.println("Booting"); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.waitForConnectResult() != WL_CONNECTED) { Serial.println("Connection Failed! Rebooting..."); delay(5000); ESP.restart(); } // Port defaults to 3232 // ArduinoOTA.setPort(3232); // Hostname defaults to esp3232-[MAC] // ArduinoOTA.setHostname("myesp32"); // No authentication by default // ArduinoOTA.setPassword("admin"); // Password can be set with it's md5 value as well // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3 // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3"); ArduinoOTA .onStart([]() { String type; if (ArduinoOTA.getCommand() == U_FLASH) type = "sketch"; else // U_SPIFFS type = "filesystem"; // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() Serial.println("Start updating " + type); }) .onEnd([]() { Serial.println("nEnd"); }) .onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%r", (progress / (total / 100))); }) .onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); }); ArduinoOTA.begin(); Serial.println("Ready"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void loop() { ArduinoOTA.handle(); }
Observe que nessa parte ainda estamos com o módulo fisicamente conectado no computador, acessando o ESP32 via porta serial (COM). Transfira então o BasicOTA normalmente para o módulo. Não esqueça que em alguns módulos é necessário manter pressionado o botão BOOT para que o programa seja transferido corretamente.
Reinicie o ESP32 (no meu módulo, é o botão EN) e aguarde o processo de configuração, que pode ser acompanhado pelo serial monitor:
Na última linha mostrada na imagem acima, temos o endereço IP que foi obtido pelo ESP32: 192.168.0.124.
Programando o ESP32 por Wifi usando OTA
Agora vamos desconectar o módulo ESP32 do computador e transferir um programa remotamente. Alimente o módulo com uma fonte externa (uma fonte de telefone celular, por exemplo).
Abra a IDE do Arduino e no menu Ferramentas -> Porta, observe que foi adicionada uma porta de rede com o endereço IP obtido anteriormente:
Selecione essa porta e carregue o programa abaixo na IDE. O grande “segredo” deste programa é a manutenção da estrutura usada anteriormente no BasicOTA, onde vamos manter as chamadas das bibliotecas, as configurações de acesso a rede wifi (para que o módulo permaneça conectado) e também as chamadas para o ArduinoOTA, que fará com que o ESP32 continue aguardando o carregamento de novos programas quando for necessário.
Temos então o mesmo programa usado anteriormente, mas agora com as configurações para que o led onboard do ESP32 pisque em intervalos regulares. Acrescentamos:
- Na linha 10 a definição da porta 2 como saída
- Dentro do loop, entre as linhas 69 e 72, a rotina para que o led acenda e apague em intervalos de 1 segundo
Nosso programa então fica assim. Não esqueça de novamente colocar o nome e senha da sua rede wifi nas linhas 6 e 7:
#include <WiFi.h> #include <ESPmDNS.h> #include <WiFiUdp.h> #include <ArduinoOTA.h> const char* ssid = "SUA-REDE-WIFI"; const char* password = "SUA-SENHA-WIFI-AQUI"; void setup() { pinMode(2, OUTPUT); //Linha incluida Serial.begin(115200); Serial.println("Booting"); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.waitForConnectResult() != WL_CONNECTED) { Serial.println("Connection Failed! Rebooting..."); delay(5000); ESP.restart(); } // Port defaults to 3232 // ArduinoOTA.setPort(3232); // Hostname defaults to esp3232-[MAC] // ArduinoOTA.setHostname("myesp32"); // No authentication by default // ArduinoOTA.setPassword("admin"); // Password can be set with it's md5 value as well // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3 // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3"); ArduinoOTA .onStart([]() { String type; if (ArduinoOTA.getCommand() == U_FLASH) type = "sketch"; else // U_SPIFFS type = "filesystem"; // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() Serial.println("Start updating " + type); }) .onEnd([]() { Serial.println("nEnd"); }) .onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%r", (progress / (total / 100))); }) .onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); }); ArduinoOTA.begin(); Serial.println("Ready"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void loop() { ArduinoOTA.handle(); digitalWrite(2, HIGH); //Linha incluida delay(1000); //Linha incluida digitalWrite(2, LOW); //Linha incluida delay(1000); //Linha incluida }
Se você estiver usando Windows, na primeira vez que você tentar transferir o programa ele vai mostrar um aviso do firewall, indicando que o espota.exe está tentando acessar a rede. No nosso caso habilitamos as opções de acesso a rede pública e privada e selecionamos Allow Access (Permitir Acesso):
Por causa desse aviso, a IDE do Arduino pode mostrar uma mensagem de erro. Observe que no lado inferior direito da IDE estamos usando como porta para transferência o IP 192.168.0.124:
Refaça o procedimento de upload do programa, e se tudo estiver ok, o programa será carregado corretamente e o led onboard do módulo ESP32 começara a piscar:
Gostou? Confira outros posts com módulo ESP32 Wifi aqui mesmo no Arduino e Cia!
Qual seu email para contratar sua consultoria? Trata-se de algo simples e que não estou conseguindo fazer com motor de passo.
Oi Gustavo,
Utilize o formulário de contato no lado direito da página, por favor. Daí conversamos.
Abraço e obrigado!
Adilson
O ESP obteve o IP , contudo na IDE Arduino no menu Ferramentas -> Porta , não aparece o item portas de rede com o IP obtido .Porque será? Só aparece portas seriais !!!
Estou com mesmo problema
É provável que falte a parte do Python, muitos tutoriais da internet estão contando somente parte da receita do bolo, alguns nem tem os endereços das bibliotecas: https://www.makerhero.com/blog/programacao-esp8266-ota-wifi/
Bom dia,
Muito obrigado pela contribuição. Realmente tinha esquecido desse detalhe, pois já tinha o Python instalado na minha máquina.
Texto do post atualizado.
Abraço!
Adilson
Olá, primeiramente, obrigado pelo tutorial.
A principio, qdo eu carreguei o primeiro código com o BasicOTA, ele mostrou o endereço IP do ESP na aba Porta da IDE do Arduino, então carreguei com sucesso um outro código com as funções OTA via WiFi. No dia seguinte, abri a IDE do Arduino mas, o IP já não aparece mais na porta. Fui na placa ESP e apertei o botão RST mas, nada. Será que isso tem a ver com o Windows Defender Firewall? Se sim, como liberar porta? Obrigado
Oi Daniel!
Tudo bem? Entendi. Ele pode ter pego outro IP do roteador.. vc tentou subir o BasicOta novamente para o ESP?
Abraço!
Adilson
Mas se a ideia é reprogramar remotamente, cada ESP32 vai estar em locais diferentes e com WiFi diferentes portanto com senhas dos clientes, que eu não posso saber. Como resolve isso ? Eu preciso apenas enviar remotamente um ou mais textos que serão usados no programa, não necessariamente mudar o programa todo. Tem como fazer isso ?
Oi Anibal,
Entendi. Bom, existem algumas maneiras de resolver isso, dependendo do circuito usado. Você pode por exemplo usar os dados gravados em um cartão SD (ok, não seria uma atualização remota) ou então usar mensagens MQTT com um canal restrito. O ESP32 iria ler esse canal de tempos em tempos e se houver alguma alteração ele grava isso em memória EEPROM. São alguams ideias.
Abraço!
Adilson
Bom dia. Obrigado pelo tutorial.
Eu tô montando um carrinho autônomo. Queira usar o código OTA para alterar o código pelo wi-fi, só as biblioteca e o código OTA já ocupa toda a memória do esp . Não sei se é alguma configuração.