Crescer (fundo transparente)_Negativo_pn
  • Thales Gonçalves Ferreira

Conectando Node-RED com ESP32 via Wi-Fi

Já vimos aqui no blog um sistema supervisório feito com node-red, porém, aquele utilizava ethernet para obter os dados do Arduino. No blog de hoje vamos ver como fazer um sistema parecido, porém, agora utilizando ESP32 e comunicando via WiFi.

Para entender melhor o que é Node-red e alguns outros conceitos básicos aconselho que veja o post anterior, clicando aqui.

Vamos ver como fazer um dashboard que consegue exibir leituras de sensores e acionar saídas do microcontrolador, manualmente ou com base nos dados lidos por um dos sensores.


Avalie-nos no google para que possamos alcançar e auxiliar cada vez mais pessoas a fazer em seus projetos e produtos! Contamos com você!




Agora vamos lá para mais um excelente aprendizado aqui no blog.



Sumário

  1. Comunicação WiFi

  2. Criando aplicação no node-red



Comunicação WiFi

Para montar esse projeto utilizou-se a placa CPB 32, com ela podemos conectar no WiFi, ler os sensores através dos pinos analógicos e ainda acionar relés. A seguir temos uma foto da placa.



A topologia implementada é a seguinte:




A base para o desenvolvimento do código foi o exemplo SimpleWifiServer, para ter acesso a ele primeiro precisamos instalar, na IDE do Arduino, a biblioteca WiFi. Para isso vá em Sketch > Incluir Biblioteca > Gerenciar Bibliotecas, agora basta pesquisar por WiFi e encontrar a biblioteca WiFi, como vista na figura a seguir.



O exemplo pode ser encontrado em, Arquivo > Exemplos > WiFi > SimpleWebServerWiFi. A primeira modificação que precisamos fazer é informar o nome e senha da rede, nos pontos indicados na figura a seguir.



Agora podemos carregar esse programa e fazer o primeiro teste, abra o monitor serial, para visualizar as informações, se tudo correu de maneira correta o resultado deve ser algo parecido com a figura a seguir.



OsirMax_Thales é o nome da minha rede WiFi, podemos ver que a ESP32 conseguiu conectar-se a rede e temos também seu IP, 192.168.8.139. Colocando o IP no navegador podemos acessar o exemplo, que permite ligar e desligar o pino 5 da ESP, na figura a seguir temos o resultado.


Agora podemos editar o código para que ele possa enviar os dados desejados e também receber os comandos do dashboard. Primeiro vamos deletar o código destacado na figura a seguir.



Os dados serão enviados no formato JSON, serão a leitura analógica, sensor de temperatura e a tensão medida por um dos canais do AD, bem como dados digitais, o estado de um botão e contato de confirmação do alarme e de um motor. A seguir o formato do dado JSON.


{
  "analogData":[
      {
         "type":"Tensão",
         "value":0.55
      },
      {
        "type":"Temperatura",
         "value":20.27
      }
  ],
  "booleanData":[
      {
         "type":"botao",
         "value":0
      },
      {
         "type":"motor",
         "value":0
      },
      {
         "type":"alarme",
         "value":0
      }
  ]
}

O código para enviar os dados deve ser inserido no local destacado na figura anterior, a seguir o código dos dados a serem enviados, é importante não esquecer de declarar os pinos como entrada.


            // send a standard http response header
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: application/json");
            client.println("Connection: close");  
        
            client.println();
            client.println("{ 'analogData':[");
            client.println("{ 'type': 'Tensão','value':");
            client.println((analogRead(39) * 3.3) / 4096);
            client.println("},");

            client.println("{ 'type': 'Temperatura','value':");
            client.println(-1491.96+sqrt(2196200.0+((1.8639-(analogRead(36)*3.3)/4096.0))*257731.0));
            client.println("}],");

            client.println(" 'booleanData':[");

            client.println("{ 'type': 'botao','value':");
            client.println(digitalRead(34));
            client.println("},");

            client.println("{ 'type': 'motor','value':");
            client.println(digitalRead(35));
            client.println("},");

            client.println("{ 'type': 'alarme','value':");
            client.println(digitalRead(25));
            client.println("}");

            client.println("]}");

