bclose

WIFI modo STATION

Usando el ESP32 WIFI

Comunicaciones para IOT con  ESP32

 

 

    • Internet of Things: WIFI Station.
    • Modos WIFI del ESP32.
    • Un servidor web sencillo.
 

Material requerido.

 

 Tienda EspañaTienda Mexico
 vista lateral del esp32
Un ESP32

Transmitiendo datos para la IOT

 

Hablábamos en la última sesión de que para que la IOT fuera una realidad íbamos a necesitar comunicaciones sencillas y a ser posibles integradas en micros de bajo coste y por eso vamos a empezar a ver que redes tenemos disponible con un ESP32 (Que será nuestro micro de referencia) y que como todos sabéis son WIFI y Bluetooth.

Vamos a empezar viendo cómo usar WIFI con el ESP32, primero porque suele ser la comunicación de más alto interés para casi todos, ya que todos tenemos en casa una red WIFI disponible actualmente. Veremos cómo usarla y programarla con el ESP32 y también entraremos en las diferentes opciones de WIFI que tenemos disponibles, como STATION y como ACCESS POINT

Después nos meteremos con el Bluetooth (En un tuto posterior) , porque si la WIFI es prácticamente ubicua, el Bluetooth no le va a la zaga, ya que todos nuestros móviles están equipados con él y hay toda una plétora de dispositivos con capacidad de conexión Bluetooth, desde e relojes de pulsera, a cascos inalámbricos pasando por teléfonos sin manos del coche.

Tanto el WIFI como el Bluetooth son capaces de transmitir gran cantidad de información a gran velocidad, pero tiene el inconveniente de que consumen más de lo que nos gustaría, a pesar de que siempre nos hablan del nuevo estándar de baja energía y bajo consumo, al final los dispositivos que van a baterías tienden a quedarse sin ella muy rápidamente en cuanto los activas y más si el uso crece.

WIFI y BT están muy bien para conectarte a internet y ver videos o descargar aplicaciones, pero su alta velocidad hace que el consume energético sea alto y por ello su alcance relativamente corto. Por eso para la IOT se requiere por regla general transmitir poca información, con lo que una velocidad baja es suficiente, pero requiere un mayor alcance que el WIFI o BT y especialmente necesita un muy bajo consumo

Es para esto para lo que se diseñan las redes llamadas LPWA o LPWAN (Low Power Wide Area Network) o redes extensas de bajo consumo, de las LORA y LORAWAN son un buen ejemplo (Pero no el único) y que esperamos que el 5G las de un empujoncito.

Pero para no ponerme pesado, vamos a empezar directamente viendo cómo usar el WIFI con nuestro ESP32

 

ESP32 WIFI STATION MODE

 

En una red WIFI, nuestro ESP32 puede actuar básicamente de dos modos:

 
  • Station Mode
  • Access point Mode.  

El Station mode es el habitual al que estas acostumbrado. La red a la que queremos conectar dispone de un router WIFI que nos proporciona el servicio de acceso. Es el caso de las conexiones de ADSL o fibra domesticas que nos son tan familiares.

Un router WIFI, suministrador por las operadoras proporciona los servicios de acceso a la red WIFI doméstica y encamina los datos hacia Internet de forma transparente para nosotros (Además de proporcionar algunos servicios adicionales como DHCP y DNS).

Red con router

Todos los dispositivos conectados funcionan como estaciones de trabajo y el router proporciona los servicios que ligan la red entre sí. Es un sistema comodo y fiable si disponemos de una red preexistente en nuestro entorno, basta con conectarnos y listo. Veamos cómo podemos hacer esto con nuestro ESP32.

El modo STATION es el modo por defecto de la conexión del ESP32 y en esta sesión vamos a centrarnos exclusivamente él. Vamos a escribir un programa de lo más sencillo que nos conecte a la WIFI, imprima la dirección IP signada por el DHCP de nuestro router e inicie un servidor web que nos muestra un simple mensaje de texto, a modo de ejemplo de uso. Veamos cómo.

Empezamos el programa incluyendo algunas librerías del WIFI para variar

#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>

