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;
}