Le NodeMCU ESP8266 est un petit microcontrôleur possédant une puce Wifi. Il est possible d’établir une communication entre deux ESP8266, lorsqu’ils sont connectés sur le même réseau. Dans ce tutoriel, nous allons voir une architecture Maître/Esclave, dans laquelle un ESP8266 va jouer le rôle de serveur et gérer une interface Web ainsi que les différentes requêtes « esclaves ».
Matériel
- Ordinateur
- NodeMCU ESP8266 x2 ou plus
- Câble USB A Mâle/Micro B Mâle
Configurer le serveur avec une adresse IP fixe
Dans certains cas, comme la création d’un serveur, vous aurez besoin de spécifier une adresse IP particulière à votre microcontrôleur. Il est possible de définir une adresse fixe sur les ESP8266 en spécifiant les adresses IP de la passerelle et du sous-réseau.
Dans le l’invite de commande, tapez arp -a pour afficher les adresses IP déjà utilisées sur votre réseau. Choisissez une adresse qui ne se trouve pas dans la liste (ex: 192.168.1.103)
Ensuite, tapez ipconfig pour récupérer les adresses IP correspondant à votre routeur.
Initialisez les différentes adresses IP dans le code Arduino (n’oubliez pas de remplacer ces adresses par celles qui s’affichent sur votre ordinateur).
IPAddress ip(192, 168, 1,103 );
IPAddress gateway(192, 168, 1, 254);
IPAddress subnet(255, 255, 255, 0);
Ensuite, vous pouvez configurer la connexion Wifi avant de l’initialiser
WiFi.config(ip, gateway, subnet); // Static IP setup
WiFi.begin(ssid, password);
Code ESP8266 Master
Pour le microcontrôleur Maître, nous allons créer un serveur pour gérer les requêtes du navigateur, l’interface web et les requêtes provenant des microcontrôleurs esclaves. nous utilisons la librairie ESP8266WiFi.h qui permet la gestion de la puce WiFi pour les cartes ESP8266.
N.B.: N’oubliez pas de modifier les valeurs de ssid et password, par le nom et le mot de passe du réseau wifi que vous souhaitez utiliser
//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); 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 Esclave
Dans le code esclave, nous allons nous connecter au serveur en utilisant l’adresse IP précédemment utilisé.
N.B.: N’oubliez pas de modifier et d’utiliser les mêmes valeurs de ssid et password que dans le module Maitre afin que les deux cartes ESP8266 soient connectées au même réseau.
//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); } } } } }
Résultat
Lorsque les microcontrôleurs sont connectés au Wifi et que la communication entre les deux ESP8266 est établie, nous pouvons voir que des informations et des commandes sont échangées entre les deux cartes. Il est aussi possible de piloter les LED des deux cartes à l’aide des boutons de l’interface.
Applications
- Créer un réseau de NodeMCU Esp8266 pour gérer différents appareils ou capteurs
Bonjour, je voudrais avoir un retour d expérience avec cette communication et l application BLYNK , est ce possible.
Merci
Philippe
Bonjour et merci pour votre Tutorial,
J’ai strictement copié vos codes Master et Slave, mis une adresse IP fixe non utilisée + SSID et mot de passe.
Les deux esp8266 semblent communiquer si l’on regarde le moniteur série, mais…
Vous dites : » Il est aussi possible de piloter les LED des deux cartes à l’aide des boutons de l’interface. »
Si je me connecte à l’adresse IP que j’ai entrée dans le code Master et le code Slave, je n’obtiens pas la page WEB que vous affichez pour commander l’allumage et l’extinction des LEDs, mais ceci :
Je ne comprend pas pourquoi la page WEB ne s’affiche pas. Pouvez-vous m’aider, car j’aimerai utiliser ces codes pour transmettre des datas de sonde d’humidité de la terre d’un potager, pour décider de l’arrosage.
A noter que je maîtrise bien la programmation des capteurs, mais que suis nul en HTML !
Cordialement.
Bonjour,
Merci beaucoup pour votre commentaire. Une coquille s’était glissée dans le code html.
C’est corrigé
S.V.P. il y a une erreur quelque part dans le programme .
il y a bel et bien la page html mais lorsque je clique sur un des 2 boutons j’ai le message suivant Impossible d’accéder à votre fichier avec comme titre de la page file:///C:/light1off
Bonjour,
je n’ai pas cette erreur. Quel navigateur utilisez-vous?
Bonjour, super tuto que j’utilise avec un dht22 + lcd et relais. Je souhaite apporter une petite amélioration en rechargeant une partie de la page (zone température et humidité) sans avoir à recharger entièrement une nouvelle page. ( browser.println »Refresh: 5″)
Est ce possible sans refaire complètement la programmation ?
Si oui , une base de départ me serait bien utile .
Merci d’avance
Oui cela est possible mais ça demande de modifier un peu le code. Il faut faire une requête AJAX pour rafraichir les données sans rafraichir la page.
Merci. je vais chercher comment modifier votre exemple.
avez vous trouvé le code en AJAX?