Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Comunicação via WebSockets com NodeMCU – ESP8266

Tutorial sobre comunicação com WebSockets  usando as placas  NodeMCU, ESP8266 ou ESP32.

Neste experimento vamos demonstrar como estabelecer uma comunicação usando WebSockets entre um servidor Nodemcu e um cliente WEB que pode ser um PC, um celular ou outra placa ESP*.*

Sobre WebSockets

Websocket é um protocolo de comunicação muito mais rápido que o protocolo  HTTP padrão. Websocket permite abrir um canal único de comunicação bidirecional entre dois dispositivos, sem a necessidade de fechar a conexão a cada requisição. Ou seja, se ajusta muito bem no mundo IoT.
Principais vantagens:

  • Bidirecional: O protocolo HTTP é unidirecional, ou seja, o cliente envia uma solicitação à qual o servidor responde.  O WebSocket é um protocolo bidirecional FULL-DUPLEX no qual o cliente ou servidor podem enviar uma mensagem para a outra parte.
  • Conexão TCP única: Diferentemente do protocolo HTTP padrão, com o WebSocket, o cliente e o servidor se comunicam na mesma conexão TCP até que um deles feche a conexão.
  • Leve: o Websocket concentra-se no essencial, diferente do HTTP, que carrega muita informação para cada requisição. Em termos de desempenho, o Websocket é muito mais rápido.
WebSocket Diagram
WebSocket Diagrama

O Projeto de Teste

Para testar as tecnologias aqui citadas, vamos criar um cliente WEB que vai se comunicar com um servidor WebSocket em uma placa NodeMCU. Nosso objetivo é realizar a comunicação bidirecional:

  • A página WEB vai possuir um botão ON/OFF para controlar um LED da placa (desculpem o clichê)
  • O servidor vai enviar para a página informações de um sensor de temperatura de 10 em 10 segundos (outro clichê)

Para entender melhor o funcionamento da experiência, veja aqui um vídeo demonstrativo:

O protótipo

Protótipo WebSocket NodeMCU
Protótipo WebSocket NodeMCU

Componentes:

  1. Placa NodeMCU. Na verdade pode ser qualquer placa da Familia ESP*.*  compatível com  a IDE do Arduino (ESP8266, NodeMCU, Wemos, ESP32, etc.). No vídeo eu utilizei uma NodeMCU Lolin com placa de expansão;
  2. Sensor de temperatura do tipo termistor NTC 10K. No vídeo eu utilizei um módulo termistor da GBK;
  3. Fios jumper e, opcionalmente, uma protoboard.

Recursos necessários

Software Cliente (WEB)

Nossa página vai ser criada em HTM5 com Bootstrap 4 e JQuery. Veja abaixo onde obter os pacotes:

  • O Bootstrap 4 é Framework CSS responsivo para front-end. Com isso, nossa página vai ser exibida perfeitamente tanto em desktops quanto no mobile. Precisaremos também instalar o pacote de fontes FontAwesome e, opcionalmente, a biblioteca de popups Popper.
  • O JQuery é uma biblioteca Javascript que facilita a manipulação dos elementos HTML (DOM).

Software NodeMCU

  • Para criamos o servidor websocket vamos precisar instalar a biblioteca arduinoWebSockets que pode ser instalada pela própria IDE do Arduino através de gerenciador de bibliotecas;
  • Os dados de temperatura do sensor serão enviados a cada 10 segundos para o cliente WEB. Para descomplicar nosso código, vamos fazer a contagem do tempo com millis fazendo uso da biblioteca NeoTimer, que também está disponível no gerenciador.
  • A leitura e cálculo da temperatura será feita através da seguinte rotina disponível na Internet: Thermistor Interfacing with NodeMCU

O código!

Os arquivos com o códigos-fonte e as bibliotecas do lado cliente estão disponíveis aqui no GitHUB.

Lado Cliente

Nossa aplicação WEB é composta de 2 arquivos. O código HTML5 e o script JQuery. Os comentários estão no próprio código fonte:


  
    Teste WebSockets

Teste WebSocket


Situação do LED
Temperatura Atual

35 °C


Log de comunicação
/***
Teste de Websockets com ESP8266 - Cliente
José Cintra em Outubro de 2019 - www.josecintra.com/blog/comunicacao-websockets-nodemcu-esp8266">
***/

$(document).ready(function () {

  let ledStatus = 0; // Status do LED 0 = desligado / 1 = ligado
  let buttonText = ['OFF', 'ON']; // Texto do botão do LED de acordo com o status
  let buttonStyle = ['btn btn-lg btn-secondary', 'btn btn-lg btn-success']; // Estilo do botão do LED de acordo com o status

  // Coloque aqui o IP obtino no ESP8266
  let con = new WebSocket('ws://192.168.0.31:81/', ['arduino']);

  // Evento que ocorre quando a placa envia dados
  let previous = "";
  con.onmessage = function (evt) { 
    if (evt.data != "ON" && evt.data != "OFF"){
		$('#temperature').html(evt.data);
	}
		previous = $('#log').html();
		$('#log').html(previous + '\n' + evt.data);

  };

  //$('#led-status').html(buttonText[ledStatus]);

  // Clique no botão do LED
  $('#led-status').click(function () {

    // Muda a classe e texto do botão de acordo com o status
    ledStatus = (ledStatus + 1) % 2; // Alterna entre 0 e 1
    $('#led-status').removeClass();
    $('#led-status').addClass(buttonStyle[ledStatus]);
    $('#led-status').html(buttonText[ledStatus]);

    // envia o comando para a placa
    con.send(buttonText[ledStatus]);


  });
});

