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:

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!

4.9/5 - (8 votos)

Related posts

Comunicação com Arduino Ethernet shield W5100

by Arduino e Cia
11 anos ago

Digispark ATtiny85 com display OLED I2C

by Arduino e Cia
7 anos ago

Comunicação wireless com Arduino e módulo NRF24L01

by Arduino e Cia
10 anos ago
Sair da versão mobile