Control de luz con esp8266 y arduino

Los objetivos de esta práctica es manejar una luz, para luego ampliarla a otras cargas, desde un módulo WIFI esp8266 y arduino

Para ello vamos a empezar paso a paso desde el control del puerto serie de arduino, etiquetas AT del módulo, la programación y la puesta en servicio del módulo como servidor web, para activar-desactivar cargas desde Internet

Antes de empezar, tenemos que tener en cuenta los objetivos de esta práctica, que no son otros que introducirnos en el Internet de las cosas, ( IOT), donde la tendencia es a tener cada vez mas máquinas y componentes conectados a Internet. Es un trabajo de desarrollo, por tanto, NO ES UNA PRÁCTICA CERRADA y la mantendremos como un punto de partida para que, entre todos, desarrollemos mas este apasionante campo de las tecnologías de redes.

Como el enfoque es al nuestro ciclo de grado medio del IES Mare nostrum, iremos explicando algunas otras cosas que, sin ser propias del curriculum del módulo, son necesarias para implementar todo el sistema. Manos a la obra

Puerto serie de arduino.

En la primera imagen, tenemos representado un viejo conector serie RS232, que contiene los dos terminales de datos Rx y Tx. En nuestro arduino tambien disponemos de esos dos puntos mostrados como terminal 0 y 1 ( ver placa ).

Lo primero que vamos a hacer es instalar un programa en arduino para que, según la tecla pulsada, se encienda el led 13.

Las instrucciones que se usan para el puerto son:

 -begin(velocidad)    Se abre el puerto  y establece la velocidad al valor marcado entre paréntesis .Varia entre  9600bps a 115000bps. Para el Uno, mejor 9600.

-available()    Comprobamos el estado del buffer para ver si hay datos.

-read()    Lee un solo carácter (byte) del buffer.

-write()    Escribe  tantos caracteres como quieras en el buffer.

-print()    Imprime los datos al puerto serie como texto ASCII.

-println()    Imprime los datos al puerto serie  como print como texto ASCII con  retorno de carro

-flush()    Vacía el buffer de entrada de datos.

-end()    Para la comunicación serie. Al terminar, los pines 0(RX) y 1 (TX)  pueden ser usados por arduino como entradas o salidas digitales.

int lectura;
int led = 13;
void setup(){
Serial.begin(9600);
pinMode(led, OUTPUT);
}
void loop(){
//Comprobamos si existe datos disponibles y  los leemos
if (Serial.available()>0){

//leemos la opcion enviada
lectura=Serial.read();
if(lectura==’1′) {
digitalWrite(led, LOW);
Serial.println(“Led apagado”);
delay (500);
}
if(lectura==’2′) {
digitalWrite(led, HIGH);
Serial.println(“Led Encendido”);
delay (500);
}}}

 2º Conectar el módulo ESP 8266 a una red wifi
Lo que vemos arriba es una maravilla con un precio menor a 2 €. Está compuesto por un microcontrolador y 8 conexiones. Tenemos como siempre la alimentación, la entrada de datos ( Rx y Tx ), dos salidas GPIO y otros pines de configuración.
Es muy importante, remarcar que este chip funciona a 3,3 voltios, por tanto, tenemos que usar una alimentación externa para poder suministrar la corriente adecuada
 Paramos aquí, para incorporar un circuito con fritzing que incorpore el arduino, una fuente de alimentación de 3,3 y las conexiones Rx  y Tx a los terminales 2 y 3.
Importante. No hacer nada hasta leer todo este punto. Luego hacer las tareas que se indican.
Tenemos que usar una librería específica para control de este modulo y éstas
 librería se baja en éste enlace.
Este archivo tiene el nombre  ITEADLIB Arduino WeeESP8266,  y es bastante completa.
Hay que tener mucho cuidado , porque una vez que se instale,  no aparece en la carpeta general de libriries, sino en un listado un poco más abajo, que se indica como  contributed libraries
 Para localizar la librería , tenemos que ir a la ruta donde normalmente se instalan este tipo de librería ( habría que ver la configuración del programa ). Suele ser:
 Biblioteca -> Documentos -> arduino -> libraries
