@tuxduino
Allora.... ho fatto un po' di test.
Intanto le certezze: una ISR di default non è interrotta da un'altra ISR.
Ho provato il tuo sketch e vedevo anch'io lampeggiare i 3 led. Una cosa che ho notato, però, è stata che i led 7 e 8 lampeggiavano entrambi con una frequenza che era la metà di quella del led 9, quindi non solo il led 8 ma anche il led sul pin 7, quello pilotato da un task in cui c'era un delay(800). Un delay che avrebbe dovuto inserire una certa differenza e quindi togliere la sincronizzazione dei flash.
Ho perciò preso un semplice sketch:
#include <leOS.h>
leOS myOS;
//variables to control the LEDs
byte led1Status = 0;
const byte LED1 = 7;
void setup() {
pinMode(LED1, OUTPUT);
Serial.begin(19200);
myOS.begin();
myOS.addTask(flashLed1, 500);
}
//main loop
void loop() {
digitalWrite(LED1, led1Status ? HIGH : LOW);
led1Status ^= 1;
}
//first task
void flashLed1() {
delay(10000);
}
Se il delay avesse funzionato nei task come tu affermavi accadeva, il led avrebbe lampeggiato regolarmente ogni secondo. Invece vedevo un velocissimo lampeggio.
Ho preso un altro sketch:
#include <leOS.h>
leOS myOS;
//variables to control the LEDs
byte led1Status = 0;
const byte LED1 = 7;
void setup() {
pinMode(LED1, OUTPUT);
Serial.begin(19200);
myOS.begin();
myOS.addTask(flashLed1, 500);
}
//main loop
void loop() {
digitalWrite(LED1, led1Status ? HIGH : LOW);
led1Status ^= 1;
}
//first task
void flashLed1() {
Serial.println(micros(), DEC);
delay(10000);
Serial.println(micros(), DEC);
}
Sul monitor seriale ho ottenuto:
1000372
1000632
1500140
1500344
1999844
2000056
2499560
2499768
2999264
2999480
3498984
3499192
3998700
3998904
4498420
4498620
4998132
4998332
5497828
5498040
In teoria la cosa dovrebbe essere impossibile perché delay è una funzione che attende del tempo sfruttando un contatore interno:
void delay(unsigned long ms)
{
uint16_t start = (uint16_t)micros();
while (ms > 0) {
if (((uint16_t)micros() - start) >= 1000) {
ms--;
start += 1000;
}
}
}
Come vedi, ogni 1000 microsecondi, viene sottratto 1 ms al valore passato.
E micros() legge direttamente dal contatore agganciato al timer 0 (ed il timer continua a funzionare, solo che non viene più chiamato il relativo interrupt). Quindi non passa dalla ISR che aggiorna invece il valore di millis(). Però ovviamente, essendo gli interrupt fermi, il valore di timer0_overflow_count non viene incrementato per cui il ritardo non è esattamente calcolato.
Che tu metta un delay(1000) o un delay(10000) il risultato è di pochissimo differente.
Usando millis, invece, il tutto "muore". Ecco uno sketch di esempio:
#include <leOS.h>
leOS myOS;
//variables to control the LEDs
byte led1Status = 0;
const byte LED1 = 7;
void setup() {
pinMode(LED1, OUTPUT);
Serial.begin(19200);
myOS.begin();
myOS.addTask(flashLed1, 500);
}
//main loop
void loop() {
digitalWrite(LED1, led1Status ? HIGH : LOW);
led1Status ^= 1;
}
//first task
void flashLed1() {
unsigned long tempMillis = millis() + 10000;
while (tempMillis > millis()); //morte cerebrale....
}