EthShield, watchdog, issue 605 e considerazioni varie.

Nella settimana passata ho lavorato con la eth shield ufficiale su IDE 1.0 e mi piacerebbe condividere con voi alcune cose, sperando in qualche opinione di confronto :slight_smile:

Parliamo del watchdog.
Ho messo su la eth shield con web client e web server ed ho notato che, dopo diverse ore di funzionamento impeccabile, iniziavano a manifestarsi freeze o lag nelle risposte del web server.
Ho cercato in rete ed ho trovato che è un problema comune della shield.
A tal proposito si implementa un controllo (watchdog) che reinizializza la scheda ogni (x) ripristinandone il corretto funzionamento.

Al momento sto lavorando con due tipi di watchdog, mi piacerebbe sapere la vostra opinione in merito.
Ora come ora il web server è up da circa 20 ore senza nessun problema. Prima si freezava dopo due o tre ore. Quindi non ho problemi di codice al momento ma apprezzerei cmq un confronto per imparare, magari, una soluzione migliore.

Primo watchdog.
Ogni x cicli reinizializzo la eth shield con questo codice, facendolo eseguire in una parte del programma sicura, per non bloccare eventuali connessioni.

void resetEthernetShield(){
  delay(100);
  Serial.println(F("Resetting Ethernet Shield."));   
  Ethernet.begin(mac,ip,dns,gateway,subnet);
  server.begin();
  delay(100);
}

E questo è ok credo, da quando l'ho messo il server non si è mai congelato.

Oltre a questo primo watchdog resetto il micro ogni 60 minuti, sempre avviando il reset in una parte di codice sicura.
Il reset software lo avvio con questo codice.

if ( watchdogtimer >= 60 ){ // resetta il micro ogni 60min
        delay(10);
        void (*softReset) (void) = 0; //declare reset function @ address 0
        softReset();
      }

Ora, sebbene tutto sembri funzionare senza problemi avrei qualche domanda.
Comprendo la funzione di reinizializzazione della eth shield ma ammetto di usare la funzione di soft reset senza comprenderla veramente. In vari forum affermano che è utilissima per evitare problemi alla eth shield.
La mia prima domanda è... crea danni? posso danneggiare qualcosa usando quella funzione?
Seconda domanda, 60 minuti è un tempo adeguato?
Voi che tempi usate per il watchdog e tenere un micro sempre "in condizioni ottimali" su lunghi periodi?
6 ore? 24 ore? 1 settimana?
Terza domanda: voi come gestite il vostro watchdog su progetti che devono rimanere up per molti mesi?
Vorrei evitare modifiche hardware (ne ho lette diverse) o custom bootloader (tipo quello di ladyada).

Ultima domanda, conoscete "l'issue 605" ?
http://code.google.com/p/arduino/issues/detail?id=605
Ha senso implementare la patch? Il mio codice del web server sembra funzionare comunque...
Utilizzo paro paro quello di ladyada per IDE1.0

ciao

Terza domanda: voi come gestite il vostro watchdog su progetti che devono rimanere up per molti mesi?

io, per un progetto che feci parecchio tempo fa, avevo usato la Eth Shield prima versione.
Quella aveva un problema non da poco: una volta data alimentazione ad Arduino, per farla funzionare dovevi resettarla, pena il mancato funzionamento di tutta la parte Eth.
Inoltre avevo notato che dopo tempi più o meno lunghi, andava in freeze la parte Eth.
Il codice lato Arduino continuava cmq ad andare - sostanzialmente il comportamento che accusi tu.

La soluzione allora era stata di fare una piccola modifica allo shield eth, piegando verso l'esterno il piedino di reset, e gestendo via sketch il reset stesso dello shield:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282231155/27#27

In questo modo potevo effettuare il reset via sw, all'avvio di Arduino, e pilotarlo in caso di freeze.
Poichè nella rete in cui il tutto doveva lavorare, era presente un tool di monitoraggio, ho fatto in modo che il monitoraggio di Arduino avvenisse tramite una get specifica.
Quindi lato sketch, se non mi vedo arrivare questa get entro un tempo prestabilito, significa che la parte Eth è fuori uso, e resetto.