Cuando accedamos a ella, tenemos que eliminar un comentario para activar una función, tan  sencillo como quitar // en la linea
#define ESP8266_USE_SOFTWARE_SERIAL
Os dejo el archivo modificado, por si tenéis problema modificando la librería general esp8266.h.
Yo he usado una maravilla de editor, Lopetedit, que “abre hasta los archivos que vienen del espacio”.
 Hay un gran programador en en Zaragoza, que me ha ayudado a realizar esta práctica ( Luis LLamas ), pero al bajar su programa , encontramos que no funcionaba. Ese primer programa de comprobación lo tenemos en su pagína y es el que vamos a discutir.  Encontramos que ,  al cargar el programa, si ponemos SSID , veremos que el programa lo toma como una variable reservada, lo cual, provoca errores. Por eso , para llamar a la ssid, la llamamos con otro nombre.
Vamos ya a cargar el programa. Para ello, descargamos el archivo este archivo de  arduino y explicar las diferentes actuaciones
 Explicamos paso a paso los bloques que conforman el programa
 5.1 Lo primero es cargar unas librerías ( 3 ) , configurar la red wifi de nuestra casa y poner la página web donde vamos a tener el control Domótico del sistema. Para la página , me he registrado en hostinget, que ofrece un pack muy completo, pero al ser gratuito, tampoco podemos exigir demasiado.#include <doxygen.h>
#include <ESP8266.h>#include <SoftwareSerial.h>const char* SSIDE = “Celi”;
const char* PASSWORD = “contraseña de la red Celi”;
const char* HOST_NAME = “www.marenostrum.esy.es”;// Página web
const int HOST_PORT = 80; // puerto de conexión . Para web es el 80
SoftwareSerial softSerial(2, 3); // Pongo puertos 2 y 3 para RX, TX
ESP8266 wifi(softSerial); // Comunicacion para el módulo esp8266
 5.2 Segundo bloque de setup
void setup(void)
{Serial.begin(9600); // Ponemos la velocidad del puerto a 9600 baudios
pinMode(13, OUTPUT); // nuestro pin 13 a salida
/* Ahora veremos si establecemos comunicación con el módulo esp 8266 . Si tenemos exito, imprimimos el texto to station + softap ok  y si no tenemos exito, se muestra el texto to station + softap err. Vemos que aparece \r\n  y esto es para indicar que se termina y se salta de linea */
if (wifi.setOprToStationSoftAP()) {
Serial.print(“to station + softap ok\r\n”);
}
else {
Serial.print(“to station + softap err\r\n”);
}
/* Un pasito mas. Ahora vamos a comprobar si logramos conectar con la red wifi que usamos. En mi caso, la llamada como Celi. Como antes, si tenemos exito, se muestra el texto Hemos conectado con la red WIFI ,  junto a los datos de IP. En caso contrario, mostramos otro texto, por ejemplo: Uff, algo pasa. No tenemos conexión 

Un poco mas abajo tenemos otra comprobación de wifi.disableMUX. Esto, segun la documentación del módulo, dada en http://docs.iteadstudio.com/ITEADLIB_Arduino_WeeESP8266/class_e_s_p8266.html no indica que

Disable IP MUX(single connection mode).

In single connection mode, only one TCP or UDP communication can be builded.

*/
if (wifi.joinAP(SSIDE, PASSWORD)) {
Serial.print(“Hemos conectado con la red WIFI\r\n”);
Serial.print(“IP:”);
Serial.println(wifi.getLocalIP().c_str());
}
else {
Serial.print(“Uff, algo pasa. No tenemos conexión\r\n”);
}
if (wifi.disableMUX()) { // si tenemos única comunicación , se muestra OK
Serial.print(“single ok\r\n”);
}
else {
Serial.print(“single err\r\n”); // no se logra ünica TCP ( esta en multi TCP )
}
Serial.print(“setup end\r\n”); // fin del setup
}
 5.3 Lazo Loop