La primera include es de obligada inclusión en todos nuestros programas si queremos servicio WIFI y la segunda es el modo cliente ya que nos vamos a conectar al router. La 3ª se cae sola: Queremos instalar un servidor web que muestre un mensaje de bienvenida a quien se conecte a nuestro servidor.

 
  • He visto que algunos noviciosse muestran confusos cuando decimos que nos conectamos a nuestro router y más tarde nos conectamos a un servidor dentro de la red. Pero no hay tal problema.
  • La conexión WIFI al router nos da acceso a la red WIFI TCPIP, y cuando conectamos a un servidor web de una estación o nodo TCPIP simplemente accedemos a un servicio de ese nodo. No hay incompatibilidad entre ambas cosas. 
.

Nos toca ahora declara nuestro servidor web en el puerto deseado:

WebServer server(80);

El 80 indica el puerto estándar para un servidor HTTP, pero puedes cambiar esto y poner tu servidor en cualquiera de los puertos disponibles (Del 100 al 64.000)

Vamos definir a continuación los datos de conexión a nuestra red WIFI: el SSIP o identificador y la contraseña de acceso. Tienes que poner aquí tus datos para que podamos conectarnos

const char* ssid = "TU_SSID";
const char* password = "Tu_contraseña";

Preparamos el setup

