aiuto:STRANO COMPORTAMENTO IN SLEEPMODE

ciao a tutti,
sto lavorando a un progetto basato su attiny85, programmato tramite arduino uno.

ecco cosa fa il programma:
-pone l’attiny in sleep mode (esso si risveglia grazie al WDT, trascorso un tempo predefinito dato dalla funzione watchdog_setup)

  • dopo che sono trascorsi i cicli richiesti di wdt l’attiny si sveglia, legge dei sensori, legge la VCC e trasmette i dati via codice morse (txpin e funzione sendmsg()).
    -loop

ecco il problema: durante l’esecuzione di cicli “sonno/veglia” l’attiny si comporta in maniera inaspettata:
appena acceso esso aspetta il giusto lasso di tempo (dato dal settaggio di WDT e dal valore di Watchdog_counter) e poi trasmette correttamente il messaggio, ma in seguito si sveglia dallo sleepmode in maniera casuale (una volta dopo 4 secondi, altre dopo 30 e così via) .

grazie a tutti per l’aiuto.

segue il codice

#include <avr/sleep.h>
#include <avr/wdt.h>
int iSensor = 0;
int iiSensor = 0;
char analogiString[6];
char analogiiString[6];
const int txpin = 0; 
char vbatt[6];
char itemp[6];
int n=0;
int watchdog_counter = 0;
#define ITEMPOFFSET 0
void setup() {
pinMode(0, OUTPUT); 
pinMode(1, OUTPUT);  
pinMode(3,INPUT);
pinMode(4,INPUT);  
set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Power down everything, wake up from WDT
sleep_enable();
}
void loop() {
setup_watchdog(8);
ADCSRA &= ~(1<<ADEN); //Disable ADC, saves ~230uA
sleep_mode(); 
if(watchdog_counter > 3)
{
watchdog_counter = 0;
ADCSRA |= (1<<ADEN); //Enable ADC
delay (200);                                                
                                        readsensors(); 
                                        digitalWrite (1, HIGH); // TX ENABLE
                                        delay(200);
                                        
                                        sendmsg(vbatt) ;
                                         
                                        sendmsg(itemp) ;
                                        
                                        sendmsg(analogiString);
                                        
                                        sendmsg(analogiiString);

                                        digitalWrite (1, LOW); // TX disABLE 
}
}
void readsensors () {
analogReference(INTERNAL1V1); 
delay (200);
iSensor = 0;
iiSensor = 0;
n=0;
for (n = 0; n < 5; n++){
iSensor = iSensor + analogRead(3);    
iiSensor = iiSensor + analogRead(4);    
delay(200);}
iSensor = iSensor / 5;    
iiSensor = iiSensor / 5;
sprintf ( analogiString, "%d ", iSensor );
sprintf ( analogiiString, "%d ", iiSensor );
sprintf ( vbatt, "%d ", readVcc() );
sprintf ( itemp, "%d ", read_Chip_Temp() );
}                                             
ISR(WDT_vect) {
watchdog_counter++;
}
struct t_mtab { char c, pat; } ;
struct t_mtab morsetab[] = {
	{'.', 106},
	{',', 115},
	{'?', 76},
	{'/', 41},
        {'t', 53},
        {'+', 42},
        {'=', 49},
	{'A', 6},
	{'B', 17},
	{'C', 21},
	{'D', 9},
	{'E', 2},
	{'F', 20},
	{'G', 11},
	{'H', 16},
	{'I', 4},
	{'J', 30},
	{'K', 13},
	{'L', 18},
	{'M', 7},
	{'N', 5},
	{'O', 15},
	{'P', 22},
	{'Q', 27},
	{'R', 10},
	{'S', 8},
	{'T', 3},
	{'U', 12},
	{'V', 24},
	{'W', 14},
	{'X', 25},
	{'Y', 29},
	{'Z', 19},
	{'1', 62},
	{'2', 60},
	{'3', 56},
	{'4', 48},
	{'5', 32},
	{'6', 33},
	{'7', 35},
	{'8', 39},
	{'9', 47},
	{'0', 63}
} ;
#define N_MORSE  (sizeof(morsetab)/sizeof(morsetab[0]))
#define SPEED  (18)
#define DOTLEN  (1200/SPEED)
#define DASHLEN  (3*(1200/SPEED))
void
dash()
{
digitalWrite(txpin, HIGH) ;
delay(DASHLEN);
digitalWrite(txpin, LOW) ;
delay(DOTLEN) ;
}
void
dit()
{
digitalWrite(txpin, HIGH) ;
delay(DOTLEN);
digitalWrite(txpin, LOW) ;
delay(DOTLEN);
}
void
send(char c)
{
int i ;
if (c == ' ') {
delay(7*DOTLEN) ;
return ;
}
for (i=0; i<N_MORSE; i++) {
if (morsetab[i].c == c) {
unsigned char p = morsetab[i].pat ;
while (p != 1) {
if (p & 1)
dash() ;
else
dit() ;
p = p / 2 ;
}
delay(2*DOTLEN) ;
return ;
}
}
}
void
sendmsg(char *str)
{
while (*str)
send(*str++) ;
}
void setup_watchdog(int timerPrescaler) {
if (timerPrescaler > 9 ) timerPrescaler = 9; //Limit incoming amount to legal settings
byte bb = timerPrescaler & 7; 
if (timerPrescaler > 7) bb |= (1<<5); //Set the special 5th bit if necessary
MCUSR &= ~(1<<WDRF); //Clear the watch dog reset
WDTCR |= (1<<WDCE) | (1<<WDE); //Set WD_change enable, set WD enable
WDTCR = bb; //Set new watchdog timeout value
WDTCR |= _BV(WDIE); //Set the interrupt enable, this will keep unit from resetting after each int
}
uint16_t readVcc(void)
{
uint16_t result;
ADMUX = (0<<REFS0) | (12<<MUX0);
delay(200); // Wait for Vref to settle
ADCSRA |= (1<<ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
n=0;
result = 0; 
for (n = 0; n < 5; n++){
result = result + ADCW;   
delay(50);
}
result = result / 5;   
return 1126400L / result; //1.1*1024*1000
}
int read_Chip_Temp() 
{ 
ADMUX = (1<<REFS1) | (15<<MUX0);
delay(200); // Wait for ADMUX setting to settle
ADCSRA |= (1<<ADSC); //Start temperature conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
int temperature = (high << 8) | low; 
return temperature - 273 + ITEMPOFFSET;
}

Vedi se questo può esserti utile http://forum.arduino.cc/index.php?topic=42670.0

Le variabili gestite dentro una ISR devono essere di tipo "volatile". quindi

int watchdog_counter = 0;

mettilo così:

volatile int watchdog_counter = 0;