Enviando mensajes a NodeMCU ESP8266 desde pagina web usando SocketIO

Nodemcu OLED

NodeMCU es una plataforma IoT de código abierto que utiliza el chip ESP-12E. Esta pequeña placa cuenta con conexión Wi Fi y nos permite conectarnos de forma remota para controlar cualquier dispositivo que hagamos, ya sea usando las salidas de nuestra NodeMCU o Arduino.

En este proyecto use la NodeMCU con una pantalla OLED para poder mostrar mensajes enviados desde una pagina web por medio de sockets, para el envio y recepcion de datos use socketio, una libreria de javascript.

REQUISITOS PREVIOS

Si quieres seguir cada paso de este proyecto sera necesario lo siguiente:

Hardware

  • Placa NodeMCU ESP8266
  • Display Lcd Oled 128×64 0.96″
  • Cables tipo jumper
  • Shield para NodeMCU(opcional)
  • Mini protoboard(opcional)

Librerias

  • NodeJS
  • Socket IO
  • Bootstrap(opcional)

Librerias para IDE Arduino

  • WebSockets by Markus Sattler
  • ESP8266WiFi.h
  • ESP8266WiFiMulti.h
  • SocketIoClient.h
  • Adafruit_SSD1306.h
  • Adafruit_GFX.h

CREANDO NUESTRO SERVIDOR

Para hacer funcionar el servidor, usaremos NodeJS, express y socket.io. Abajo comparto el código necesario para enviar mensajes a nuestra placa.

Como requisito previo sera necesario crear nuestro proyecto e instalar las dependencias. Para ahorrarte un poco de trabajo, puedes clonar el repositorio del proyecto. Para ejecutar el servidor abrimos una terminal y entramos a la raíz del proyecto. Después ejecutamos con node index.js. Podemos detener nuestro servidor con CTRL + C

Servidor index.js

var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var path = require('path');
var public = path.join(__dirname, 'public/src');

app.get('/', function(req, res) {
    res.sendFile(path.join(public, 'index.html'));
});

app.use('/', express.static(public));

io.on('connection', function(socket){  
  console.log('a user connected');

  socket.on('disconnect', function(){
    console.log('user disconnected');
  });

  socket.on('message', function(msg){
    console.log('message: ' + msg);
    io.emit('message', msg);
  });
  
  socket.on('Connection', function(msg){
    console.log('message #'  + ": " + msg);
    socket.emit('event', "Hi NodeMCU, I'm the server");
    });
});

http.listen(process.env.PORT || 3000, function(){
  console.log('Server works on: localhost:3000');
});

Como notaras, en la linea 32 de index.js especificamos que nuestro servidor funcionara en el puerto 3000, como ya debes saber, para vizualizar nuestro servidor desde un navegador es necesario ir a http://localhost:3000 o lo que es igual, http://127.0.0.1:3000Debemos de tener en cuenta que esta direccion solo funciona para ver el servidor desde nuestra computadora, para poder conectarnos a el desde la NodeMCU sera necesario conocer nuestra IP local, es decir, la dirección de nuestro servidor. Para esto abrimos una terminal y escribimos ipconfig. En mi caso la IP donde esta mi servidor es 192.168.0.5. Usaremos esta IP para para especificar a donde nos conectaremos desde nuestro codigo en el IDE de Arduino.

CREANDO EL FORMULARIO

Para enviar mensajes a nuestra pantalla OLED sera necesario tener un formulario. Por medio de el recibiremos un texto que después enviaremos desde el servidor. Bastara con tener un campo input field y un botón con HTML, en mi caso use Bootstrap, un framework de css y javascript. Nos ayudara a que nuestra pagina se adapte fácilmente a teléfonos y tabletas y a que se vea bien sin tener que escribir tanto CSS.

Por ahora el formulario se ve así:

El código HTML necesario para crear el formulario es el siguiente:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Socket.IO chat</title>
    <link rel="stylesheet" href="./assets/css/bootstrap.css">
    <link rel="stylesheet" href="./assets/css/styles.css" >
    
    <base href="/">
    
  </head>
  <body>
    <nav class="navbar navbar-dark navbar-custom">
      <a class="navbar-brand" href="#">IOT CAR</a>
    </nav>
    <div class="container">
      <form class="form-container">
        <div class="form-group">
          <div class="title-form">Send Message</div>
          <input type="text" class="form-control input-form" id="m" autocomplete="off" aria-describedby="emailHelp" placeholder="Enter message">
        </div>          
        <button class="btn btn-lg button-form btn-block input-form">Send</button>
      </form>
      
    </div>
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="assets/js/bootstrap.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
    <script>
      $(function () {
        var socket = io();
        $('form').submit(function(e){
          e.preventDefault(); // prevents page reloading
          socket.emit('message', $('#m').val());
          $('#m').val('');
          return false;
        });
      });
