Ciao a tutti, ho un problema con l'attiny85.
Il programma fa questo:
una volta al secondo il watchdog sveglia il micro; il micro genera un numero random, se è diverso da 10 torna a dormire, diversamente fa dei giochi di luce con un led rgb in pwm per un certo tempo e poi si riaddormenta.
Ora, tutto funziona ma solo per circa 14 minuti, poi tutto si blocca, il micro entra in un limbo e non si riaddormenta più, nè accende alcun led.
Lo sketch
#include <avr/sleep.h>
#include <avr/wdt.h>
volatile boolean f_wdt = 1;
byte FirstStart = false;
int OLDrandNumberRED;
int OLDrandNumberGREEN;
int OLDrandNumberBLUE;
int NEWrandNumberRED;
int NEWrandNumberGREEN;
int NEWrandNumberBLUE;
int FadeRate = 10; // in millis
byte maxpwm = 250;
int i, j, k;
byte Red = 0;
byte Green = 1;
byte Blue = 4;
int counter = 0;
int keyloop = 0;
void setup() {
//Serial.begin(9600); // used for debug
pinMode(Red, OUTPUT);
pinMode(Green, OUTPUT);
pinMode(Blue, OUTPUT);
pinMode(2, INPUT); // pin non usati settati come input
pinMode(3, INPUT);
pinMode(5, INPUT);
digitalWrite(2, HIGH); // pull-up sui pin non usati
digitalWrite(3, HIGH);
digitalWrite(5, HIGH);
randomSeed(100);
OLDrandNumberRED = random(maxpwm);
OLDrandNumberGREEN = random(maxpwm);
OLDrandNumberBLUE = random(maxpwm);
setup_watchdog(6); // approximately 1 seconds sleep
}
void loop() {
if (f_wdt == 1) { // wait for timed out watchdog / flag is set when a watchdog timeout occurs
if (keyloop != 10) {
keyloop = random(11);
// Serial.println(keyloop);
f_wdt = 0; // reset flag
pinMode(Red, INPUT);
pinMode(Green, INPUT);
pinMode(Blue, INPUT);
system_sleep();
pinMode(Red, OUTPUT);
pinMode(Green, OUTPUT);
pinMode(Blue, OUTPUT);
}
if (keyloop == 10) {
if (FirstStart == false) { // fade in
if ( i < OLDrandNumberRED) {
i++;
analogWrite(Red, i);
}
if ( j < OLDrandNumberGREEN) {
j++;
analogWrite(Green, j);
}
if ( k < OLDrandNumberBLUE) {
k++;
analogWrite(Blue, k);
}
if ( i >= OLDrandNumberRED && j >= OLDrandNumberGREEN && k >= OLDrandNumberBLUE ) {
FirstStart = true;
}
delay(FadeRate);
}
if (FirstStart == true) { // loop
if ( counter < 5) {
NEWrandNumberRED = random(maxpwm);
NEWrandNumberGREEN = random(maxpwm);
NEWrandNumberBLUE = random(maxpwm);
// Serial.print("OLDrandNumberRED = "); Serial.println(OLDrandNumberRED);
// Serial.print("NEWrandNumberRED = "); Serial.println(NEWrandNumberRED);
// Serial.print("OLDrandNumberGREEN = "); Serial.println(OLDrandNumberGREEN);
// Serial.print("NEWrandNumberGREEN = "); Serial.println(NEWrandNumberGREEN);
// Serial.print("OLDrandNumberBLUE = "); Serial.println(OLDrandNumberBLUE);
// Serial.print("NEWrandNumberBLUE = "); Serial.println(NEWrandNumberBLUE);
// delay(3000);
if ( NEWrandNumberRED < OLDrandNumberRED) {
for ( i = OLDrandNumberRED; i >= NEWrandNumberRED; i--) {
analogWrite(Red, i);
// Serial.print("i-- = "); Serial.println(i);
delay(FadeRate);
}
}
if ( NEWrandNumberRED > OLDrandNumberRED) {
for ( i = OLDrandNumberRED; i <= NEWrandNumberRED; i++) {
analogWrite(Red, i);
// Serial.print("i++ = "); Serial.println(i);
delay(FadeRate);
}
}
if ( NEWrandNumberGREEN < OLDrandNumberGREEN) {
for ( j = OLDrandNumberGREEN; j >= NEWrandNumberGREEN; j--) {
analogWrite(Green, j);
// Serial.print("j-- = "); Serial.println(j);
delay(FadeRate);
}
}
if ( NEWrandNumberGREEN > OLDrandNumberGREEN) {
for ( j = OLDrandNumberGREEN; j <= NEWrandNumberGREEN; j++) {
analogWrite(Green, j);
// Serial.print("j++ = "); Serial.println(j);
delay(FadeRate);
}
}
if ( NEWrandNumberBLUE < OLDrandNumberBLUE) {
for ( k = OLDrandNumberBLUE; k >= NEWrandNumberBLUE; k--) {
analogWrite(Blue, k);
// Serial.print("k-- = "); Serial.println(k);
delay(FadeRate);
}
}
if ( NEWrandNumberBLUE > OLDrandNumberBLUE) {
for ( k = OLDrandNumberBLUE; k <= NEWrandNumberBLUE; k++) {
analogWrite(Blue, k);
// Serial.print("k++ = "); Serial.println(k);
delay(FadeRate);
}
}
OLDrandNumberRED = NEWrandNumberRED;
OLDrandNumberGREEN = NEWrandNumberGREEN;
OLDrandNumberBLUE = NEWrandNumberBLUE;
counter++;
// Serial.println(counter);
}
if (counter >= 5) { // fade out
if ( i > 0) {
i--;
analogWrite(Red, i);
}
if ( j > 0) {
j--;
analogWrite(Green, j);
}
if ( k > 0) {
k--;
analogWrite(Blue, k);
}
delay(FadeRate);
if ( i == 0 && j == 0 && k == 0) {
counter = 0;
FirstStart = false;
keyloop = 0;
f_wdt = 0; // reset flag
pinMode(Red, INPUT);
pinMode(Green, INPUT);
pinMode(Blue, INPUT);
system_sleep();
}
}
}
}
}
}
//***************************************************************************
// set system into the sleep state
// system wakes up when wtchdog is timed out
void system_sleep() {
ADCSRA &= ~(1<<ADEN); //Disable ADC, saves ~230uA
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable();
sleep_mode(); // System sleeps here
sleep_disable(); // System continues execution here when watchdog timed out
ADCSRA |= (1<<ADEN); //Enable ADC
}
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {
byte bb;
int ww;
if (ii > 9 ) ii = 9;
bb = ii & 7;
if (ii > 7) bb |= (1 << 5);
bb |= (1 << WDCE);
ww = bb;
MCUSR &= ~(1 << WDRF); //This bit is set if a Watchdog Reset occurs. The bit is reset by a Power-on Reset, or by writing a logic zero to the flag
// start timed sequence
WDTCR |= (1 << WDCE) | (1 << WDE); // WDCE: Watchdog Change Enable --- WDE: Watchdog Enable
// set new watchdog timeout value
WDTCR = bb;
WDTCR |= _BV(WDIE);
}
// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect) {
f_wdt = 1; // set global flag
}
Altre info:
Attiny85 -1MHz (internal oscillator; BOD disabled)
fuse:
tinyx5.menu.cpu.attiny85at1.bootloader.low_fuses=0x62
tinyx5.menu.cpu.attiny85at1.bootloader.high_fuses=0xD7
tinyx5.menu.cpu.attiny85at1.bootloader.extended_fuses=0xFF
il led è collegato ai pin 0, 1 e 4
alimentazione diretta a 3V, 2 batterie stilo cariche
Ho provato a:
inserire condensatori tra Vcc e GND da 100n, 200n, 1u, 10u ---> non cambia niente
staccare tutti i led --> non cambia niente
modificare il codice mettendo il pin4 come input, di fatto togliendo un colore --> funziona per 33 min circa
Francamente non so più cosa provare, perlomeno per capire dov'è il problema :
qualche idea??
P.S. lo sleep l'ho inserito seguendo questo sketch, che comunque funziona
P.P.S eliminando lo sleep, quindi facendo giochi di luce di continuo il micro funziona correttamente