Ciao, mi scuso subito per il titolo abbastanza vago ma sincerament non saprei come descrivere in due parole quello che vorrei chiedervi!
Sto facendo uno sketch che controlla lo stato di una connessione internet, per farlo pingo un server ogni x secondi (ora per debuggare ogni 10 s) ma in futuro sarà 10 minuti.
Se il ping ritorna correttamente, allora significa che c'è connessione internet e aspetto dieci minuti per il secondo ping.. se invece il ping mi ritorna sbagliato, entro in un if dove colleziono 4 ping sbagliati e stabilisco che non c'è connessione internet, ora vorrei che questi ping siano ogni x/2 secondi (nel mio caso 5 s).
Mi chiedevo, è un discorso di delay ? Mi manca forse una parte di conoscenza del linguaggio di programmazione..
Non so che escamotage usare!
In ogni caso, questo è il mio loop: (Le Serial.print sono giusto a scopo di debug)
bool pingReturn; //variabile in cui c'è il risultato del ping (vero o falso)
ICMPPing ping(pingSocket);
pingReturn = ping(4, pingAddr, buffer); //Pingo e riempio anche la variabile
delay(500);
Serial.println(buffer); //scrivo sul serial monitor il risultato del ping
if(pingReturn == true) //se è vero, tutto ok, errori 0 vado avanti e continuo[sup]1[/sup]
{
Serial.println("Ti sto solo dicendo che tutto e ok");
errori = 0;
}
else //se è falso..
{
digitalWrite(ledR, HIGH); //questo si può evitare di considerare.. è giusto per
Serial.println("Ti sto solo dicendo che non pinga");
errori++; //e quindi aumento gli errori
Serial.println(errori); //al 4 errore, entro nell'if, faccio il datalog, resetto il router
if (errori == 4)
{
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) {
dataFile.println("Data - Ora - Errore di connessione"); //ovviamente è molto embrionale anche a scopo didattico!
dataFile.close();
}
digitalWrite(ledR,LOW);
errori = 0; //dopo quattro errori, rinizio
}
delay di dieci s finale;
1 è corretto scrivere così if(pingReturn == true) ? o posso anche solo if(pingReturn){} ?
dai un'occhiata all'esempio BlinkWithoutDelay che è allegato all'IDE nonché questo mio articolo in cui spiego come far eseguire dei compiti ad intervalli programmati.
mettere if(A == true) oppure if(A) è equivalente solo nel caso in cui A debba valere 1, valore che ha true di default nell'IDE di Arduino. La seconda forma infatti più precisamente significa : se A è vera, se cioè ha un valore superiore a 0.
No siamo nell'ordine dei minuti per cui andrebbe bene..
Però non riesco a capire esattamente come muovermi, magari vi scrivo cosa ho in mente così mi è anche più facile organizzare le idee!
Io parto, inizializzo l'ethernet shield e inizializzo due funzioni:
Ping ogni 10s
Ping ogni 5s
A questo punto assegno le funzioni a due job e inizio a pingare ogni 10s perchè si suppon che almeno all'inizio va tutto bene, se ricevo 1 ping sbagliato allora devo mettere in pausa il primo job (ogni 10s) e avviare il scondo (ogni 5s), dopo 4 ping errati siamo sicuri che ci il router abbia qualche problema e allora pauso anche il 2 job e riavvio il router e aspetto abbastanza in modo tale che si registri
Quando è passato abbastanza tempo posso riprendere il 2 job perchè c'è possibilità che sia ancora offline.. faccio le prove, se ricevo 4 ping giusti interrompo questo task per passare al primo e così via, altrimenti tengo in pausa il prmo e proseguo con il reset..
Ci sta?
Sinceramente, mi sembra una soluzione ma non so se è una buona soluzione e se affidarsi ai ping è una buona strada per verificare la connesion internet
Ciao Pablo, come avevo premesso in questa fase uso tempi molto brevi proprio per aver un riscontro diretto di quello che faccio.
Il programma finale infatti userà tempi nell'ordine dei minuti.
Ciao, sono tornato perchè nonostante gli studi riguardo la funzione millis.. proprio non riesco a capire come usarla in questo caso, ovvero cambiare la frequenza in caso di errore.
Mi potete dare una mano ?
Ciao, grazie della pronta risposta.. allora uno sketch embrionale è pubblicato inizio 3D mentre quello a cui sto lavorando ora.. per ora, dovrebbe pingare una volta ogni 10s sfruttando la funzione millis ma siccome il router non si connette a internet -_- non posso provarlo.
Quello che mi manca è, dopo aver raccolto 4 ping errati, cambiare l'intervallo da 10s a 5s
int errori ; //Contatore di ping falliti
int alim = 7; //Pin alimentazione router
unsigned long time;
unsigned long tempoIniziale = 0;
long intervallo = 10000;
void setup() //SET UP del programma
{
pinMode(alim,OUTPUT);
pinMode(alim,LOW); //Attivo il pin di alimentazione
delay(2000); //2sec per far ripigliare la scheda
//Inizializzo SD card
Serial.begin(9600);
if (!SD.begin(4))
{
return;
}
//Inizializzo Ethernet shield
if(Ethernet.begin(mac) == 0) //Primo tentativo
{
Ethernet.begin(mac,ip); //Se fallisce, faccio "a mano"
}
delay(1000); //Attendo un secondo prima di iniziare il programma.
//Ora il router è sulla rete - salvo errori
}
void loop()
{
unsigned long tempoAttuale = millis();
if (tempoAttuale - tempoIniziale == intervallo)*
{
tempoIniziale = tempoAttuale;
bool pingReturn; //Qua ci va il risultato del ping (Vero o Falso)
ICMPPing ping(pingSocket);
pingReturn = ping(4, pingAddr, buffer); //Mando il ping
Serial.println(buffer);
}
}
Note:
negli esempi mette sempre >, mettere == comporterà errori ?
Non mettere mai == perché se per qualche motivo perdi quel preciso istante, per 49,7 giorni poi l'if non è più valido
Per cambiare frequenza non devi far altro che cambiare in corso d'esecuzione il valore di "intervallo".
Esempio:
void loop()
{
unsigned long tempoAttuale = millis();
if (tempoAttuale - tempoIniziale == intervallo)*
{
tempoIniziale = tempoAttuale;
bool pingReturn; //Qua ci va il risultato del ping (Vero o Falso)
ICMPPing ping(pingSocket);
pingReturn = ping(4, pingAddr, buffer); //Mando il ping
if (pingReturn) { //pin vero
intervallo = 10000; //10 secondi
} else {
intervallo = 5000; //5 secondi
}
Serial.println(buffer);
}
}
Se pinga giusto, l'intervallo è a 10 secondi, se il ping è false, mette a 5
!!
Ottimo, grazie davvero davvero tanto che così ho risolto il problema e ho imparato una nuova soluzione molto più elegante di tutte quelle che avevo pensato..
Graze ancora!
Giusto per il > in effetti è meglio essere sicuri!
Ultima domanda, se io devo spegnere un dispostivo tramite relè e uso un delay vado a bloccare il corso dei millis o quant'altro ? Mi spiego, ho capito che anche se c'è il DELAY i millis proseguono, nel caso l'intervallo si verifichi mentre il programma è bloccato da un delay coas succederebe ? errori o si continua.. finisce il delay e va avanti a controllare gli intervalli ?
Io avrei una altra domanda, non per risolvere un problema ma per capire cosa è consigliato - meglio fare!
Insomma, rileggndo il codice c'è questa parte che mi sembra un po' "doppia"
if(Ethernet.begin(mac) == 0) //Se il DHCP fallisce,
{
Ethernet.begin(mac,ip); //Faccio "a mano"
}
Per prma cosa, è giusto il commento ?
Ma se io sono sicuro del mio mac e del mio IP sulla rete non posso togliere l'if e lasciare semplicemente "Ethernet.begin(mac,ip)" ?
tutto quello che dici è corretto.
Spesso alcune macchine hanno gli ip riservati, sopratutto se sono server. Ma non è una funzionalità che i router di bassa fascia (aka: quelli che ti danno le compagnie telefoniche) possiedono.. o almeno io non l'ho mai visto sui vari router che ho visto in giro