Icono del sitio AranaCorp

Comunicación entre dos ESP8266 por WiFi

El NodeMCU ESP8266 es un pequeño microcontrolador con un chip Wi-Fi. Es posible establecer una comunicación entre dos ESP8266, cuando están conectados en la misma red. En este tutorial, veremos una arquitectura Maestro/Esclavo, en la que un ESP8266 hará de servidor y gestionará una interfaz web así como las distintas peticiones «esclavas».

Material

Configurar el servidor con una dirección IP fija

En algunos casos, como la creación de un servidor, tendrá que especificar una dirección IP concreta a su microcontrolador. Es posible establecer una dirección fija en el ESP8266 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)

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

Inicializa las diferentes direcciones IP en el código de Arduino (no olvides sustituir estas direcciones por las que aparecen en tu 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 Wifi antes de inicializarla

WiFi.config(ip, gateway, subnet); // Static IP setup
WiFi.begin(ssid, password);

Código ESP8266 Master

Para el microcontrolador maestro, crearemos un servidor que gestione las peticiones del navegador, la interfaz web y las peticiones procedentes de los microcontroladores esclavos. Utilizamos la librería ESP8266WiFi.h que permite gestionar el chip WiFi de las tarjetas ESP8266.

N.B.: No olvides cambiar los valores de ssid y password, por el nombre y la contraseña de la red wifi que quieres utilizar

//Libraries
#include <ESP8266WiFi.h>//https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/src/ESP8266WiFi.h

//Constants
#define NUM_SLAVES 1
#define LED D4

//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 ESP8266 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);
        client.flush();
        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> Esp8266 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 ESP8266 Slave

En el código del 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 password que en el módulo Master para que las dos tarjetas ESP8266 estén conectadas a la misma red.

//Libraries
#include <ESP8266WiFi.h>//https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/src/ESP8266WiFi.h

//Constants
#define LED D4
#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 ESP8266 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);
        }
      }
    }
  }
}



Resultado

Cuando los microcontroladores se conectan al Wifi y se establece la comunicación entre los dos ESP8266, podemos ver que se intercambia información y comandos entre las dos placas. También es posible controlar los LED de ambas placas mediante los botones de la interfaz.

Aplicaciones

Fuentes

Salir de la versión móvil