Ao carregar o código, acessando seu IP no navegador o resultado deve ser algo parecido com a figura a seguir:



Agora vamos adicionar no código a recepção dos dados vindos do node-red, primeiro vamos remover do exemplo as linhas referentes a isso, destacadas na figura a seguir.


Perceba que nesse código do exemplo temos um IF para ligar o pino 5 e outro para desligá-lo. Os testes são feitos com as strings “GET /H” e “GET /L”, isso é feito dessa forma pois para ligar o pino precisamos acessar o ip do dispositivo mais o /H, por exemplo, http://192.168.8.139/H e http://192.168.8.139/L, portanto a função testar se foi feita uma requisição a um desses valores.


Os comandos que vamos utilizar aqui são para ligar e desligar um motor e o alarme, portanto serão, /motor1_l, /motor1_h, /alarme_l e /alarme_h. A seguir os códigos que devem ser colocados no lugar das linhas destacadas na figura anterior.


        if (currentLine.endsWith("GET /motor1_h")) {
          digitalWrite(15, HIGH);
        }
        if (currentLine.endsWith("GET /motor1_l")) {
          digitalWrite(15, LOW);
        }
        if (currentLine.endsWith("GET /alarme_h")) {
          digitalWrite(32, HIGH);
        }
        if (currentLine.endsWith("GET /alarme_l")) {
          digitalWrite(32, LOW);
        }

Para os testes o pino 35, sensor do motor, foi conectado ao pino 15, pino que ativa o motor. Para o alarme foi utilizada uma saída com relé, portanto, o comum dele foi conectado no sensor do alarme, pino 25, NA em 3,3V e NF em 0V.


Dessa forma podemos testar a comunicação digitando, no navegador, o IP do dispositivo seguido de /motor1_h, http://192.168.8.139/motor1_h, obtendo o resultado mostrado na figura a seguir, onde podemos ver o sensor do motor indicando que ele está ligado.




Criando aplicação no node-red

Agora que a comunicação está funcionando perfeitamente podemos trabalhar na aplicação no node-red, o primeiro passo é iniciar ele, através do cmd e depois acessá-lo pelo navegador, utilizando localhost:1880.

Primeiro monte a estrutura de acordo com a imagem a seguir, além dos nós padrão foram utilizados nos adicionais para criar o dashboard, para adicionais abra o cmd, com o node-red fechado, e adicione as seguintes linhas.


npm i node-red-dashboard
npm install node-red-contrib-ui-led


Agora vamos ver como cada nó foi configurado, utilize os números para identificá-los.



Nó 1


Esse é o nó responsável por disparar o sistema, sempre que ele for acionado o fluxo será executado, porém, vamos configura-lo também para disparar automaticamente, na figura a seguir temos como ele foi configurado, para abrir as configurações do nó basta dar um clique duplo nele.




Nós 2, 7, 8, 22 e 23


Estes nós são responsáveis por fazerem a requisição dos dados no Arduino, devemos configurá-lo com o IP do dispositivo.








Nó 3


Esse nó será responsável por trocar as aspas simples por duplas, para deixar a string no formato JSON corretamente. Será simplesmente uma troca de caracteres da string.




Nó 4

Esse é responsável por converter a string em JSON, a partir daqui o pacote de dados será interpretado como um JSON e não mais uma string.




Nós 12, 14, 16, 18, 20


Esses nós permitem inserir uma função desenvolvida em javascript, assim podemos processar a mensagem para enviar somente o dado desejado para o próximo bloco.








Nós 6 e 21


Esses nós selecionam para qual saída o dado será enviado, nesse caso tomando como decisão se ele for true ou false.





Nós 10 e 11


Esses são nós do dashboard, serão usados para exibir a tensão e a temperatura.





Nós 13, 15 e 17

