fbpixel
Etiquetas: ,

El NodeMCU ESP32 es un pequeño microcontrolador con un chip WiFi. Es posible establecer comunicación entre dos ESP32 cuando están conectados a la misma red. En este tutorial, veremos una arquitectura maestra.

Hardware

  • Ordenador
  • NodeMCU ESP32 x2 o más
  • Cable USB A macho

Configurar el servidor con una dirección IP fija

En algunos casos, como la creación de un servidor, necesitará especificar una dirección IP concreta para su microcontrolador. Es posible definir una dirección fija en los ESP32 especificando las direcciones IP de la puerta de enlace y de la subred.

En la línea de comandos, escriba arp -a para mostrar las direcciones IP que ya están en uso en su red. Elija una dirección que no esté en la lista (por ejemplo, 192.168.1.103).

windows-cmd-prompt-terminal-get-available-ip Comunicación entre dos ESP32 a través de WiFi

A continuación, escriba ipconfig para recuperar las direcciones IP correspondientes a su router.

window-ipconfig-ip-subnet-gateway Comunicación entre dos ESP32 a través de WiFi

Inicialice las distintas direcciones IP en el código Arduino (no olvide sustituir estas direcciones por las que aparecen en su ordenador).

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

A continuación, puede configurar la conexión Wi-Fi antes de inicializarla

WiFi.config(ip, gateway, subnet); // Static IP setup
WiFi.begin(ssid, password);
arduino-monitor-ip-fix Comunicación entre dos ESP32 a través de WiFi

ESP32 Código Maestro

Para el microcontrolador maestro, vamos a crear un servidor para gestionar las peticiones del navegador, la interfaz web y las peticiones de los microcontroladores esclavos. Vamos a utilizar la librería WiFi.h, que gestiona el chip WiFi de las tarjetas ESP32.

N.B.: No olvides cambiar los valores de ssid y password por el nombre y password de la red wifi que quieras 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);
}

ESP32 código esclavo

En el código esclavo, nos conectaremos al servidor utilizando la dirección IP utilizada anteriormente.

N.B.: No olvide modificar y utilizar los mismos valores de ssid y contraseña que en el módulo Master para que las dos tarjetas ESP32 estén conectadas a la misma red.

//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

Cuando los microcontroladores están conectados a Wi-Fi y se establece la comunicación entre los dos ESP32, podemos ver que la información y los comandos se intercambian entre las dos placas. También es posible controlar los LED de las dos placas mediante los botones de la interfaz.

nodemcu-esp32-web-insterface Comunicación entre dos ESP32 a través de WiFi
nodemcu-esp32-master-monitor Comunicación entre dos ESP32 a través de WiFi
nodemcu-esp32-slave-monitor Comunicación entre dos ESP32 a través de WiFi

En este tutorial, hemos visto cómo hacer que dos ESP32 se comuniquen en la red Wifi local. También es posible reproducir este tutorial utilizando la tarjeta ESP32 Master en modo Access Point.

Aplicaciones

  • Crear una red de Esp32 NodeMCUs (u otros microcontroladores) para gestionar diferentes dispositivos o sensores.

Fuentes