Tags: , ,

The NodeMCU ESP8266 is a small microcontroller with a Wifi chip. It is possible to establish a communication between two ESP8266, when they are connected on the same network. In this tutorial, we will see a Master/Slave architecture, in which an ESP8266 will play the role of a server and manage a Web interface as well as the various “slave” requests.

Material

  • Computer
  • NodeMCU ESP8266 x2 or more
  • USB A Male/Micro B Male Cable

Configure the server with a fixed IP address

In some cases, such as creating a server, you will need to specify a particular IP address to your microcontroller. It is possible to define a fixed address on the ESP8266 by specifying the IP addresses of the gateway and the subnet.

At the command prompt, type arp -a to display the IP addresses already in use on your network. Choose an address that is not in the list (ex: 192.168.1.103)

windows-cmd-prompt-terminal-get-available-ip Communication between two ESP8266 via WiFi

Then type ipconfig to get the IP addresses corresponding to your router.

window-ipconfig-ip-subnet-gateway Communication between two ESP8266 via WiFi

Initialize the different IP addresses in the Arduino code (don’t forget to replace these addresses by those displayed on your computer).

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

Then, you can configure the Wifi connection before initializing it

WiFi.config(ip, gateway, subnet); // Static IP setup
WiFi.begin(ssid, password);
arduino-monitor-ip-fix Communication between two ESP8266 via WiFi

Code ESP8266 Master

For the Master microcontroller, we will create a server to manage the browser requests, the web interface and the requests coming from the slave microcontrollers. We use the ESP8266WiFi.h library which allows the management of the WiFi chip for the ESP8266 cards

N.B.: Don’t forget to change the values of ssid and password, by the name and the password of the wifi network you want to use

//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);
}

Code ESP8266 Slave

In the slave code, we will connect to the server using the IP address previously used.

N.B.: Don’t forget to modify and use the same ssid and password values as in the Master module so that the two ESP8266 cards are connected to the same network.

//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);
        }
      }
    }
  }
}



Result

When the microcontrollers are connected to the Wifi and the communication between the two ESP8266 is established, we can see that information and commands are exchanged between the two boards. It is also possible to control the LEDs on both boards using the buttons on the interface.

esp8266-communication-web-interface Communication between two ESP8266 via WiFi
arduino-monitor-esp8266-master Communication between two ESP8266 via WiFi
arduino-monitor-esp8266-slave Communication between two ESP8266 via WiFi

Applications

  • Create a network of Esp8266 NodeMCUs to manage different devices or sensors

Sources