la vita di un maker non è facile, quando pensi di aver risolto i tuoi dilemmi ecco che se ne presenta uno nuovo e più grande di te e ti chiedi: ma perchè mi ostino a costruirmele da me le cose, comprale già fatte che è più semplice!
Ieri notte la mia linea internet è andata giù e quindi tutti i miei dispositivi connessi, basati su EPS8266 non erano raggiungibili.
Quello che ho notato guardando il mio router è che durante il fermo rete, la portante internet dalla centrale era inesistente ma il wi-fi c'era per cui i miei oggetti continuavano ad avere un IP assegnato dal router e a riprova di ciò WL_CONNECTED era true.
Nei miei progetti uso la libreria <WiFiManager.h> che gestisce i paramenti rete e altre cosette e poi "parlo" con i miei oggetti attraverso telegram usando "AsyncTelegram.h" . Nei setup() uso sempre la funzione **WiFi.setAutoReconnect(true); **che tenta in caso di perdita rete una riconnessione, se non mi sbaglio, ogni secondo.
Vengo al fattaccio: per le 12 h del blocco internet che ho avuto, immagino che **WiFi.setAutoReconnect(true); **abbia costantemente cercato di riconnettere l'esp causando in un progetto, il rallentamento del codice al punto che il display SSD1309 che gestisco con <U8g2lib.h> ed alcuni pulsanti che gestisco con interrupt, sono diventati lenti quasi inutilizzabili. Poi tornata la connessione l'esp si è riconnesso o forse sarebbe meglio dire ha avuto nuovamente accesso a internet, (in quanto mai disconnesso dal wi-fi,) e tutto il codice è tornato ad essere reattivo.
Questo strano comportamento riesco a riprodurlo semplicemente staccando il doppino telefonico che va al router.
Che voi sappiate, esiste un modo per gestire questi casi in cui manca il wi-fi o la portante e dire all'esp di tentare a riconnettersi ogni 10 secondi così da lasciare che il codice non rallenti?
Grazie a chi vorrà spendere due parole per fugare la marea di dubbi che ho in questo istante.
Non credo che il problema sia legato all'autoreconnect, ma piuttosto alla libreria AsyncTelegram.
Quando l'esp richiama l'API Telegram getUpdates per vedere se ci sono nuovi messaggi, esegue una verifica della connessione con il server Telegram e se non connesso tenta di istanziare una nuova connessione con l'istruzione *client.connect(uri, port) *che purtroppo credo sia bloccante (dovrebbe avere un timeout).
Prova a simulare di nuovo commentando tutto il blocco if (myBot.getNewMessage(msg)) {} e se il rallentamento sparisce vuol dire che dipende da quello.
In caso positivo, non vedo modi "semplici" per risolvere ahimé
Forse facendo un ping (non supportato in modo nativo dall'esp) prima di richiamare il metodo?
Ciao, dunque ho appena simulato il "guasto" internet e commentando il blocco che mi hai indicato, senza internet, il codice è filato liscio e sia display e i pulsanti sono reattivi e perfettamente funzionanti.
Io riesco a pensare solo a questo:
if ((millis() - tempo_ping) >= 1250) {
if (myBot.getNewMessage(msg)) {
// codice
}
tempo_ping = millis();
}
che in assenza di rete in effetti almeno non fa bloccare del tutto il display e i pulsanti, ma li rallenta di brutto. Mentre quando c'è rete invece rallenta purtroppo un pochino la comunicazione con telegram, ed un peccato visto la reattività della tua libreria. Idee per limitare questo grave inconveniente?
Serve una soluzione più elegante...ma io non ne sono capace.
Potresti fare il ping ad un server che è sicuramente sempre online tipo il DNS primario di Google con indirizzo ip 8.8.8.8
Se il server risponde al ping, sicuro c'è connessione.
Magari il ping lo fai una volta ogni tot secondi ed imposti una variabile bool che poi metti in and con getNewMessages().
#include <ESP8266WiFi.h>
#include <ESP8266Ping.h>
const char* ssid = "xxxx";
const char* password = "xxxxxx";
const IPAddress remote_ip(8, 8, 8, 8);
unsigned long tempo_ping = 0;
bool flag_ping = false;
void setup() {
Serial.begin(115200);
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.println("Connecting to WiFi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println();
Serial.print("WiFi connected with ip ");
Serial.println(WiFi.localIP());
Serial.print("Pinging ip ");
Serial.println(remote_ip);
}
void loop() {
if ((millis() - tempo_ping) >= 5000) {
if (Ping.ping(remote_ip)) {
Serial.println("ping OK!!");
flag_ping = true;
} else {
Serial.println("ping KO");
flag_ping = false;
}
tempo_ping = millis();
}
Serial.println("vediamo se è bloccante");
delay(1000);
}
per verificare il ping impiega circa 3-4 secondi in cui immagino sia bloccante, ma è accettabile direi. Alla luce di ciò, ogni quanti secondi faresti il ping? Io pensavo a 60 secondi.
Allora, ho dato un'occhiata più approfondita alla libreria.
Di default prova ad eseguire un massimo di 5 ping distanziati di 1 secondo tra loro.
Se gli passi il parametro per farne 1 solo hai una risposta molto più reattiva.
Facendo una prova al volo con il tuo sketch leggermente modificato, ho misurato tempi tra i 40 e 80 ms con la connessione di uno smartphone attiva ed poco più di 1 secondo con i dati disattivati (immagino ci sia un timeout perché è costante a 1016 ms).
Per quanto riguarda l'intervallo di tempo, non saprei sinceramente. Dipende da quanto spesso accade che rimani senza internet ed hai la necessità di dover interagire con il dispositivo.
if (flag_ping == true) { // per prima cosa controllo se c'è ping sulla rete
if (myBot.getNewMessage(msg)) { // poi controllo se ci sono nuovi messaggi
......
così no:
if (flag_ping == true) && (myBot.getNewMessage(msg)) {
...
Adesso lo tengo in prova e vediamo quanto potrò stare tranquillo
A parte gli errori di sintassi, il codice era stato comunque compilato bene, poi l'ho trascritto male qui, ma non va comunque, nel senso che continua bloccare il codice se manca la rete perchè immagino che myBot.getNewMessage(msg) viene comunque scomodato ed interrogato e blocca il codice ....
Si in effetti in quel modo la funzione viene eseguita a prescindere dal valore di flag_ping.
Quindi ci sta che non sia il modo adatto allo scopo, però non va in eccezione giusto?
No, direi che sta andando bene, ho impostato il ping ogni 5" per fare dei test durante la pausa pranzo e devo dire che con o senza rete il codice scorre sempre fluido. Conto di tenerlo in prova ancora qualche giorno e poi imposto il ping ogni mezz'ora.