Etiquetas: ,

,O NodeMCU ESP32 é um pequeno microcontrolador com um chip WiFi. É possível estabelecer uma comunicação entre dois ESP32 quando estes estão ligados à mesma rede. Neste tutorial, vamos analisar uma arquitetura principal.

Hardware

  • Computador
  • NodeMCU ESP32 x2 ou mais
  • Cabo USB A macho

Configurar o servidor com um endereço IP fixo

Em alguns casos, como na criação de um servidor, é necessário especificar um endereço IP específico para o microcontrolador. É possível definir um endereço fixo nos ESP32s especificando os endereços IP de gateway e de sub-rede.

No prompt de comando, digite arp -a para exibir os endereços IP já em uso na sua rede. Escolha um endereço que não esteja na lista (por exemplo, 192.168.1.103)

windows-cmd-prompt-terminal-get-available-ip Comunicação entre dois ESP32s via WiFi

Em seguida, digite ipconfig para obter os endereços IP correspondentes ao seu router.

window-ipconfig-ip-subnet-gateway Comunicação entre dois ESP32s via WiFi

Inicialize os vários endereços IP no código Arduino (não se esqueça de substituir estes endereços pelos que aparecem no seu computador).

IPAddress ip(192, 168, 1,103 );
IPAddress gateway(192, 168, 1, 254);
IPAddress subnet(255, 255, 255, 0);

Em seguida, pode configurar a ligação Wi-Fi antes de a inicializar

WiFi.config(ip, gateway, subnet); // Static IP setup
WiFi.begin(ssid, password);
arduino-monitor-ip-fix Comunicação entre dois ESP32s via WiFi

Código mestre do ESP32

Para o microcontrolador mestre, vamos criar um servidor para gerir os pedidos do navegador, a interface Web e os pedidos dos microcontroladores escravos. Estamos a utilizar a biblioteca WiFi.h, que gere o chip WiFi para as placas ESP32.

Nota: Não se esqueça de alterar os valores ssid e password para o nome e password da rede wifi que pretende utilizar.

//Libraries
#include <WiFi.h>

//Constants
#define NUM_SLAVES 1
#define LED 2

//Parameters
String nom = "Master";
const char* ssid = "*******";
const char* password = "**********";

//Variables
bool sendCmd = false;
String slaveCmd = "0";
String slaveState = "0";

//Objects
WiFiServer server(80);
WiFiClient browser;
IPAddress ip(192, 168, 1, 44);
IPAddress gateway(192, 168, 1, 254);
IPAddress subnet(255, 255, 255, 0);

void setup() {
  //Init Serial USB
  Serial.begin(115200);
  Serial.println(F("Initialize System"));
  //Init ESP32 Wifi
  WiFi.config(ip, gateway, subnet);       // forces to use the fix IP
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(F("."));
  }
  server.begin();
  Serial.print(nom);
  Serial.print(F(" connected to Wifi! IP address : http://")); Serial.println(WiFi.localIP()); // Print the IP address
  pinMode(LED, OUTPUT);
}

void loop() {
  clientRequest();
}

void clientRequest( ) { /* function clientRequest */
  ////Check if client connected
  WiFiClient client = server.available();
  client.setTimeout(50);
  if (client) {
    if (client.connected()) {
      //Print client IP address
      Serial.print(" ->");Serial.println(client.remoteIP());
      String request = client.readStringUntil('\r'); //receives the message from the client
      
      if (request.indexOf("Slave0") == 0) {
        //Handle slave request
        Serial.print("From "); Serial.println(request);
        int index = request.indexOf(":");
        String slaveid = request.substring(0, index);
        slaveState = request.substring(request.indexOf("x") + 1, request.length());
        Serial.print("state received: "); Serial.println(slaveState);
        client.print(nom);
        if (sendCmd) {
          sendCmd = false;
          client.println(": Ok " + slaveid + "! Set state to x" + String(slaveCmd) + "\r");
        } else {
          client.println(": Hi " + slaveid + "!\r"); // sends the answer to the client
        }
        client.stop();                // terminates the connection with the client
      } else {
        Serial.print("From Browser : "); Serial.println(request);
       
        handleRequest(request);
        webpage(client);
      }
    }
  }
}

void handleRequest(String request) { /* function handleRequest */
  ////Check if client connected
  if (request.indexOf("/light1on") > 0)  {
    digitalWrite(LED, LOW);
  }
  if (request.indexOf("/light1off") > 0)  {
    digitalWrite(LED, HIGH);
  }
  if (request.indexOf("/light2on") > 0)  {
    sendCmd = true;
    slaveCmd = "1";
  }
  if (request.indexOf("/light2off") > 0)  {
    sendCmd = true;
    slaveCmd = "0";
  }
}

