Ri-connessione WiFi senza bloccare il loop

Buongiorno e buone vacanze (per chi è in vacanza!).

Sto cercando (senza per ora riuscirci) di trovare un modo per riconnettere (in caso di perdita della connessione) il mio NODEMCU (oppure ESP32) al wifi senza bloccare il loop.

Utilizzo la classicissima forma:

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

Ovviamente il while blocca il codice finché non avviene la connessione.
Per mitigare il problema ho aggiunto un contatore, ad ogni loop del while incrementa la mia variabile ed una volta arrivata a 30 forzo l'uscita dal loop while.
Attendo 5 minuti e riprovo ad effettuare la connessione.

Il mio problema è che durante l'attesa della connessione (loop while) tutto si blocca li e se ad esempio premo un pulsante pr accendere un led o se arriva un dato da un sensore questi vengono ignorati.

Esiste un modo per effettuare il "WiFi.begin" senza bloccare il loop?

Grazie

Non sò rispondere direttamente. Ma penso che ci voglia sempre un certo minimo di tempo al comando per ricollegarsi

Comunque, prova a leggere qui:
https://www.esp8266.com/viewtopic.php?f=32&t=16241

Grazie Nid.
Si, ci vuole un minimo di tempo per la connessione, volevo proprio vedere se è possibile sfruttare quel tempo per altro :smiley:

Ora do un'occhiata al link.

Ancora grazie

nid69ita:
Comunque, prova a leggere qui:
[SOLVED] How to re-connect Wifi with a non-blocking fashion? - Everything ESP8266

L'esempio funziona con ESP8266 (Utilizza la libreria ESP8266WiFi.h) ma ovviamente non funziona con ESP32.
Vediamo se c'è soluzione anche a questo...

