Come spunto aggiungo anche il codice di esempio di miky_police in forma di macchine a stati, come suggerito qualche post precedente.
Oltre al fading lampeggia anche indisturbato il led on board, e allo stesso modo possono essere portati avanti altri N lavori indipendenti in contemporanea.
Curiosità: In questo codice le due funzioni gestFader e gestObdLed vengono eseguite circa 50mila volte al secondo ciascuna, quindi il ciclo programma è di circa 20 microsecondi.
//----------------------------------------------------------------------------
#define EXT_LED_PIN 3
#define OBD_LED_PIN 13
//----------------------------------------------------------------------------
void setup()
{
pinMode(EXT_LED_PIN, OUTPUT);
pinMode(OBD_LED_PIN, OUTPUT);
}
//----------------------------------------------------------------------------
void loop()
{
gestFader(); // processo alba-tramonto su led esterno
gestObdLed(); // processo lampeggio led on board 1Hz
}
//----------------------------------------------------------------------------
void gestObdLed()
{
static unsigned long tempo = 0;
if(millis() - tempo >= 500)
{
tempo += 500;
digitalWrite(OBD_LED_PIN, !digitalRead(OBD_LED_PIN));
}
}
//----------------------------------------------------------------------------
void gestFader()
{
static byte fase = 0;
static unsigned long tempo = 0;
static int fadeValue = 0;
switch (fase)
{
case 0: // IN ACCENSIONE (durata 1.53 sec)
analogWrite(EXT_LED_PIN, fadeValue);
if(millis() - tempo >= 30)
{
tempo += 30;
fadeValue += 5;
if(fadeValue > 255) { tempo = millis(); fase = 1; }
}
break;
//------------------------------------------------------------
case 1: // DURATA GIORNO 3 SECONDI
if(millis() - tempo >= 3000)
{
fadeValue = 255;
tempo = millis();
fase = 2;
}
break;
//------------------------------------------------------------
case 2: // IN SPEGNIMENTO (durata 1.53 sec)
analogWrite(EXT_LED_PIN, fadeValue);
if(millis() - tempo >= 30)
{
tempo += 30;
fadeValue -= 5;
if(fadeValue < 0) { tempo = millis(); fase = 3; }
}
break;
//------------------------------------------------------------
case 3: // DURATA NOTTE 5 SECONDI
if(millis() - tempo >= 5000)
{
fadeValue = 0;
tempo = millis();
fase = 0;
}
}//end switch
}
//----------------------------------------------------------------------------
La dimostrazione del fatto che il problema non è strettamente delay contro millis, ma la struttura logica con cui si imposta l'esecuzione, è il codice seguente, che fa la stessa cosa senza usare millis ma solo delay e non blocca nulla ![]()
//----------------------------------------------------------------------------
#define EXT_LED_PIN 3
#define OBD_LED_PIN 13
//----------------------------------------------------------------------------
void setup()
{
pinMode(EXT_LED_PIN, OUTPUT);
pinMode(OBD_LED_PIN, OUTPUT);
}
//----------------------------------------------------------------------------
void loop()
{
gestFader(); // processo alba-tramonto su led esterno
gestObdLed(); // processo lampeggio led on board 1Hz
delay(10); // temporizza il programma a passi di *circa* 10ms
}
//----------------------------------------------------------------------------
void gestObdLed()
{
static unsigned long tempo = 0;
static byte counter = 0;
if(++counter == 50)
{
counter = 0;
digitalWrite(OBD_LED_PIN, !digitalRead(OBD_LED_PIN));
}
}
//----------------------------------------------------------------------------
void gestFader()
{
static byte fase = 0;
static unsigned long tempo = 0;
static int fadeValue = 0;
static int counter = 0;
switch (fase)
{
case 0: // IN ACCENSIONE (durata 1.53 sec)
analogWrite(EXT_LED_PIN, fadeValue);
if(++counter == 3)
{
counter = 0;
fadeValue += 5;
if(fadeValue > 255) { counter = 0; fase = 1; }
}
break;
//------------------------------------------------------------
case 1: // DURATA GIORNO 3 SECONDI
if(++counter == 300)
{
fadeValue = 255;
counter = 0;
fase = 2;
}
break;
//------------------------------------------------------------
case 2: // IN SPEGNIMENTO (durata 1.53 sec)
analogWrite(EXT_LED_PIN, fadeValue);
if(++counter == 3)
{
counter = 0;
fadeValue -= 5;
if(fadeValue < 0) { counter = 0; fase = 3; }
}
break;
//------------------------------------------------------------
case 3: // DURATA NOTTE 5 SECONDI
if(++counter == 500)
{
fadeValue = 0;
counter = 0;
fase = 0;
}
}//end switch
}
//----------------------------------------------------------------------------
Nota: naturalmente in questo caso il ciclo programma è di 10ms, le funzioni vengono cioè eseguite solo cento volte al secondo.