void webpage(WiFiClient browser) { /* function webpage */
  ////Send webpage to browser
  browser.println("HTTP/1.1 200 OK");
  browser.println("Content-Type: text/html");
  browser.println(""); //  do not forget this one
  browser.println("<!DOCTYPE HTML>");
  browser.println("<html>");
  browser.println("<head>");
  browser.println("<meta name='apple-mobile-web-app-capable' content='yes' />");
  browser.println("<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />");
  browser.println("</head>");
  browser.println("<body style = ' background-color:#000000; color:white;'>");
  browser.println("<hr/><hr>");
  browser.println("<h1><center> Esp32 Electrical Device Control </center></h1>");
  browser.println("<hr/><hr>");
  browser.println("<br><br>");
  browser.println("<br><br>");
  browser.println("<h2> Commands </h2>");
  browser.println("<center>");
  browser.println("Built-in LED");
  browser.println("<a href='/light1on'><button>Turn On </button></a>");
  browser.println("<a href='/light1off'><button>Turn Off </button></a><br />");
  browser.println("</center>");
  browser.println("<br><br>");
  browser.println("<center>");
  browser.println("Device 2");
  browser.println("<a href='/light2on'><button>Turn On </button></a>");
  browser.println("<a href='/light2off'><button>Turn Off </button></a><br />");
  browser.println("</center>");
  browser.println("<br><br>");
  browser.println("<br><br>");
  browser.println("<h2> Data </h2>");
  browser.println("<center>");
  browser.println("<table border='5'>");
  browser.println("<tr>");
  if (digitalRead(LED))
  {
    browser.print("<td>LED is OFF</td>");
  }
  else
  {
    browser.print("<td>LED is ON</td>");
  }
  browser.println("<br />");
  if (slaveState == "1") //(digitalRead(4))
  {
    browser.print("<td>Light 2 is OFF</td>");
  }
  else
  {
    browser.print("<td>Light 2 is ON</td>");
  }
  browser.println("</tr>");
  browser.println("</table>");
  browser.println("</center>");
  browser.println("</body></html>");
  delay(1);
}

Código escravo ESP32

No código slave, vamos ligar-nos ao servidor utilizando o endereço IP anteriormente utilizado.

N.B.: Não se esqueça de modificar e utilizar os mesmos valores de ssid e palavra-passe que no módulo Master, para que as duas placas ESP32 estejam ligadas à mesma rede.

//Libraries
#include <WiFi.h>

//Constants
#define LED 2
#define UPDATE_TIME 500

//Parameters
String nom = "Slave0";
const char* ssid = "*******";
const char* password = "*******";

//Variables
String command;
unsigned long previousRequest = 0;

//Objects
WiFiClient master;
IPAddress server(192, 168, 1, 44);

void setup() {
  //Init Serial USB
  Serial.begin(115200);
  Serial.println(F("Initialize System"));
  //Init ESP32 Wifi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(F("."));
  }
  Serial.print(nom);
  Serial.print(F(" connected to Wifi! IP address : ")); Serial.println(WiFi.localIP()); // Print the IP address
  pinMode(LED, OUTPUT);
}

void loop() {
  requestMaster();
}

void requestMaster( ) { /* function requestMaster */
  ////Request to master
  if ((millis() - previousRequest) > UPDATE_TIME) { // client connect to server every 500ms
    previousRequest = millis();

    if (master.connect(server, 80)) { // Connection to the server
      master.println(nom + ": Hello! my current state is x" + String(!digitalRead(LED)) + "\r");

      //answer
      String answer = master.readStringUntil('\r');   // receives the answer from the sever
      master.flush();
      Serial.println("from " + answer);
      if (answer.indexOf("x") >= 0) {
        command = answer.substring(answer.indexOf("x") + 1, answer.length());
        Serial.print("command received: "); Serial.println(command);
        if (command == "1") {
          Serial.println("LED ON");
          digitalWrite(LED, LOW);
        } else {
          Serial.println("LED OFF");
          digitalWrite(LED, HIGH);
        }
      }
    }
  }
}



Resultados

Quando os microcontroladores estão ligados ao Wi-Fi e a comunicação entre os dois ESP32 é estabelecida, podemos ver que são trocadas informações e comandos entre as duas placas. Também é possível controlar os LEDs das duas placas utilizando os botões da interface.

nodemcu-esp32-web-insterface Comunicação entre dois ESP32s via WiFi
nodemcu-esp32-master-monitor Comunicação entre dois ESP32s via WiFi
nodemcu-esp32-slave-monitor Comunicação entre dois ESP32s via WiFi

Neste tutorial, vimos como fazer com que dois ESP32s se comuniquem na rede Wifi local. Também é possível reproduzir este tutorial utilizando a placa ESP32 Master em modo Access Point.

Aplicações

  • Criar uma rede de Esp32 NodeMCUs (ou outros microcontroladores) para gerir diferentes dispositivos ou sensores

Fontes