ESP-NOW: Comunicação direta entre módulos ESP8266 e ESP32
Comunicação sem fio direta entre módulos ESP8266 e ESP32: esse é o ESP-NOW, um protocolo desenvolvido pela Espressif e que pode ser um importante aliado no seu projeto de automação e IoT.
Vamos ver como isso funciona e montar um teste básico de comunicação usando essa tecnologia.
O que é o ESP-NOW
O ESP-NOW é um protocolo de comunicação sem fio desenvolvido pela Espressif e que permite a comunicação entre dispositivos ESP – sejam eles ESP8266 ou ESP32 – sem que seja necessária a conexão dos módulos na rede wifi convencional usando SSID e a senha.
Ou seja, a comunicação é direta, sem intermediários: não é necessário conectar o ESP em um roteador, e os dados são enviados diretamente de um módulo para o outro.
Por ser um protocolo que permite uma rápida comunicação e segurança através de criptografia, o ESP-NOW pode ser utilizado em uma infinidade de projetos de automação residencial, IoT (Internet of Things ou Internet das Coisas), controle remoto de dispositivos, monitoramento de sensores e outras aplicações.
A comunicação não precisa ser feita apenas entre 2 módulos: você pode ter um ESP “central” enviando ou recebendo dados de vários outros módulos ao mesmo tempo. Não existe a princípio o conceito de cliente/servidor, então cada ESP pode ser emissor e receptor ao mesmo tempo.
Uma observação importante sobre o ESP-NOW é a limitação quanto ao tamanho da mensagem enviada, que deve ter no máximo 250 bytes.
Como vamos testar o ESP-NOW
Neste post vamos testar a comunicação usando ESP-NOW com dois módulos ESP. Vamos usar:
- 02 Módulos ESP8266 NodeMCU
- 01 Push Button
- 01 Led
- 02 Resistores
Um módulo que vamos chamar de EMISSOR terá um botão tipo push-button no circuito, que ao ser acionado vai enviar uma string (uma palavra/texto) para o módulo RECEPTOR, que por sua vez vai acionar um led conforme o dado recebido.
Conexões e circuito
O NodeMCU que será o EMISSOR tem um push-button conectado na porta D2.
Um resistor de 1K serve de pull-down, mantendo o sinal em nível baixo (LOW) enquanto o botão não estiver sendo acionado:
No circuito do RECEPTOR temos um led conectado na porta D1. Usamos um resistor de 330 ohms como limitador de corrente:
Como podem notar o circuito é bem simples, agora vamos para a parte de configuração e programação.
Preparando a IDE para programar o NodeMCU
Antes da programação, vamos preparar a IDE do Arduino para que o módulo ESP8266 seja reconhecido.
Dentro da IDE, acesse o menu Arquivo e em seguida Preferências. No campo URLs Adicionais para Gerenciadores de placas, coloque a URL abaixo:
http://arduino.esp8266.com/stable/package_esp8266com_index.json
Clique em OK e acesse o menu Ferramentas -> Placa -> Gerenciador de Placas. Na tela do gerenciador procure por ESP8266 e selecione esp8266 by ESP8266 Community, clicando em seguida em instalar:
As placas da linha ESP8266 aparecerão na lista de placas disponíveis. Agora basta você selecionar NodeMCU 1.0 (ESP-12E Module) como mostra a imagem abaixo:
Não esqueça de selecionar a porta serial (COM) correta no menu Ferramentas ao programar cada placa. Como você vai trabalhar com duas placas, é muito comum mandar o programa para o módulo errado, portanto atenção na hora de compilar e transferir cada programa.
Descobrindo o endereço MAC do ESP8266
O que precisamos fazer agora é descobrir o endereço MAC (MAC address) do NodeMCU Receptor. É por meio desse endereço que o ESP-NOW vai saber para onde mandar a mensagem com os dados, ou seja, quem será o destinatário da mensagem.
Carregue o programa abaixo no Receptor:
//Programa: Mostra endereco MAC do modulo ESP8266 //Autor: Arduino e Cia #include <ESP8266WiFi.h> void setup() { Serial.begin(115200); delay(500); Serial.println(); Serial.print("Endereco MAC: "); Serial.println(WiFi.macAddress()); } void loop() {}
O programa é bem simples e usa o método macAddress() para mostrar o endereço no monitor serial da IDE:
Vamos anotar esse endereço pois vamos usá-lo logo abaixo no programa emissor.
Programa ESP8266 Emissor ESP-NOW
No programa do Emissor temos a definição da biblioteca do ESP-NOW na linha 5, que é ligeiramente diferente se você for usar o ESP32 (ao invés de espnow.h teremos esp_now.h), mas isso é assunto para um outro post.
Na linha 8 vamos colocar o endereço MAC (Mac Address) do destinatário das mensagens, no caso o endereço 60:01:94:0A:87:72 que vimos anteriormente.
Na linha 11 montamos a estrutura da mensagem, que no nosso caso só vai conter uma String, mas é possível colocar valores inteiros (INT), char, boolean, etc.
//Programa: ESP-NOW com ESP8266 NodeMCU - Emissor //Autor: Arduino e Cia #include <ESP8266WiFi.h> #include <espnow.h> //Coloque na linha abaixo o Mac Address do NodeMCU receptor uint8_t broadcastAddress[] = {0x60, 0x01, 0x94, 0x0A, 0x87, 0x72}; //Estrutura para envio dos dados. Deve ser a mesma tanto no emissor como no receptor. typedef struct struct_message { String a; } struct_message; //Definicoes botao #define pino_botao D2 bool inverte_led = 0; int valor; //Cria uma struct_message chamada myData struct_message myData; //Callback quando os dados sao enviados void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) { Serial.print("Status dos dados enviados: "); if (sendStatus == 0) { Serial.println("Envio ok!"); } else { Serial.println("Falha no envio!"); } } void setup() { Serial.begin(115200); //Inicializa o pino do botao pinMode(pino_botao, INPUT); //Coloca o dispositivo no modo Wi-Fi Station WiFi.mode(WIFI_STA); //Inicializa o ESP-NOW if (esp_now_init() != 0) { Serial.println("Erro ao inicializar o ESP-NOW"); return; } esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER); esp_now_register_send_cb(OnDataSent); //Registra o destinatario da mensagem esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0); } void loop() { valor = digitalRead(pino_botao); if (valor == 1) { while (digitalRead(pino_botao) == 1) { delay(50); } Serial.println("Botao pressionado!"); //Inverte o estado do led inverte_led = !inverte_led; //Envia a string de acordo com o estado do led if (inverte_led == 1) { myData.a = "L_Led"; } if (inverte_led == 0) { myData.a = "D_Led"; } //Envia a mensagem usando o ESP-NOW esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData)); } }
Ao executar o programa o mesmo aguarda o acionamento do botão e envia L_Led para ligar ou D_Led para desligar o led.
Você pode acompanhar o status do acionamento do botão no monitor serial, assim como o status do envio da mensagem:
Vamos agora para o programa do receptor.
Programa ESP8266 receptor
O programa receptor é bem parecido com o emissor, e você não precisa alterar nada nele.
Basicamente o programa checa o recebimento das mensagens via ESP-NOW e liga ou desliga o led de acordo com a string recebida.
//Programa: ESP-NOW com ESP8266 NodeMCU - Receptor //Autor: Arduino e Cia #include <ESP8266WiFi.h> #include <espnow.h> //Estrutura para envio dos dados. Deve ser a mesma tanto no emissor como no receptor. typedef struct struct_message { String a; } struct_message; //Definicoes led #define pino_led D1 //Cria uma struct_message chamada myData struct_message myData; //Funcao de Callback executada quando a mensagem for recebida void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) { memcpy(&myData, incomingData, sizeof(myData)); Serial.println(); Serial.print("Bytes recebidos: "); Serial.println(len); Serial.print("String: "); Serial.println(myData.a); String dado_recebido = myData.a; //Acende ou apaga o led de acordo com a String recebida if (dado_recebido == "L_Led") { Serial.println("Recebido Liga Led!"); digitalWrite(pino_led, LOW); } if (dado_recebido == "D_Led") { Serial.println("Recebido Desliga Led!"); digitalWrite(pino_led, HIGH); } } void setup() { Serial.begin(115200); pinMode(pino_led, OUTPUT); digitalWrite(pino_led, HIGH); //Coloca o dispositivo no modo Wi-Fi Station WiFi.mode(WIFI_STA); //Inicializa o ESP-NOW if (esp_now_init() != 0) { Serial.println("Erro ao inicializar o ESP-NOW"); return; } esp_now_set_self_role(ESP_NOW_ROLE_SLAVE); esp_now_register_recv_cb(OnDataRecv); } void loop() { //Neste programa nao temos comandos no loop }
Você também pode acompanhar a recepção das mensagens pelo Monitor Serial da IDE do Arduino.
Neste caso, abra uma segunda instância da IDE (um segundo programa), configure a porta serial do ESP Receptor e acompanhe o recebimento dos dados:
Em um próximo artigo sobre o ESP-NOW vamos ver como utilizar o protocolo com ESP32.
Gostou? Confira outros posts usando ESP8266 NodeMCU aqui mesmo no Arduino e Cia!
Olá! Tudo bem?
Estou estruturando o protocolo Esp now no esp32! Alguma notícias sobre quando sai o post sobre esse esp?
Desde já, muito obrigado!
Oi Pedro,
Estou programando esse post para o começo de dezembro, blz?
Abraço!
Adilson
Fala meu amigo, faça um vídeo demonstrando, ia ser muito mais rico, para o aprendizado, meise mesmo assim esse tutorial está top!
Boa noite, primeiro post que acho onde se encaixa na minha necessidade, preciso criar um web server com um esp e através desse web server, enviar comando para outros EsP, consegue me ajudar ?
Olá. Gostaria de saber se há alguma publicação com Esp8862, usando o espnow para fazer o ponto-a-ponte entre dois esp8862 utilizando 3 botões no emissor e 3 leds no receptor.. Preciso do código. Ou onde compro este serviço.
Olá, você teria o código semelhante a esse, porém para uso no ESP32?
E poderia disponibilizar as bibliotecas
bom dia,
esse projeto se aplica ao Modulo ESP8266-01?!
Oi Lucas,
Funciona com ESP-01 sim.
Abraço!
Adilson
Saudaçoes
só posso usar ESPNOW em modo ST?
Eu tenho um sistema que eu uso para programr uma pagina web, com campos variaveis que defino antes de executar o programa, uso Little fs, programo as variaveis por wifi modo AP, nesses caso nao posso usar ST?
Oi Carlos,
Vou ver se acho algo na documentação, mas acho que funcionam apenas no modo ST, já que criam uma rede própria para comunicação.
Abraço!
Adilson