</script>
  </body>
</html>

CONFIGURACION DE SOCKET IO

La librería socket.io-client es un proyecto que nos permite usar las funciones de socketio dentro de arduino. Para instalarlo y configurarlo es necesario seguir los pasos desde su pagina en github.com.

A PROGRAMAR NUESTRA NODEMCU

Bien, ahora que ya tenemos configurado y listo nuestro servidor pasaremos a crear y cargar nuestro programa a nuestra placa.

Primero tendremos que preparar nuestro IDE de Arduino.

Tenemos que cargar la placa NODEMCU a nuestro IDE para poder usarla. Para esto vamos a File/Preferences y pegamos el siguiente link:

http://arduino.esp8266.com/stable/package_esp8266com_index.json

Quedara de la siguiente manera:

Ahora podemos agregar nuestra placa, vamos a Tools/Board:/Boards Manager y buscamos ESP8266 e instalamos.

Vamos a agregar el codigo para cargarlo, puedes copiar el codigo de abajo o usar el codigo del repositorio, el archivo se encuentra en:

/NodeMCU/socket/socket.io

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <SocketIoClient.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>

#define USE_SERIAL Serial
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
#define OLED_ADDR   0x3C
#ifdef DEBUG_ESP_PORT
#define DEBUG_MSG(...) DEBUG_ESP_PORT.printf( __VA_ARGS__ )
#else
#define DEBUG_MSG(...)
#endif

Adafruit_SSD1306 display(OLED_WIDTH, OLED_HEIGHT);
ESP8266WiFiMulti WiFiMulti;
SocketIoClient webSocket;

void setup() {
  while(WiFiMulti.run() != WL_CONNECTED) {
        delay(5000);
        WiFiMulti.addAP("nombre de tu red", "password");// nombre y contrasena de nuestra red WIFI entre comillas dobles
    }
  // Display
  WiFi.mode(WIFI_STA);
  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("Welcome");// mensaje de bienvenida en nuestra pantalla
  display.display();
  
    USE_SERIAL.begin(115200);
    USE_SERIAL.setDebugOutput(true);

      for(uint8_t t = 4; t > 0; t--) {
          USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
          USE_SERIAL.flush();
          delay(1000);
      }
    
    webSocket.begin("192.168.0.5", 3000);// direccion del servidor en nuestra red local
    webSocket.emit("Connection", "\"Hi, I'm nodeMCU\"");
    
    webSocket.on("connect", response);
    webSocket.on("message", message);// Escucha el encabezado message que se envia desde el servidor
    }

void response(const char * response, size_t length) {
          USE_SERIAL.println(response);
          display.println(response);
        }

//Funcion que se ejecuta cuando se recibe un nuevo mensaje desde el servidor
void message(const char * message, size_t length){
  USE_SERIAL.println(message);

  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);  
  display.println(message);// imprime el mensaje recibido en nuestra pantalla OLED
  display.display();
}

void loop() {  
if(WiFi.status() == WL_CONNECTED) {
    webSocket.loop();
  } else {
    webSocket.disconnect();
  }        
}

CONEXIÓN DE NODEMCU CON PANTALLA

La configuración es muy sencilla, bastara con utilizar 4 cables tipo jumper hembra-macho. La siguiente imagen muestra la forma correcta de hacerlo:

PROBANDO NUESTRO PROYECTO

Si todo ha salido correctamente, ahora tenemos una pagina desde la que podemos enviar mensajes y vizualizarlos en tiempo real en nuestra pantalla OLED.

Es importante verificar que tengamos funcionando nuestro servidor ademas de tener la ip correcta de el en nuestro código cargado a la NodeMCU. También verifica que los datos de la red Wi FI sean los indicados. Una ves listo carga el código a la placa.

Cuando termine de cargarse podrás visualizar lo siguiente en el Monitor Serial del IDE de Arduino y recibirás un mensaje Welcome en tu pantalla OLED:

Dejar un comentario