void setup()
{ Serial.begin(115200);
  WiFi.mode(WIFI_STA);               //Modo Station

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
    {    delay(1000);
         Serial.print(".");
    }

Iniciamos el Serial port para poder mostrar más adelante la dirección IP que nos asigne el router (Imprescindible para saber la IP del servidor web) y luego declaramos el WIFI mode como WIFI STATION para conectarnos al router.

Iniciamos la conexión a la WIFI con la instrucción begin a la que pasamos el nombre de la red y la contraseña, y entramos en un bucle sencillo que va imprimiendo un puntito en la consola cada segundo hasta que se conecte correctamente. Lo siguiente es sacar un mensaje de éxito en la conexión y mostrar la IP que nos ha signado el router:

Serial.println("WiFi connected..!");
Serial.print("IP del servidor: ");  Serial.println(WiFi.localIP());

En mi caso, la dirección que me toca es esta  (Apunta la tuya, que va a hacer falta):

mensaje de exito en la conexion

Nos falta iniciar el servicio web , pero antes tenemos que definir dos funciones básicas de todo servidor, que son, básicamente,  que hacer cuando alguien se conecta correctamente, y que hacer cuando nos pide algo que no tenemos o entendemos.

Cuando alguien se conecta a nuestro servidor se invoca una función cuando alguien entra y otra cuando hay un error, por costumbre las llamamos handle_OnConnect() para el que sí, y handle_NotFound para el que no (Aunque puedes cambiar los nombres a lo que te encaje) y después iniciamos el servicio web:

server.on("/", handle_OnConnect);
server.onNotFound(handle_NotFound);
server.begin();
Serial.println("HTTP server started");

A este tipo de funciones se las llama de Call-back, porque se invocan por otra función cuando se cumple una cierta condición, pero tenemos que definirlas a más adelante. Y por último nos falta el loop:

void loop()
{ server.handleClient();
}

Como ves el loop es de lo más sencillo porque simplemente le dice a nuestro servidor que se encargue de los clientes que lleguen y punto . Vamos con las funciones que trabajan: La más sencilla es la de no encontrada:

void handle_NotFound()

{      server.send(404, “text/plain”, “No hay respuesta”);

}

Con ella sacaremos un mensaje plano, sin formato, diciendo que no hay respuesta, conformando un texto sencillo en formato HTML, o puedes escribir tu propio mensaje de error . Si solo quieres ver que el servidor responde puedes usar esto ya para enviar mensajes por tu página web, simplemente salta a la direccion IP que apuntaste mas arriba ñadiendole una barra “/qq” para que salte a una página que no existe :

mensaje de error

El problema es que este mensaje da asco y acabaríamos el tuto excesivamente deprisa y como me pagan por paginas me conviene trabajar el asunto un poco más. Vamos a usar otra función que conforme un mensaje HTML con algo de formato, de modo que no quieras sacarte los ojos cuando lo veas. Para ello,  vamos a escribir una función que nos permita enviar mensajes en formato HTML lo que nos permitirá mejorar un poco la presentación de nuestra bienvenida, y que invocaremos desde la función de conexión correcta.

void handle_OnConnect()
   { server.send(200, "text/html", SendHTML("Hola a todos"));
   }

En la que puedes que usamos una función llamada SendHTML() que nos permitirá hacer algunas cosas un poco más presentables con nuestra página web (Que escribiremos .

Es importante decir ahora, que la parte de arrancar el servidor HTML está completa y que ya hemos visto cómo funciona el modo STATION en el que nos conectamos a un router disponible. Lo que viene ahora es simplemente crear una función que nos permita sacar mensajes formateados con un poco más de estilo que lo que habíamos visto antes, pero tienes que entender que lo que viene en la función SendHTML() es simplemente crear un mensaje HTML con lo que deseamos presentar.

Vamos a sacar el logo de Prometec, como ejemplo de insertar una imagen (Y porque me encanta hacer publicidad) más un texto fijo y un mensaje de texto que podamos variar. Pero tenéis que entender que no podemos liarnos hablando de HTML porque si no, no acabaríamos nunca, así que si queréis podáis usar esta función como base para otra vuestra y modificarla a vuestro antojo.

Básicamente vamos a crear un mensaje de texto que represente la página web que queramos mostrar y para eso vamos a crear un puntero a String, al que iremos añadiendo las líneas necesarias para que sea un mensaje HTML correcto ¿Vale?

String SendHTML(String S)
{ String ptr = "<!DOCTYPE html>";
  ptr +="<html>";
  ptr +="<head>";
  ptr +="<title>Prometec.net</title>";
  ptr +="<img src='https://www.prometec.net/wp-content/uploads/2018/11/logo-prometec.jpg'>";

Vale, una vez que cargues el programa en tu micro, tienes que saltar a su dirección IP (Que apuntaste de la consola) con un navegador y veras algo asi:

conectado al servidor

 

Programa final

 

El programa completo quedaría así:

#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>

WebServer server(80);
//..........................Aqui van tus datos WIFI
const char* ssid = "REDLINEB";
const char* password = "contrase";
//.................................................

void setup()
{ Serial.begin(115200);
  WiFi.mode(WIFI_STA); //Modo Station
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
    {    delay(1000);
         Serial.print(".");
    }
  Serial.println("WiFi connected..!");
  Serial.print("Got IP: ");  Serial.println(WiFi.localIP());

  server.on("/", handle_OnConnect);
  server.onNotFound(handle_NotFound);
  server.begin();
  Serial.println("HTTP server started");
}

void loop()
{ server.handleClient();
}

void handle_OnConnect()
{    server.send(200, "text/html", SendHTML("Hola a todos"));
}

void handle_NotFound()
{    server.send(404, "text/plain", "No hay respuesta");
}

String SendHTML(String S)
{ String ptr = "<!DOCTYPE html>";
ptr +="<html>";
ptr +="<head>";
ptr +="<title>Prometec.net</title>";
ptr +="<img src='https://www.prometec.net/wp-content/uploads/2018/11/logo-prometec.jpg'>";
ptr +="<meta http-equiv='refresh' content='0.3' >";
ptr +="<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
ptr +="<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600' rel='stylesheet'>";
ptr +="<style>";
ptr +="html { font-family: 'Open Sans', sans-serif; display: block; margin: 0px auto; text-align: center;color: #444444;}";
ptr +="body{margin: 0px;} ";
ptr +="h1 {margin: 50px auto 30px;} ";
ptr +=".side-by-side{display: table-cell;vertical-align: middle;position: relative;}";
ptr +=".text{font-weight: 600;font-size: 19px;width: 200px;}";
ptr +=".reading{font-weight: 300;font-size: 50px;padding-right: 25px;}";

ptr +=".superscript{font-size: 17px;font-weight: 600;position: absolute;top: 10px;}";
ptr +=".data{padding: 10px;}";
ptr +=".container{display: table;margin: 0 auto;}";
ptr +=".icon{width:65px}";
ptr +="</style>";
ptr +="</head>";
ptr +="<body>";
ptr +="<h1>Mensaje simple WEB</h1>";
ptr +="<div class='container'>";
//ptr +="<div class='side-by-side text'>S</div>";
ptr +="<div class='side-by-side reading'>";
ptr +=S;                  //.................................
ptr +="</div>";
ptr +="</div>";
ptr +="</div>";
ptr +="</body>";
ptr +="</html>";
return ptr;
}

 

IMAGEN DE MARCA