il Watchdog non funziona

allora dopo aver (+ o -) risolto i problemi sull’UDP…e per risolto intendo preso per buono che la libreria UDP dell’arduino voglia un ack dal ricevitore del pacchetto, pensavo di aver risolto i miei problemi con il watchdog…
quindi, tornato in campagna, montato tutto…dopo nemmeno 3 giorni l’arduino si è piantato…e il watchdog non lo ha resettato…
vi posto il codice

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <Udp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008
#include <avr/io.h>
#include <avr/wdt.h>


byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,0,202 };
unsigned int localPort = 8888;      // local port to listen on

byte remoteIp[] = { 192,168,0,201 }; 
byte remoteIp2[] = {192,168,0,203 };

unsigned int remotePort = 8888; // holds received packet's originating port
unsigned int remotePort2 = 8889;

char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,

int risposta;
int arrivo;
char invio[3];
char invio2[3];

int persi = 0;

int stato4 = 0;
int stato5 = 0;
int stato6 = 0;
int stato7 = 0;
int stati = 0;


void setup() {

  wdt_enable(WDTO_8S);
  
  pinMode(2, OUTPUT); //POMPA
  pinMode(3, OUTPUT); //Acquedotto
  pinMode(8, OUTPUT); //Assenza rete
  pinMode(9, OUTPUT); //Reset Arduino
  digitalWrite(9,LOW);  
  
  pinMode(4,INPUT); //Pompa ON
  pinMode(5,INPUT); //Acquedotto ON
  pinMode(6,INPUT); //Avaria Pompa
  pinMode(7,INPUT); //Energia Elettrica
  

  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  Serial.begin(9600);
}

void loop() {
  
   wdt_reset();
   stati = 0;
   
   stato4 = digitalRead(4);
   stato5 = digitalRead(5);
   stato6 = digitalRead(6);
   stato7 = digitalRead(7);
   
    
   if (stato4 == HIGH) { (stati=stati+1);  }  
   if (stato5 == HIGH) { (stati=stati+2);  }   
   if (stato6 == HIGH) { (stati=stati+4);  }
   if (stato7 == LOW) { (stati=stati+8);
                        digitalWrite(8, HIGH); }   
   if (stato7 == HIGH) {digitalWrite(8, LOW);} 
   itoa(stati,invio,10); 
   
   Udp.sendPacket( invio, remoteIp, remotePort);
   Udp.sendPacket( invio, remoteIp2, remotePort2);
   Serial.print("Ho inviato");
   Serial.println(invio);

  char packetBuffer[]="0";
  
  int packetSize = Udp.available(); 
  if(packetSize)
  { 
    persi =0;
    

    Udp.readPacket(packetBuffer,UDP_TX_PACKET_MAX_SIZE, remoteIp, remotePort);
    arrivo=atoi(packetBuffer);
   
    Serial.print("Ho Ricevuto:");
    Serial.println(arrivo);

   switch (arrivo) {
    case 1:
      digitalWrite(2, HIGH);
      digitalWrite(3, LOW);
      break;
    
    case 2:
      digitalWrite(2, LOW);
      digitalWrite(3, HIGH);
      break;
      
    case 3:
      digitalWrite(2, HIGH);
      digitalWrite(3, HIGH);
      break;
    
    default: 
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      
  }
if (arrivo <0 || arrivo>3){
  digitalWrite(9,HIGH);
  }
}
  else { persi= persi+1;}
    if (persi >20){
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    Serial.println("Nessun Collegamento");}
    
    if (persi == 100){
      digitalWrite(9,HIGH);
    }
          
  
  Serial.print("pacchetti Persi: ");
  Serial.println(persi);
  Serial.println();
  
    
  delay(200);
}

il pin 9 serve a resettare l’arduino nel caso di errori, o tramite un comando da remoto, non fa altro che attrarre un relè che chiude il pin reset a massa…ma ovviamente se l’arduino si pianta non funziona, per questo avevo inserito il watchdog…ma non fa…
cosa ho sbagliato? ho controllato sul sito dell’Atmel il atmega328 supporta anche il watchdog 8secondi
io penso di aver sbagliato qualcosa nella sintassi…boh…

