Gestire più pattern contemporaneamente è certamente possibile con una piattaforma come Arduino e ci sono diversi modi in cui puoi farlo.
Un metodo che prenderei in considerazione è la scrittura di funzioni che rappresentano efficacemente ogni modello matematicamente. Lo passeresti solo per il tempo totale trascorso finora nel tuo programma e farà l'azione appropriata per quel momento specifico. Tornerà immediatamente dopo (senza ritardi o altro).
Per fare ciò, devi prima sapere quanto dura un singolo ciclo del modello. È quindi possibile utilizzare l'operatore modulo per capire fino a che punto del ciclo corrente ci si trova. Da lì, tutto ciò che devi fare è avere alcune if
condizioni per determinare cosa fare in un dato momento.
Ecco come potrebbe apparire il tuo modello "5 secondi acceso, 5 secondi spento":
function pattern5on5off(unsigned long totalTime)
{
// Calculate how far through the current cycle we are
const unsigned long cycleTime = totalTime % 10000;
// If we're in the first 5 seconds of the cycle then turn the light on.
// Otherwise, turn it off.
if (cycleTime < 5000)
digitalWrite(3, HIGH);
else
digitalWrite(3, LOW);
}
Certo, chiamare costantemente digitalWrite()
quando tecnicamente non è necessario non è molto efficiente. Tuttavia, non dovrebbe causare alcun danno ed è abbastanza facile da ottimizzare se necessario.
Per usare l'esempio sopra in uno schizzo, devi solo chiamarlo loop()
e passare il numero da cui ottieni millis()
; per esempio:
void loop()
{
const unsigned long totalTime = millis();
pattern5on5off(totalTime);
// call other patterns here...
}
Altri schemi saranno più complessi, ma seguiranno lo stesso principio. Dovresti semplicemente usare le if
dichiarazioni appropriate per esprimere la tua logica.
La cosa vitale da ricordare è che la funzione rappresenta un momento specifico nel tempo. Non dovrebbe mai mettere in pausa o ritardare il programma, altrimenti impedirà l'esecuzione degli altri pattern.
Modifica: temporizzazione sul primo ciclo
Come notato da jfpoilpret nei commenti, il primo ciclo inizierà in un punto casuale. Questo perché la prima volta che si chiama millis()
in loop()
, non si avvia a 0 (il dispositivo sarà già stato in esecuzione per un breve periodo prima loop()
viene chiamato). È facile da risolvere, se necessario.
Lo faresti compensando il totalTime
valore di qualunque valore tu abbia ottenuto la prima volta loop()
. Per esempio:
unsigned long g_startTime = 0;
void loop()
{
unsigned long totalTime = 0;
if (g_startTime == 0) {
// This is the first cycle.
// Store the start time so we can compensate later.
g_startTime = millis();
} else {
// This is not the first cycle.
// Compensate for the start time.
totalTime = millis() - g_startTime;
}
pattern5on5off(totalTime);
// etc..
}