,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)
Em seguida, digite ipconfig para obter os endereços IP correspondentes ao seu router.
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);
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.
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