Secondo me i comandi della libreria WiFi sono uguali tra esp8266 e esp32 (almeno spero :slight_smile:

Purtroppo pare di no...
Nel link che mi hai girato dice:
Methods and properties described in this section are specific to ESP8266. They are not covered in Arduino WiFi library documentation. Before they are fully documented please refer to information below.
Esp32 utilizza WiFi.h (per esp32) e non mi è possibile dichiarare questi eventi:
WiFiEventHandler gotIpEventHandler, disconnectedEventHandler;

Va detto che io sono un ignorante astronomico in materia quindi...

khriss75:
Esiste un modo per effettuare il "WiFi.begin" senza bloccare il loop?

WiFi.begin non blocca il loop.... a bloccarlo è quel while. A te serve quel while? Non fa altro che controllare lo stato prima di proseguire. E' una cosa che a te personalmente serve fare?

Seconda cosa, per quanto ne so la connessione ritorna comunque in piedi da sola anche senza rifare il begin.

Ciao Claudio, grazie per l'interessamento.
Sinceramente non riesco a comprendere la tua domanda.
So benissimo che a "bloccare" il ciclo è il while e che serve per verificare se è avvenuta la connessione wifi, però omettendolo (il while) senza il blocco del codice avverrebbe comunque la connessione?

Io ho ovviamente bisogno che la connessione wifi avvenga, semplicemente se per qualsiasi motivo si dovesse disconnettere, ho la necessità che si riconnetta (anche dopo x minuti). La cosa importante è che durante la riconnessione non si blocchi il ciclo.

Sinceramente ho trovato anch'io qualche info riguardo la "riconnessione automatica" in caso di disconnessione.

Grazie anche a te per il supporto!

khriss75:
però omettendolo (il while) senza il blocco del codice avverrebbe comunque la connessione?

Come detto la connessione va in piedi col begin. Verificare l'avvenuta connessione serve solo se si deve fare qualcosa per cui la connessione deve essere obbligatoriamente già attiva. Ma a quel punto allora basta verificare lo stato nel momento in cui si deve fare quella cosa, mentre tutto il resto può proseguire liberamente.

La riconnessione avviene sicuramente in modo automatico, almeno entro pochi minuti o poche decine di minuti, non so se ci sono timeout più lunghi.

Perfetto. Ho in effetti verificato quanto dici ed è così (sto utilizzando ESP32).
Approfitto della tua gentilezza (e competenza!!!) Hai mai avuto a che fare con MQTT (libreria pubsudclient)?
Se il client mqtt non è connesso ho anche in questo caso un blocco del loop. Tu hai mai affrontato questo discorso?

khriss75:
Hai mai avuto a che fare con MQTT (libreria pubsudclient)?

No, per cui non so se ad essere bloccante è una specifica funzione della libreria, o solo il modo in cui la usi (tipo il while di cui si parlava prima che potrebbe ovviamente essere riscritto in modo non bloccante).

Non uso while, è proprio la libreria pubsubclient che stoppa per 5 secondi in attesa della connessione. Devo provare altre librerie.
Grazie.

Secondo me devi evitare il comando di MQTT se non c'e' connessione.
Mi pare ovvio che il comando ci prova a inviare ma se non c'e' collegamento ci prova per un pò (magari puoi abbassare il timeout ma non "azzerarlo")
Evitalo, ovvero devi usare degli if (WiFi.status() == WL_CONNECTED) allora faccio

Il delay non avviene quando invio il comando mqtt, ma quando vado a verificare se il client è connesso.
Non sto facendo riferimento ora alla connessione wifi, ma alla connessione tra arduino (esp32) e il broker mqtt.
Forse è meglio se apro un'altra discussione, il titolo ora è fuorviante.

Avevo capito. Ma la connessione con mqtt può mancare anche se la connessione c'e' ? Verifica nella libreria mqtt se c'e' un comando per verificare se quella connessione è attiva. Sempre che esista per mqtt un concetto di "connessione" attiva/disattiva.

Non conosco mqtt, ma leggo:
http://www.lucadentella.it/2016/11/19/mqtt-enc28j60-e-adafruit-io/
e vedo funzioni tipo mqttClient.connected()

Hai centrato in pieno il problema (mio problema ::slight_smile: ), purtroppo (anche se in caso remoto) la connessione mqtt può interrompersi anche se quella wifi è attiva.
Nelle mie simulazioni, ho spento il wifi, con un controllo allo stato del wifi posso quindi bypassare il tentativo di connessione a mqtt e di conseguenza non ho problemi di blocco del loop: if wifi non connesso --> non controllare connessione mqtt.

Se però spengo il server mqtt (broker) allora tutto si blocca. E' pur vero che può sembrare stupido cercare di far funzionare qualcosa che si basa su mqtt quando il suo broker è spento, ma se io posso avere la necessita di attivare un qualcosa semplicemente premendo un pulsante (anche se via mqtt non verrà inviato il comando).
Tutto qua (si fa per dire...).

Beh può capitare che sei in wifi, rete okay ma server broker KO.
Hai visto al link che ti ho postato ? Comando mqttClient.connected()

Si, conosco il comando "mqttClient.connected()"
In pratica nel codice si mette proprio un if e se il client è connesso gli passo i dati.
Il problema è che se arrivi proprio a quel if e non è connesso, blocca il tutto per 5 secondi (nel migliore dei casi) cercando di connettersi al broker. Leggendo qua e la, la libreria si appoggia alla libreria wifi.h per i timing, ma qua per me diventa cmpo un poco troppo complesso.
Spesso mi rimane li bloccato per molto più tempo.

Verifica se anche la libreria mqtt per Arduino ha il comando setConnectionTimeout()
Mi pare ci sia: LINK

Ne parlano qui, ma per libreria Java

Dunque dunque...
Ho aperto PubSubClient.h (ovviamente nella cartella che viene richiamata dalla compilazione dello sketch) ed ho sostituito qua:

// MQTT_KEEPALIVE : keepAlive interval in Seconds
#ifndef MQTT_KEEPALIVE
#define MQTT_KEEPALIVE 1
#endif

// MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds
#ifndef MQTT_SOCKET_TIMEOUT
#define MQTT_SOCKET_TIMEOUT 1
#endif

Prima i valori MQTT_KEEALIVE e SOCKET_TIMEOUT erano a 15.

Purtroppo non è cambiato nulla dopo aver ricompilato.

Stando a quello che si dice qua Pubsubclient_API sembrano le voci che effettivamente devo modificare...