Dispositivo básico - Jusaba/Domo-Serverpic GitHub Wiki
Como se decía en la introducción a los dispositivos, existe una estructura básica para el diseño del del software de los dispositivos que se detalla en este apartado.
En la siguiente figura se describe el diagrama de flujo de esa estructura.
El diagrama de flujo se ha dividido en los dos bloques típicos utilizados en Arduino: Setup() y Loop()
El el bloque setup() se configuran los terminales del módulo y se gestiona el arranque
Cuando arranca el módulo, lo primero que se hace es cargar las librerias y los ficheros de configuración, inmediatamente después, recupera el flag de configuración grabado en EPROM, si el flag es 0, entiende el módulo que no está configurado y se pone en modo AP creando una red wifi Jusaba con password 24081960. Conectandose a esa red con un terminal en la dirección 192.168.4.1 se nos presenta un formulario de configuración que deberemos rellenar con los datos de la SSID, la ubicación de Serverpic y el nombre que deseamos para este dispositivo una vez se conecte a Serverpic. Con los datos rellenados, enviamos el formulario al módulo, este los almacenará en la Erpom para establecer la conexión, al mismo tiempo, se pone el flag de configuración a 1 para indicar al módulo en el próximo arranque que ya está configurado.
Si cuando arranca el módulo, el flag de configuración está a 1 el módulo entiende que ya fué configurado, entonces, se recuperan de la Eprom los datos de conexión a la SSID y se intenta conectar, si la conexión es satisfactoria, se recuperan los datos de conexión a Serverpic y se establece esa conexión. Una vez conectado a Serverpic, se chequea la versión del último firmware publicado y se actualiza si es necesario, luego se recuperan otros datos de configuración que indicará al módulo si tiene que interactuar con HomeKit y WebSocket y si tiene que gestionar estadisticas de arranques, perdidas de conexión y recepción de comandos. El siguiente paso es recuperar el ultimo estado en el que se encontraba el dispositivo en la última parada y restablecerlo a ese estado, esto es útil para cuando el dispositivo se desconecto por un fallo de red electrica ( por ejempolo ). Cuando el dispositivo se inicia por primera vez, no existe ultimo valor y recibe del servidor el texto ERROR.
En el bloque loop() se supervisa el botón de reset, la conexión con el seervidor y se interactua con el. En primer lugar, se comprueba si el botón de reset está pulsado y, en caso de que esté pulsado comprueba si es una pulsación corta que hace que el módulo se reinicie o una pulsación larga que restablece el módulo a sus condiciones de fábrica. Si el reset no está pulsado, se comprueba si existe conexión con Serverpic y si se ha perdido la conexión hace intentos de reconexión hasta que lo consigue. Si la conexión es correcta, comprueba si se ha recibido algún mensaje de Serverpic testeadno el flag oMensaje.lRxMensaje y, si se ha recibido actuará en consecuencia, esto es interactuar con Serverpic. Por último, se refresca el WDT.
A continuación se detalla el código de ambos bloques
//----------------------------------
// Carga de Librerias
// Carga ficheros de configuración
//----------------------------------
#include "ServerPic.h"
#include "IO.h"
void setup() {
#ifdef Debug
Serial.begin(9600);
Serial.println("Iniciando........");
#endif
//----------------------------------
//Inicializa Eprom
//----------------------------------
EEPROM.begin(128);
//----------------------------------
//Pin de Reset
//----------------------------------
pinMode(PinReset, INPUT_PULLUP);
//----------------------------------
//Lee el Flag de configuracion
//----------------------------------
if ( LeeByteEprom ( FlagConfiguracion ) == 0 )
{
//-------------------------------------------
//Si es 0 se pone en modo AP para la configuracion
//Se crea la red Jusaba con passwoer 24081960
//Conectandosnos con terminal e esta red a la direccion 192.168.4.1
//Se presenta formulario de configuracion
//-------------------------------------------
ModoAP();
}else{
//-------------------------------------------
//Si es 1, ponemos el modulo en modo STA
//Se leen datos de configuracion y se conecta a la SSID
//-------------------------------------------
if ( ClienteSTA() )
{
//-------------------------------------------
//Si se ha conectado a la SSID
//Leemos la configuracion de la conexion a
//Serverpic y establecemos conexion
//------------------------------------------
if ( ClienteServerPic () )
{
//-------------------------------------------
//Chequeamos si existe actualizacion firmware
//-------------------------------------------
CheckFirmware();
#ifdef Debug
Serial.println(" ");
Serial.println("Conectado al servidor...");
#endif
//-------------------------------------------
//Leemos los datos de configuracion
//cDispositivo, lHomekit,lWebSocket, lEstadisticas
//-------------------------------------------
DataConfig aCfg = EpromToConfiguracion ();
char USUARIO[1+aCfg.Usuario.length()];
(aCfg.Usuario).toCharArray(USUARIO, 1+1+aCfg.Usuario.length());
cDispositivo = USUARIO;
lHomeKit = aCfg.lHomeKit;
lWebSocket = aCfg.lWebSocket;
lEstadisticas = aCfg.lEstadisticas;
//-------------------------------------------
//Si están habilitadas las estadisticas
//Se actualiza el numero de reinicios
//-------------------------------------------
if ( lEstadisticas )
{
GrabaVariable ("inicios", 1 + LeeVariable("inicios") );
}
}
}
}
//---------------------------------------------------------
//Recuperamos el ultimo estado antes de que se desconectara
//Si no se había registrado estado, ejecuta un proceso
//particular
//---------------------------------------------------------
cSalida = LeeValor();
if ( cSalida == "ERROR")
{
//*******************************
//Proceso si no se almacenó último
//valor en la desconexión
//*******************************
}else{
//*******************************
//Proceso que pone el dispositivo
//en un estado en fucnión del
//contenido del ultimo valor
//*******************************
}
}
void loop() {
TestBtnReset (PinReset);
if ( TiempoTest > 0 )
{
if ( millis() > ( nMiliSegundosTest + TiempoTest ) )
{
nMiliSegundosTest = millis();
if ( !TestConexion() )
{
//**********************************************************************
//Aqui pondremos las acciones a ejecutar si se pierde la conexion
//Por ejemplo, se puede poner el dispositivo controlado en off que seria
//el estado deseado cuando perdemos la conexion y no lo podemos
//telecontrolar
//**********************************************************************
}
}
}
oMensaje = Mensaje ();
if ( oMensaje.lRxMensaje)
{
//*******************************************************************************
//En este punto empieza el bloque de programa particular del dispositivo según la
//utilización
//Se analiza el mensaje recibido y se actúa en consecuencia
//*******************************************************************************
}
wdt_reset();
}
Para la creación del software de un dispositivo será necesario el progarma ino con los apartados setup() y loop() descritos y, además, será necesario de crear los ficheros de cabecera serverpic.h e IO.h. El primero de ellos, Serverpic.h, en el primero de sus bloques contiene la carga de las librerias serverpic mencionadas anteriormente, el segundo bloque contiene la declaración de variables comunes a todos los módulos ( Universales ), a continuación, en el siguiente bloque se declaran las variables particulares para el módulo en cuestión, el siguiente bloque contiene las características del dispostivo ( ESP utilizado, nombre del ino, hardware, versión de compilación ), en otro bloque se definen las características del compilador, seguidamente se declaran unos defines para condicionar la compilación de funciones para Debug, HomeKit y WebSocket, se estalece el tiempo de test de conexión ( cada cuanto tiempo se harán las comprobaciones de conexión a Serverpic em el bloque setup()), luego se definen unas variables para transferir parametos del módulo a las Librerías Serverpic y por último se desarrollan las funciones particulares para el módulo que utilizará el programa principal.
Esta sería la estructura básica del fichero serverpic.h
#ifndef SERVERPIC_H
#define SERVERPIC_H
//----------------------------------------------
//Include
//----------------------------------------------
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include "Global.h"
#include "Configuracion.h"
#include "Eprom.h"
#include "ModoAP.h"
#include "ModoSTA.h"
#include "Servidor.h"
//----------------------------
//Declaracion de variables UNIVERSALES
//----------------------------
ESP8266WebServer server(80);
WiFiClient Cliente;
Telegrama oMensaje;
String cDispositivo = String(' ');
String cSalida;
boolean lEstado = 0;
boolean lConexionPerdida = 0;
boolean lHomeKit;
boolean lWebSocket ;
boolean lEstadisticas;
unsigned long nMiliSegundosTest = 0;
//-------------------------------------------
//Declaración de variables PARTICULARES
//-------------------------------------------
//Aquí se declaran las variables particulares
//del programa principal
//----------------------------
//CARACTERISTICAS DISPOSITIVO
//----------------------------
#define ESP12 //Modelo de ESP8266
#define Ino "basico" //Nombre del programa principal
#define VIno "1.0" //Version del programa principal
#define Placa "Nodemcu" //Placa utilizada
#define VBuild "1" //Versión compilación
//---------------------------------
//CARACTERISTICAS DE LA COMPILACION
//---------------------------------
#define Compiler "Stino"; //Compilador
#define VCore "2.5.2"; //Versión del Core Arduino
#include "IO.h";
//----------------------------------------------
//DEBUG
//----------------------------------------------
#define Debug
//----------------------------------------------
//HOME KIT
//----------------------------------------------
#define HomeKit
//----------------------------------------------
//Teimpo de Test de conexion
//----------------------------------------------
#define TiempoTest 14000 //Tiempo en milisegundos para Test de conexion a servidor
//----------------------------------------------
//TiEmpo de rebotes
//----------------------------------------------
#define TempoRebotes 150
//----------------------------------------------
//Web Socket
//----------------------------------------------
#define WebSocket
//--------------------------------------------------------------------------
//Variables donde se almacenan los datos definidos anteriormente para
//pasarlos a Serverpic.h para mandar la información del Hardware
//y Software utilizados.
//En la libreria ServerPic.h estan definidos como datos externos y se
//utilizan en la funcion Mensaje () para responder al comando generico #Info.
//Con ese comando, el dispositivo mandara toda esta información al cliente
//que se lo pida
//ESTOS DATOS NO SON PARA MODIFICAR POR USUARIO
//--------------------------------------------------------------------------
//Datos del programa principal
String VMain = VIno;
String Main = Ino;
String VModulo = VBuild;
//Datos de compilación
String Compilador = Compiler;
String VersionCore = VCore;
//Datos de Hardware
String ModeloESP = Modelo;
String Board = Placa;
//-------------------------------------------
//Desplieque de funciones PARTICULARES
//-------------------------------------------
//Aquí se ubican las funciones auxiliares añadidas al
//añadidas al programa principal
El segundo de los ficheros, IO.ino contiene la asignación de pins's que se utilizarán en el dispositivo en función del modelo ESP utilizada en el hardware.
#ifndef IO_H
#define IO_H
#ifdef ESP01
#define Modelo "ESP01"
int PinReset = 0;
//Resto de PIN's utilizados en ESP01
#endif
#ifdef ESP11
#define Modelo "ESP11"
int PinReset = 0;
//Resto de PIN's utilizados en ESP11
#endif
#ifdef ESP12
#define Modelo "ESP12"
int PinReset = 4;
//Resto de PIN's utilizados en ESP12
#endif
#endif
Bien pues todo lo aquí expuesto, es la base de los dispositivos que se crearán para operar en Serverpic, es psible que todo esto resulte algo confuso y espeso pero, en cuanto se detalle el hardware software del módulo específico Alimentador USB quedará todo mucho más claro.