Ultimamente ho dovuto fare un lavoro usando uno shield WiFi (la RedFly).
Anche qui randomicamente la comunicazione eth si freeza. Il nodo è pingabile, ma nulla di più.
Analogamente al caso precedente, qui c'è una procedura schedulata che contatta il nodo per recuperare delle informazioni (ogni 15 minuti).
Lato Arduino, se non ricevo la get in questione entro 16 minuti, reinizializzo lo shield wifi e tutto funziona come prima.

Ho dovuto però implementare anche un watchdog per gestire dei reset di tutto (Arduino e shield) in caso di freeze totale.
In questo caso, ho aggiornato le 2009 con l'ultimo firmware della UNO, e utilizzo le funzioni di watchdog tramite la libreria <avr/wdt.h>:
http://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1292260145

Quindi, da questa ultima esperienza, penso che implementerò le funzionalità di watchdog in tutti i miei prossimi progetti.

Se vuoi usare watchdog sw, ovvero che piloti tu (come nell'esempio da te postato), il tempo massimo lo devi definire tu, in base alla criticità dell'applicazione e al tempo massimo di down tollerabile.

pitusso:
ciao

Ma ciao pitusso :slight_smile:
Sappi che ti sto identificando come esperto ethernet, visto che spesso compari competentemente in discussioni relate :slight_smile:

La soluzione allora era stata di fare una piccola modifica allo shield eth, piegando verso l'esterno il piedino di reset, e gestendo via sketch il reset stesso dello shield:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282231155/27#27

La modifica hardware l'avevo vista sul forum di adafruit... ma mi piange il cuore a piegare il piedino, soprattutto se posso fare via software :slight_smile:

Ultimamente ho dovuto fare un lavoro usando uno shield WiFi (la RedFly).
Anche qui randomicamente la comunicazione eth si freeza. Il nodo è pingabile, ma nulla di più.
Analogamente al caso precedente, qui c'è una procedura schedulata che contatta il nodo per recuperare delle informazioni (ogni 15 minuti).

Un keep alive in pratica... E' una buona idea, anche se non posso farla :
Tutto il sistema è fatto per funzionare in autonomia, anche senza connettività in rete (lan o internet) e quindi non ho host che possa "pingare" la shield per vedere se è sveglia :slight_smile:

In questo caso, ho aggiornato le 2009 con l'ultimo firmware della UNO, e utilizzo le funzioni di watchdog tramite la libreria <avr/wdt.h>:
avr-libc: <avr/wdt.h>: Watchdog timer handling
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1292260145

Interessantissimo. Ero rimasta, dal forum di adafruit, che serviva un bootloader modificato... invece, da quello che scrivi, la gestione wdt è stata abilitata con l'ultimo firmware uno presente nell'IDE 1.0?
Se ho capito bene... allora potrei aggiornare la mia 2009 :slight_smile:
Il bootloader della uno IDE 1.0 l'ho già messo su due altri standalone, potrei metterlo anche li :slight_smile:

Se vuoi usare watchdog sw, ovvero che piloti tu (come nell'esempio da te postato), il tempo massimo lo devi definire tu, in base alla criticità dell'applicazione e al tempo massimo di down tollerabile.

Si ma la mia preoccupazione era:
se resetto via software il micro ogni ora, per i prossimi 5 anni, si rovina?
Penso (sono concetti diversi lo so) alla EEPROM ed al suo numero massimo di scritture.
Se il micro non si rovina ed è indifferente tengo il reset ogni ora.
Se nella vita del micro posso fare solo 100mila reset trovo un altro valore di tempo che si adatti alle esigenze.
Hai info in merito?

Interessantissimo. Ero rimasta, dal forum di adafruit, che serviva un bootloader modificato... invece, da quello che scrivi, la gestione wdt è stata abilitata con l'ultimo firmware uno presente nell'IDE 1.0?

sì, confermo che con il bootloader distribuito con l'IDE 1.0, il watchdog funziona (oltre a essere stata fixata la issue della dimensione dello sketch).

Se ho capito bene... allora potrei aggiornare la mia 2009

sì, io ne ho tenuta solo un paio con il bootloader 2009, le altre son state tutte aggiornate. Chiaramente c'è solo da guadagnarci, ad aggiornare bootloader.

se resetto via software il micro ogni ora, per i prossimi 5 anni, si rovina?

non ti so rispondere con certezza (non ne ho le competenze), anche se non credo.

Inoltre la parte di codice per il reset sw che riporti, non avevo mai avuto modo di vederlo, prima (uso
asm("jmp 0");
citato da astro in uno dei suoi post).

EDIT: nel frattempo vedo che legacy ha risposto.

A me re-inizializzare la scheda non bastava, perche' spesso si bloccava proprio durante l'invio dei dati ( Pachube, ThingSpeak, Google Documents ) e ho notato che questo avveniva sempre nei momenti di maggior traffico sulla rete.
Poi, dato che uso delle Arduino Ethernet non mi veniva bene neanche resettare solo la parte relativa. Ho quindi aggiunto un Watchdog hardware ( un semplice 555), cosi' se il codice si pianta di brutto si resetta tutta la scheda.
Poi, per tranquillita', all'alba resetto il tutto e risincronizzo in NTP

pitusso:
sì, confermo che con il bootloader distribuito con l'IDE 1.0, il watchdog funziona (oltre a essere stata fixata la issue della dimensione dello sketch).

Sto leggendo i links su wdt che mi hai dato, in più googlo qua e la, però c'è una cosa che non mi è chiara.
Non capisco come si avvia il reset.
Il wdt interno al micro come rileva l' "hang"?
Mi sembra di aver capito che:
Il wdt supportato dal bootloader setta un timer interno e quando rileva un hang pari al tempo settato (dai 15ms ai 2 secondi) nell'esecuzione dello sketch fa partire il reset.
E' così che funziona?

Se ciò fosse non sarebbe utile nel caso della eth shield perché i freezing dell'eth shield non influiscono (generalmente) sull'esecuzione del codice a livello del micro sull'arduino.

E dulcis in fundo... hai un esempio di un tuo codice che utilizza il wdt con il nuovo bootloader?
So che è importante disabilitarlo nel setup e avviarlo nel loop, ma non so se sono questioni risolte con l'aggiornamento.

@Brunello: azz! Un design proprio failproof :slight_smile: Hai mica qualche link dove vedere il tuo progetto? magari posso prendere qualche spunto :slight_smile:

Quando si fanno le prove all'una di notte ci si arrangia con quello che c'e' in casa

Ecco il semplice Watchdog.
555 in modalita' Astabile, con ciclo di circa 60 secondi. Nel codice si rinfresca periodicamente il Pin 5 con un livello HIGH.
Il Pin 6 serve ( con un LOW ) a forzare il Reset .

Ciao

Non capisco come si avvia il reset.
Il wdt interno al micro come rileva l' "hang"?

in realtà, se tu non resetti il wd, al termine del tempo stabilito avviene il reset.
Per resettare il wd utilizzi la funzione:

 wdt_reset();

Se ciò fosse non sarebbe utile nel caso della eth shield perché i freezing dell'eth shield non influiscono (generalmente) sull'esecuzione del codice a livello del micro sull'arduino.

è vero, infatti in quei casi devi gestire un wd sw che venga resettato da qualche evento in particolare; nel caso specifico, una get esterna, un ping, altro.

E dulcis in fundo... hai un esempio di un tuo codice che utilizza il wdt con il nuovo bootloader?
So che è importante disabilitarlo nel setup e avviarlo nel loop, ma non so se sono questioni risolte con l'aggiornamento.

Esempio base:
dopo 8 secondi la board si resetta (il led acceso per 3 secondi nel setup è la conferma).
Se all'inizio del loop dovessi mettere il reset ( wdt_reset()), a meno di freeze nel codice, il reset non avverrebbe mai (in questo caso).

#include <avr/wdt.h>

void setup() {   

  MCUSR = 0;
  wdt_disable();   //disable wd 
   
  pinMode(13, OUTPUT); 

  digitalWrite(13, HIGH); 
  delay(3000);                       
  digitalWrite(13, LOW);   

    
  wdt_enable(WDTO_8S);   //enable wd - 8sec timer
  wdt_reset();   //reset wd
}

void loop() {
  digitalWrite(13, HIGH);    
  delay(1000);                     
  digitalWrite(13, LOW);     
  delay(1000);                     
}

Cmq, il tempo massimo utilizzabile con il wd è 8 secondi.

@Pitusso

Quella aveva un problema non da poco: una volta data alimentazione ad Arduino, per farla funzionare dovevi resettarla, pena il mancato funzionamento di tutta la parte Eth.

Si questo è un problema non solo di parecchio tempo fa, ma anche sulle schede che compri adesso, anche dopo aver uploadato lo sketch va resettata, infatti poi va, ma la cosa di piegare il pin reset non mi è chiara....
La ethernet shield è collegata ad arduino con 2 pin reset quello vicino al 3.3v e sul connettore a 6 pin ICSP, hai dovuto modificare anche quello no? Piegare il pin reset solo non risolve nulla .....

Un altro problema è il buffer, non c'e' verso di cancellarlo se non scollegare e ricollegare l'alimentazione, il reset viene totalmente ignorato.

Vale la pena di passare a raspberry solo per questo :slight_smile:

@ Daniela
Hai risolto il problema R/W su sd e l'uso della ethernet avendo lo stesso SPI con l'ide 1.0?

ciao

La ethernet shield è collegata ad arduino con 2 pin reset quello vicino al 3.3v e sul connettore a 6 pin ICSP, hai dovuto modificare anche quello no? Piegare il pin reset solo non risolve nulla .....

la prima versione dello shield Eth non aveva il connettore ICSP :stuck_out_tongue:

Un altro problema è il buffer, non c'e' verso di cancellarlo se non scollegare e ricollegare l'alimentazione, il reset viene totalmente ignorato.

cosa intendi?

Intendo che in diversi esperimenti, se ad esempio carico uno sketch che ha righe html accedo all'ip e tutto ok funziona bene, poi decido di uploadare un altro sketch sempre con linee html ma completamente diverse, bene quando accedo con l'ip la pagina è un casino bestiale appaiono le righe dell'altro sketch precedente con quelle del nuovo nonstante lo abbia sovrascritto e resettato più volte. Se lo disalimento e rialimento il problema non ce l'ho più. Sembra che restino in memoria parti della pagina precedente, non me lo so spiegare

Mi ci sono picchiato delle notti su questo a cercare errori di programma e non capivo, poi per puro caso ho trovato che quando cambio sketch che usa la eth è meglio pulirlo spegnendolo.

Secondo te sarebbe il caso di provare a sostituire il bootloader?

ciao

Intendo che in diversi esperimenti, se ad esempio carico uno sketch che ha righe html accedo all'ip e tutto ok funziona bene, poi decido di uploadare un altro sketch sempre con linee html ma completamente diverse, bene quando accedo con l'ip la pagina è un casino bestiale appaiono le righe dell'altro sketch precedente nonstante lo abbia sovrascritto e resettato più volte

uhmm, mi sa che so problemi di cache del browser..

pitusso:
in realtà, se tu non resetti il wd, al termine del tempo stabilito avviene il reset.
Per resettare il wd utilizzi la funzione:

 wdt_reset();

Ora ho capito anche se, questa impostazione, è assai limitante.
Poniamo il caso io abbia un while per un menu dove setto le impostazioni, può essere che io rimanga in questo while anche per qualche minuto.
Se metto il reset semplicemente nel loop... il menu non potrò mai utilizzarlo perché dopo 8 secondi max si resetta tutto.

Devo quindi fare qualcosa tipo un sotto ciclo con un counter.

void setup (){
MCUSR = 0;
wdt_disable();   //disable wd  }

void loop() {
int cnt = 0;
cnt++
If ( cnt > 10 ) { wdt_enable(WDTO_15MS); 
delay (30);
}
}

E' corretto il mio ragionamento?
Domanda MCURS=0 cos'è?
Credo il flag del reset, ma che valori restituisce e come si comporta?

Due ultime domande sul wdt.
Il link di pitusso consiglia di disabilitare il prima possibile il wdt così:

   #include <stdint.h>
    #include <avr/wdt.h>

    uint8_t mcusr_mirror __attribute__ ((section (".noinit")));

    void get_mcusr(void) \
      __attribute__((naked)) \
      __attribute__((section(".init3")));
    void get_mcusr(void)
    {
      mcusr_mirror = MCUSR;
      MCUSR = 0;
      wdt_disable();
    }

Mentre il codice di pitusso lo disabilita nel setup.
Magari nel blink fa poca differenza ma io ho un setup bello pieno, meglio spostare il disable fuori?
Ho letto che se non lo disabilito a dovere incappo in un loop eterno di reset...

@pablos a quale problema ti riferisci?
Fondamentalmente spegno il web server quando devo scrivere sulla SD e lo riabilito appena finita la scrittura.
Il passaggio è così veloce che non è umanamente percettibile.
In lettura dalla sd non ho utilizzato nessun accorgimento particolare, ho seguito il classico esempio di ladyada.
Btw anche a me la shield eth fa le bizze dopo il caricamento di uno sketch con modifiche sostanziose rispetto al precedente. Ed anche io, dopo un paio di sopracciglia inarcate e perplesse, ho compreso che in alcuni casi va fatto un power cycle.

Fondamentalmente spegno il web server quando devo scrivere sulla SD e lo riabilito appena finita la scrittura.
Il passaggio è così veloce che non è umanamente percettibile.

Strano secondo me nella 0022 gli enable/disable le faceva la SPI.h, comunque se così ti va .... meglio :slight_smile:

ciao

pablos:

Fondamentalmente spegno il web server quando devo scrivere sulla SD e lo riabilito appena finita la scrittura.
Il passaggio è così veloce che non è umanamente percettibile.

Strano secondo me nella 0022 gli enable/disable le faceva la SPI.h, comunque se così ti va .... meglio :slight_smile:

ciao

Mo provo a toglierli e vediamo... giusto per curiosità :slight_smile:

Almeno mi consolo che non sono l'unico folle a trovarsi sul forum e con arduino sulla scrivania alle 3 di notte :smiley: :smiley:

@legacy
parli di questa? http://www.nuelectronics.com/estore/index.php?main_page=project_eth

DanielaES:
Strano secondo me nella 0022 gli enable/disable le faceva la SPI.h, comunque se così ti va .... meglio :slight_smile:

Tolti i codici di enable/disable nel loop di log... e sembra andare cmq.
Il codice si è alleggerito di un 0.1k, adesso lo lascio andare tutta la notte e tutto domani e vediamo se funziona :slight_smile:

Ma collegare esternamente il pin reset dello shield ad un pin digitale di arduino no? (visto che arduino continua a funzionare nella condizione di fault dello shield).

BrainBooster:
Ma collegare esternamente il pin reset dello shield ad un pin digitale di arduino no? (visto che arduino continua a funzionare nella condizione di fault dello shield).

devo segare anche il pin dell ICSP e sinceramente non mi va, e poi quando si è ingrippata da remoto come la resetto? Devo costruire acrocchi per aggirare il problema ?

Ti compri un utilitaria e poi ti accorgi che devi montare una maniglia per farla partire, dopo 12 ore che è parcheggiata il motorino di avviamento non va più. Diciamo meglio che abbiamo comprato un pacco e va sostituito con un altro modello ...

ciao

pablos:
Diciamo meglio che abbiamo comprato un pacco e va sostituito con un altro modello ...

Concordo pienamente

E Banzi cosa dice ??