void loop(void)
{
uint8_t buffer[800] = { 0 }; // establecemos el buffer de datos inicial a 0

if (wifi.createTCP(HOST_NAME, HOST_PORT)) { // si tenemos conexión TCP a la web y en el puerto 80
Serial.print(“Conexión TCP ok\r\n”); // se imprime Conexión TCP ok
}
else { // en caso contrario
Serial.print(“mostramos error en la conexión tcp\r\n”); // mostramos error en la conexión tcp
}

/* Ahora se crea una variable , llamada request,  que posteriormente vamos a entrar al módulo para obtener la lectura de la página. La variación que hemos añadido es despues del GET/ que nos indica que no vamos a leer la página principal, sino otra de la que hablaremos, que se llama resultado.php. En esta página vamos a guardar toda la información que vamos a necesitar */

char *request = “GET /resultado.php HTTP/1.1\r\nHost: marenostrum.esy.es\r\nConnection: close\r\n\r\n”;

 

wifi.send((const uint8_t*)request, strlen(request)); // mandamos la solicitud a la página

uint32_t len = wifi.recv(buffer, sizeof(buffer), 10000); / tomamos la longitud del buffer recibido
if (len > 0) // si hay lectura, ( buffer con datos )
{
Serial.print(“Datos recibidos de la web:\r\n”); // Mostramos Datos recibidos de la web

/* Aunque no es necesario, vamos a explicar que es eso de uint32_t , o  uint8_t*. Este viene a decir cómo se deben tratar los datos que se reciben.

  1. La U vienen de tipo unsigned, o sea, no está definido
  2. lo siguiente ( int ) nos indica que es un valor entero
  3. El numero que lo acompaña, 8, 16, 32, etc, hace referencia a los bits utilizados
  4. Por último,  _t  nos dice que el tamaño es estandar para todas las plataformas

*/

for (uint32_t i = 0; i < len; i++)
{
char c = (char)buffer[i];

/* Para leer una parte concreta de la información que nos llega, hemos añadido el gusanillo como comodín de entrada, de forma que si llegamos a encontrar ese valor, empezamos a crear un array con todo el texto que haya entre el gusalillo de entrada y salida */

if (c == ‘~’)
{
for (uint32_t j = i + 1; j < len; j++)

/*

aquí, el valor de partida del contador j es el siguiente al valor detectado en el gusalillo, o sea, que si en el anterior de i, vemos que el gusanillo tiene la posición 45, el valor de j, será 46 y a partir de ese valor, se irán tomando datos */
{
c = (char)buffer[j];
if (c == ‘1’) // Si detectamos que hay un 1, damos orden de encender el LED 13
{ digitalWrite (13, HIGH);}
if (c == ‘0’) // Si aparece el 0, apagamos el LED 13
{ digitalWrite (13, LOW);}
// else { digitalWrite (13, LOW);}
if (c == ‘~’) break; // si se detecta el gusanillo, cerramos el array en imprimimos c
Serial.print(c);
}
break;
}

}

Serial.print(“\r\n”); // imprimimos salto de carro
}

//while (1) delay(1000); // esto lo hemos quitado
delay(1000); // esperamos un segundo para tomar la siguiente lectura.- Por si la cosa ha cambiado
}

 Por último, en nuestros test vemos que hay veces que le cuesta mucho trabajo conectar con la red. Parece que tiene que ver con el orden de entrada de los módulos. Es mejor encender el arduino y posteriormente el modulo esp8266. Si se hace al contrario, nos da problemas.
Páginas web
El siguiente paso es hacer nuestra página web, que estará formada por tres archivos
  1. index.php . Esta página contiene los formularios de actuación. En nuestro caso empezamos con un encender apagar de led. Lo podemos ver en http://marenostrum.esy.es/
  2.  led.php  Esta página toma las variables enviadas por index.php para hacer una grabación de datos en la base de datos
  3. db.php . En este archivo se tenemos la configuración de la base de datos ( datos y claves )
  4. resultado.php. Esta página, cada vez que la llamamos, hace una petición sql a la base de datos, para mostrar las variables  que necesita arduino para  encender o apagar el led