sei sicuro che sia il codice a bloccarsi e NON solo la comunicazione UDP/la ethernet board?

secondo me dovresti mondare un led che ogni to loop() si accende/spegne, così vedi se è il codice incantato o solo la ethernet.

http://www.arduino.cc/playground/Main/ArduinoWaker

Qui hanno realizzato un progetto identico. Usare un Arduino per risvegliare con il watchdog, tramite una ethernet shield, un PC.

Però leggo:

One of the frustrations that can be met during Arduino Ethernet Shield development, is the problem that the ethernet shield will not automatically boot when Arduino is first powered; only after a hardware reset (caused either by pressing the button, or by programming the Arduino via USB (Arduino Forum - disable auto-reset by serial connection)) does the ethernet shield "wake up", and start running properly

Se non capisci l'inglese, dicono che l'Ethernet shield non riparte in automatico dopo aver dato tensione all'Arduino ma solo dopo un reset hardware o tramite programmazione via USB.

quindi anche questo porta a credere che il problema sia sullo shield ethernet..

Però.... se non erro quando si resetta, arduino mette tutte le uscite a 5v per un istante.. questo non crea un loop infinito di reset?

scusa ma il codice watchdog è testato? fai un codice che nel setup invia via seriale "ok" e non resetti mai il watchdog.

e il reset sul pin 9 l'hai testato? sempre setup che dice "ok", e nel loop metti una delay e poi il segnale di reset.

scusa se sembrano cose banali che magari hai già fatto, però voglio essere sicuro di non dare per scontato nulla

leo72:
Se non capisci l’inglese, dicono che l’Ethernet shield non riparte in automatico dopo aver dato tensione all’Arduino ma solo dopo un reset hardware o tramite programmazione via USB.

Questa cosa è vera per la vecchia versione della Ethernet shield, quelle più recenti hanno il reset controllato da Arduino.
Non è possibile resettare in hardware l’ATmega da se stesso, cosa già appurata in thread simile, c’è un problema di durata dell’impulso di reset che è maggiore di quanto è possibile effettuare in pratica.
Non ha alcun senso usare un relè per resettare Arduino da software, al limite esistono integrati appositi per il reset dei micro comandati da remoti o dal micro stesso, ma è una complicazione inutile su Arduino.
Per resettare Arduino da software, ammesso di avere ancora il controllo, basta eseguire un jump alla locazione 0, si fa tramite l’assembler inline con questa istruzione : " asm volatile (“jmp 0x0000”); ".
L’uso improprio del Watchdog può portare a spiacevoli conseguenza, inclusa la necessità di dover riprogrammare il bootloader sull’ATmega.

Secondo il datasheet dell'Atmega328, pag. 53, il codice per gestire il watchdog dovrebbe essere differente.

...dicono che l'Ethernet shield non riparte in automatico dopo aver dato tensione all'Arduino ma solo dopo un reset hardware o tramite programmazione via USB

Verissimo, mi è successo anche a me con la prima versione dell'ethernet shield ufficiale, quella nuova non so se ha lo stesso difetto. Comunque sia ho risolto mettendo un condensatore da 47 nF tra i pin reset e gnd, spero possa esserti utile questo suggerimento. Se non hai un condensatore da 47nF non disperare, mettine 2 da 100nF in serie che funzionano ugualmente, questi dovresti averli... Fa questa prova, vedrai che con questo espediente la tua ethernet shield non fallirà un'accensione. Saluti.

il reset con il relè funziona bene! quando si blocca la ethernet inizia a nonricevere pacchetti, quando ne ha persi troppi alza l'uscita 9 che pilota il relè e resetta! questo fa! ho inserito questo nel caso si bloccasse l'ethernet e non l'arduino non funzionava se tentavo di resettare l'arduino con il pin stesso (cioè mettendo basso il pin 9 direttamente collegato al reset), ma data la lentezza meccanica del relè ce la fa!Anche perchè l'unica cosa che fa è mettere l'uscita alta sul pin, che amnda il reset a massa tramite il contatto del relè, quindi l'uscita tornarà bassa solo se si resetta e staccherà il rele, quindi anche ci volesse 1 secondo per resettarlo, fino a che non si resetta il relè mi tiene il reset a massa!