Observações:
Neste exemplo, não usamos um servidor WEB para “hospedar” a página. Mas caso queira usar um banco de dados ou outro recurso de servidor, será necessário configurar um. Recomendo o instalador XAMPP (PHP) para isso.

Lado Servidor

Abaixo o código do ESP8266. Para saber como usar a IDE Arduino com as placas ESP8266, veja o seguinte artigo: Tutorial: Programando a NodeMCU (ESP8266) com a IDE do Arduino

/***
Teste de Websockets com ESP8266 - Servidor
José Cintra em Outubro de 2019 - www.josecintra.com/blog/comunicacao-websockets-nodemcu-esp8266">
***/

#include 
#include 
#include 

//Correção nivel lógico invertido
#define ON LOW
#define OFF HIGH

WebSocketsServer webSocket = WebSocketsServer(81); // Recebe dados do cliente
Neotimer mytimer = Neotimer(10000); // Intervalo de 10 segundos para envio dos dados do sensor

// Autenticação wi-fi - Coloque aqui a sua configuração
const char* ssid     = "xxxx";
const char* password = "xxxx";

const int pinLED = D4;
String tempString; // Temperatura convertida para String

// Tratamento de eventos dos dados que vêm do cliente 
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) {

  switch (type) {
    case WStype_DISCONNECTED:
      break;

    case WStype_CONNECTED:
      { IPAddress ip = webSocket.remoteIP(num);
        Serial.println(ip);
      }
      break;

    case WStype_TEXT:
      { String text = String((char *) &payload[0]);
        Serial.println(text);
        Serial.println(num);
        Serial.println(type);

        if (text == "ON") {
          digitalWrite(pinLED, ON);
        } else {
          digitalWrite(pinLED, OFF);
        }
      }
      break;

  }

}

void setup() {
  
  // Inicialização do LED
  Serial.begin(9600);
  pinMode(pinLED, OUTPUT);
  digitalWrite(pinLED, OFF);
  // Conexões wi-fi e websocket
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(". ");
    delay(100);
  }
  Serial.println(WiFi.localIP());
  webSocket.begin();
  webSocket.onEvent(webSocketEvent);

}

void loop() {
  webSocket.loop();

  // Envio periódico dos dados do sensor de temperatura para o cliente
  if (mytimer.repeat()) {
    tempString = readTemperature();
    webSocket.sendTXT(0, tempString);
  }
}

// Leitura e cálculo da temperatura pelo termistor
double readTemperature() {
   
  // Código extraído do tutorial 'Thermistor Interfacing with NodeMCU' disponível em:
  // https://www.electronicwings.com/nodemcu/thermistor-interfacing-with-nodemcu

  const double VCC = 3.3; // NodeMCU on board 3.3v vcc
  const double R2 = 10000; // 10k ohm series resistor
  const double adc_resolution = 1023; // 10-bit adc
  const double A = 0.001129148; // thermistor equation parameters
  const double B = 0.000234125;
  const double C = 0.0000000876741;
  double Vout, Rth, temperature, adc_value;

  adc_value = analogRead(A0);
  Vout = (adc_value * VCC) / adc_resolution;
  Rth = (VCC * R2 / Vout) - R2;

  temperature = (1 / (A + (B * log(Rth)) + (C * pow((log(Rth)), 3))));  // Temperature in kelvin
  temperature = temperature - 273.15;  // Temperature in degree celsius
  delay(500);
  return (temperature);

}

Observações:

  1. As portas do NodeMCU possuem o nível lógico invertido. Cuidado aqui! Isso significa que o LED acende com LOW e apaga com HIGH;
  2. O LED interno do NODEMCU V3 (Lolin) está em uma porta diferente das demais versões. Então aqui não podemos usar a constante LED_BUILTIN
  3. Como dissemos acima, para ler e calcular a entrada análogica do sensor NTC, usamos uma rotina específica, já que o sinal lógico dos ESP é de 3.3V, o que pode acarretar inconsistências nos valores da temperatura

Referências

  • A Beginner’s Guide to the ESP8266
  • WebSocket communication with an ESP8266 or Arduino in Python

Conclusão

Isso é tudo. Espero ter ajudado…

O post Comunicação via WebSockets com NodeMCU – ESP8266 apareceu primeiro em BlogDoJoséCintra.



This post first appeared on BlogDoJoséCintra, please read the originial post: here

Share the post

Comunicação via WebSockets com NodeMCU – ESP8266

×

Subscribe to Blogdojosécintra

Get updates delivered right to your inbox!

Thank you for your subscription

×