Esses nós também são do dashboard, são leds para indicar o estado dos pinos do Arduino. Eles não permitem ajustar o dado que será usado, igual o gauge, por isso é necessário utilizar o function.






Nó 19


Esse nó é capaz de criar um gráfico com os dados que ele recebe, da mesma forma que o LED, não permite selecionar o dado na mensagem, por isso é necessário utilizar o function.




Nó 5


Ele é um nó de chave on/off, que pode ser alterado no dashboard, dependendo do seu estado ele envia true ou false para o próximo.




Nó 9


Com o nó debug podemos visualizar os dados que chegam nele, utilizando a tela de debug.




Dashboard


Para acessar as configurações do dashboard clique na seta na lateral direita, abrirá o menu, depois basta acessa-lo.



Na aba home o menu layout estará disponível. Após acessar o layout basta posicionar os dispositivos como desejar.



A posição dos elementos do dashboard não é crucial para o seu funcionamento, então podemos posicioná-los de acordo com a necessidade e melhor posicionamento para a sua utilização.


Com tudo configurado devemos clicar em deploy, para visualizar o supervisório devemos digitar no navegador localhost:1880/ui. O resultado deve ser algo parecido com a figura a seguir.



Para acessar o dashboard de outro computador, da mesma rede, deve-se colocar o IP do computador que está executando o node-red seguido de :1880, por exemplo 192.168.8.105:1880.


Gostou do conteúdo? tenta fazer esse exemplo aí, quando conseguir compartilha nas redes sociais e marca a gente @crescer_automacao!


Autor: Thales Ferreira



ANEXO - Código exemplo


#include <WiFi.h>

const char* ssid     = "NomeDaRede";
const char* password = "Senha";

WiFiServer server(80);

void setup()
{
  Serial.begin(115200);
  pinMode(34, INPUT);
  pinMode(35, INPUT);
  pinMode(25, INPUT);
  pinMode(15, OUTPUT);
  pinMode(32, OUTPUT);

  delay(10);
  digitalWrite(15, LOW);
  digitalWrite(32, LOW);
  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
 Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  int contador = 0;

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
   Serial.print(".");
    contador++;

    if (contador >= 10) {
      ESP.restart();
    }
  }

 Serial.println("");
 Serial.println("WiFi connected.");
 Serial.println("IP address: ");
 Serial.println(WiFi.localIP());

  server.begin();

}

int value = 0;

void loop() {
  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,
   Serial.println("New Client.");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
       Serial.write(c);                   // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          if (currentLine.length() == 0) {

            // send a standard http response header
           client.println("HTTP/1.1 200 OK");
           client.println("Content-Type: application/json");
           client.println("Connection: close");  // the connection will be closed after completion of the response
           client.println();
           client.println("{ 'analogData':[");
           client.println("{ 'type': 'Tensão','value':");
           client.println((analogRead(39) * 3.3) / 4096);
           client.println("},");

           client.println("{ 'type': 'Temperatura','value':");
           client.println(-1491.96+sqrt(2196200.0+((1.8639-(analogRead(36)*3.3)/4096.0))*257731.0));
           client.println("}],");


           client.println(" 'booleanData':[");

           client.println("{ 'type': 'botao','value':");
           client.println(digitalRead(34));
            client.println("},");

           client.println("{ 'type': 'motor','value':");
           client.println(digitalRead(35));
           client.println("},");

           client.println("{ 'type': 'alarme','value':");
           client.println(digitalRead(25));
           client.println("}");


           client.println("]}");
            break;
          } else {    // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /motor1_h")) {
         digitalWrite(15, HIGH);
        }
        if (currentLine.endsWith("GET /motor1_l")) {
         digitalWrite(15, LOW);
        }
        if (currentLine.endsWith("GET /alarme_h")) {
         digitalWrite(32, HIGH);
        }
        if (currentLine.endsWith("GET /alarme_l")) {
         digitalWrite(32, LOW);
        }

      }
    }
    // close the connection:
    client.stop();
   Serial.println("Client Disconnected.");
  }
}

Autor: Thales Ferreira


51 visualizações

Posts recentes

Ver tudo