questa ethernet è di dicembre, durante le prove fatte sono quasi sicuro che npon c'è bisogno di resettarla, ma appena dò corrente parte tranquillamente (infatti il reset con relè funziona), ha solo dei problemi se parte senza che ci sia il ricevitore attaccato, ma questo è un problema di libreria (come abbiamo già visto con Lesto)

Il problema è nel Watchdog…ho fatto questo semplice sketch:

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Udp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008
#include <avr/io.h>
#include <avr/wdt.h>


int stato=0;

void setup() {

  wdt_enable(WDTO_8S);  
  pinMode(2, INPUT); 
  Serial.begin(9600);
}

void loop() {
  
   wdt_reset();

   stato = digitalRead(2);
 
    
  if (stato == HIGH) { delay(10000);  }  
  Serial.print("ok");  
  
    
  delay(10);
}

se premo il pulsante e inizia il ritardo di 10 secondi, effettivamente qualcosa succede…ma sucede un macello…l’arduino si blocca, e tocca resettarlo manualmente, a questo punto continua a resettarsi di continuo e non su può nemmeno riscrivere un qualsiasi programma perchè il compilatore va in errore…dopo ore di imprecazioni sono riuscito a sovrascriverci blink cronometrando i 10 secondi che separano la compilazione dall’invio all’arduino rilasciando il tasto reset con una precisione svizzera :slight_smile:

Prima di toccare parti così vitali io mi documenterei per bene. Come ti avevo già scritto, il codice per gestire il watchdog che è contenuto nella documentazione dell'Atmega non è così semplice come quello che usi tu. Inoltre sempre nel datasheet si legge:

Note: If the Watchdog is accidentally enabled, for example by a runaway pointer or brown-out condition, the device will be reset and the Watchdog Timer will stay enabled. If the code is not set up to handle the Watchdog, this might lead to an eternal loop of time-out resets. To avoid this situation, the application software should always clear the Watchdog System Reset Flag (WDRF) and the WDE control bit in the initialization routine, even if the Watchdog is not in use.

Quindi se sbagli a programmare il watchdog, esso rimane attivo anche dopo un reset e si attiva prima che parta il tuo sketch, col risultato che il micro entra in un loop eterno.

Ho letto il datasheet dell'atmega, e ho cercato di capire la parte dove spiega la programmazione in C, ma non c'ho capito un granchè (date le mie scarse doti di programmazione) allora ho cercato nel forum ed ho visto in un post che veniva utilizzato così... qui: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1229317367/9 quindi mi sono fidato... :)

mi potresti dare una mano per come usarlo?grazieee

Quella discussione rimanda ad un paio di link. Vedo che nel primo ci sono esempi di codice ben scritti.

Io cmq metterei nel setup un bel MCUSR=0 per eliminare traccia dei precedenti segni di watchdog, poi imposterei il timing del watchdog e dopo lancerei il loop. Non appena termina la condizione da controllare, resetta il watchdog in modo che non ti rompa nel resto del codice.

Ah, bada bene: il tempo gestito dal watchdog non può arrivare a 10s, è limitato a 8s. Quindi da quel loop non uscirà mai perché tu aspetti 10s con quel delay.

ok ora provo! sisi quel 10 secondi era voluto per provare se scattava o no il watchdog...perchè nel progetto "vero" il watchdog non è scattato...volevo vedere se almeno così apsettando 10 secondi su 8 di wd qualcosa partiva...è partito...ma è entrato in loop, ma questo èun latro discorso :)

Ripristino questa discussione, perchè forse ho un problema analogo.

Volevo sapere quale versione dell' ethernet shield da problemi con il watchdog, per vedere se è anche il mio caso.