Todas ellas, las podemos bajar en  el ENLACE WEB 

Base de datos
Como dijimos antes, lo primero es crearse una cuenta en la empresa hostinger. Una vez que tenemos las claves y la página url generada en el proceso de alta, vamos al panel de administración y creamos la base de datos mysql. Esta base va a tener 4 valores importantes, que son:
  • Donde está. En este caso, viene como Host Mysql, y nos dice que  la base está alojada en mysql.hostinger.es. Otras veces suele poner localhost
  • Cómo se llama la base de datos.
  • Cómo se llama el usuario de la base de datos
  • La contraseña de ese usuario

Con esos 4 datos, no podemos conectar a la base de datos y, esos datos tienen que estar guardados en el archivo db.php

Tenemos ya la base creada, pero no tenemos la tabla. Por ello, tenemos que ir dentro de las herramientas del panel de control de hostinger , a la sección de base de datos y phpmyadmin
Entramos para crear nuestra tabla , de nombre “datos”
Una vez dentro, pinchamos en la pestaña sql y añadimos este código
  • CREATE TABLE IF NOT EXISTS `datos` (
    `id` int(11) NOT NULL,
    `led` tinyint(4) NOT NULL
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  • INSERT INTO `datos` (`id`, `led`) VALUES
    (1, 0);

8 Archivo de grabar los datos ( led.php )

Si lo abrimos, tenemos el código por excelencia utilizado en el mundo web, el PHP . pasamos a comentar algunas cosillas.

Lo promero , se abre con las etiquetas <?php, luego decimos que inicie una sesión “session_start();”, lo cual no es obligatorio, pero necesario en nuestro caso para pasa crear variables de sesión, luego incluimos el archivo db.php con los datos de conexión y después una serie de lineas para saber si hemos tenido éxito en la conexión.

En la linea if, vemos si del formulario de contacto, recibimos la variable $_POST[‘encender’], que tendrá el valor encender si alguien en el formulario ha pinchado en ese botón ( luego lo veremos ).

En caso afirmativo, se graba el dato en la base de datos “resultado.php ”  utilizando laa lineas

1º $sql = “UPDATE datos SET led=1 WHERE id = 1 “;

2º mysqli_query($link, $sql);

La 1º se crea la variable de texto $sql con el valor que se muestra, diciendo que se actualice la tabla datos poniendo (SET) el registro led a 1, donde( WHERE )  el id es 1

La 2º linea nos dice que conectemos a la base de datos y volquemos ese texto $sql

Ademas , aparece $_SESSION[“led”]=1. Esto no dice se crea una variable , llamada $_SESSION[“led”], que va a ser siempre 1, independientemente de qué pagina de nuestro proyecto estemos. Ese valor será recogido luego por la página del formulario para mostrarlo en pantalla.

Lo mismo podemos decir para el resto del programa. La última linea de header nos manda a la pagina principal, pasado dos segundos

<?php
session_start();
include(“db.php”);

$link = mysqli_connect($db_host, $db_user, $db_pass, $db_name);
// mysqli_set_charset($link,’utf8′);
mysqli_set_charset($link,’iso-8859-1′);
/* verificar la conexión */
if (mysqli_connect_errno()) {
printf(“Conexión fallida: %s\n”, mysqli_connect_error());
exit();
}
if ($_POST[‘encender’] ==”encender”)
{
$sql = “UPDATE datos SET led=1 WHERE id = 1 “;

mysqli_query($link, $sql);

echo “Encendemos el LED”;
$_SESSION[“led”]=1;
}

if ($_POST[‘apagar’] ==”apagar”)
{
$sql = “UPDATE datos SET led=0 WHERE id = 1 “;

mysqli_query($link, $sql);
echo “Apagamos el LED”;
$_SESSION[“led”]=0;
}

header( “refresh:2; url=http://marenostrum.esy.es/” );
?>

 

Mas info enhttps://www.luisllamas.es/arduino-wifi-esp8266-esp01/