Parte 3/4
Un’altra caratteristica che ho voluto implementare sul software della scheda è quella che somiglia, alla lontana, al concetto di Master Page implementato in .NET. Ho voluto cioè comporre le pagine con una parte comune a tutte all’interno della quale inserire un contenuto diverso per ogni pagina ( vedi parte alta di ogni pagina riportata ). Oltre a risparmiare parecchia memoria per il codice si ha il vantaggio, se serve, di dover modificare una sola volta la parte comune. Con un approccio più tradizionale ogni pagina avrebbe contenuto anche la parte comune ed una variazione su questa parte avrebbe comportato la necessità di variarla su tutte le pagine.
Per fare queste operazioni uso variabili del tipo String. So che tutti concordano sul fatto che l’utilizzo di questo tipo di dato su Arduino non sia consigliato ma ne trovo l’utilizzo molto pulito ed intuibile. Oltre a questo le dimensioni della memoria sull’Esp32 non sono così limitate come su un ATMega328 ed inoltre ho letto che sull’Esp32 gira un RTOS che si occupa anche del Garbage Collection.
#include <EEPROM.h>
#include <WiFi.h>
#include <WebServer.h>
#include <Update.h>
#include "Wire.h"
#include "VariabiliGlobali.h"
#include <WebSocketsServer.h>
TaskHandle_t Task1;
#include <DS3231M.h>
DS3231M_Class RTC;
WebServer httpServer(80);
WebSocketsServer webSocket = WebSocketsServer(1337);
String StringaRicevuta = "";
void onWebSocketEvent(uint8_t client_num, WStype_t type,uint8_t * payload, size_t length)
{
switch(type)
{
case WStype_DISCONNECTED:
Serial.printf("[%u] Disconnected!\n", client_num);
break;
case WStype_CONNECTED:
{
IPAddress ip = webSocket.remoteIP(client_num);
Serial.printf("[%u] Connection from ", client_num);
Serial.println(ip.toString());
webSocket.broadcastTXT("StatoIngressi:" + String(StatoIngressi));
webSocket.broadcastTXT("StatoUscite:" + String(StatoUscite));
}
break;
case WStype_TEXT: // quando ricevo una stringa dal client Web....
StringaRicevuta = String((char *)payload);
if (StringaRicevuta.startsWith("StatoIngressiWeb:"))
{
StringaRicevuta.replace("StatoIngressiWeb:","");
StatoIngressiWeb = StringaRicevuta.toInt();
}
else if (StringaRicevuta.startsWith("SetTime:"))
{
StringaRicevuta.replace("SetTime:","");
SetTime(StringaRicevuta);
}
else if (StringaRicevuta.startsWith("SaveInConf:"))
{
StringaRicevuta.replace("SaveInConf:","");
Save_In_Conf(StringaRicevuta);
}
else if (StringaRicevuta.startsWith("ResetInConf:"))
{
StringaRicevuta.replace("ResetInConf:","");
Reset_In_Conf();
}
else if (StringaRicevuta.startsWith("SaveTimerConf:"))
{
StringaRicevuta.replace("SaveTimerConf:","");
Save_Timer_Conf(StringaRicevuta);
}
else if (StringaRicevuta.startsWith("ResetTimerConf:"))
{
StringaRicevuta.replace("ResetTimerConf:","");
Reset_Timer_Conf();
}
else if (StringaRicevuta.startsWith("SaveAPConf:"))
{
StringaRicevuta.replace("SaveAPConf:","");
Save_AP_Conf(StringaRicevuta);
}
else if (StringaRicevuta.startsWith("ResetAPConf:"))
{
StringaRicevuta.replace("ResetAPConf:","");
Reset_AP_Conf();
}
else
{
Serial.println("[%u] Message not recognized");
}
break;
Serial.print(" StringaRicevuta.replace : "); Serial.println(StringaRicevuta);
case WStype_BIN:
case WStype_ERROR:
case WStype_FRAGMENT_TEXT_START:
case WStype_FRAGMENT_BIN_START:
case WStype_FRAGMENT:
case WStype_FRAGMENT_FIN:
default:
break;
}
}
String MasterPage = "<!DOCTYPE html PUBLIC '-//W3C//DTD ……… (5.077 byte) ..…..</div></body></html>";
void PaginaHome()
{
String NewPage = MasterPage;
NewPage.replace("<!--|Contenuto Pagina| -->","<div><div><table…... (4.065 byte) ……);}</script>");
httpServer.send(200, "text/html", NewPage);
}
void PaginaOTA()
{
String NewPage = MasterPage;
NewPage.replace("<!--|Contenuto Pagina| -->","<div class='St3'><……… (2.411 byte) …. script>");
httpServer.send(200, "text/html", NewPage);
}
void PaginaSSR_Array()
{
String NewPage = MasterPage;
ConfigurazioneIngressi = Get_In_Conf();
NewPage.replace("<!--|Contenuto Pagina| -->","<script type='text/javascript'……(7.315 byte) …….;}}</script>");
httpServer.send(200, "text/html", NewPage);
}
void PaginaAccessPoint()
{
String NewPage = MasterPage;
ConfigurazioneAP = Get_AP_Conf(&AP);
NewPage.replace("<!--|Contenuto Pagina| -->","<script type='text/javascript' ……… (2.240 byte) ….}</script>");
httpServer.send(200, "text/html", NewPage);
}
void PaginaTimer()
{
String NewPage = MasterPage;
ConfigurazioneTimer = Get_Timer_Conf();
NewPage.replace("<!--|Contenuto Pagina| -->","<script type='text/…… (6.687 byte) ..….}</script>");
httpServer.send(200, "text/html", NewPage);
}
void PaginaNonTrovata()
{
httpServer.send(404, "text/plain", "Pagina non trovata");
UltimaPaginaAperta = "Errore";
}
void Codice_Task1( void * pvParameters )
{
Serial.print("Task1 running on core ");
Serial.println(xPortGetCoreID());
for(;;)
{
uint16_t ValoreAlimentazione = analogRead(PinControlloAlimentazione);
if ( ValoreAlimentazione < ValoreMinimaTensioneAlimentazione ) // Limite tensione sotto alla quale salvare le variabili in EEProm
{
SalvaParametriInEEProm_PerMancanzaAlimentazione();
Serial.print("ValoreAlimentazione = ");Serial.println(ValoreAlimentazione);
}
Verifica_BlinkLed_NoDelay();
}
}
void setup()
{
for (uint8_t Cont = 0; Cont < 8; pinMode(PinIn[Cont++], INPUT_PULLDOWN));
for (uint8_t Cont = 0; Cont < 8; pinMode(PinOut[Cont++], OUTPUT));
pinMode(PinControlloAlimentazione, INPUT);
pinMode(PinReset, INPUT_PULLUP);
pinMode(PinStatusLed, OUTPUT);
// Altro codice non riportato
}
void loop()
{
webSocket.loop();
httpServer.handleClient();
// Altro codice non riportato
// Se un pulsante d'ingresso viene premuto per almento 6 secondi .......
{
WiFi.mode(WIFI_AP);
delay(200);
boolean EsitoConf = WiFi.softAPConfig(AP.IP, AP.Gateway, AP.Subnet);
delay(200);
boolean EsitoAtt = WiFi.softAP(AP.ssid.c_str(), AP.password.c_str());
delay(200);
if (EsitoConf == true && EsitoAtt == true) Serial.println("Ready"); else Serial.println("Failed!");
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: "); Serial.println(myIP); Serial.println("HTTP server started");
delay(200);
httpServer.on("/", HTTP_GET, PaginaHome);
httpServer.on("/Home.htm", HTTP_GET, PaginaHome);
httpServer.on("/SSR_Array.htm", HTTP_GET, PaginaSSR_Array);
httpServer.on("/AccessPoint.htm", HTTP_GET, PaginaAccessPoint);
httpServer.on("/Timer.htm", HTTP_GET, PaginaTimer);
httpServer.on("/AggiornamentoOTA.htm", HTTP_GET, PaginaOTA);
// Altro codice non riportato
httpServer.onNotFound(PaginaNonTrovata);
httpServer.begin();
webSocket.begin();
webSocket.onEvent(onWebSocketEvent);
}
// Altro codice non riportato
}
Continua.....