Manejar múltiples patrones al mismo tiempo es ciertamente posible con una plataforma como Arduino, y hay varias maneras de hacerlo.
Un método que consideraría es escribir funciones que representen efectivamente cada patrón matemáticamente. Simplemente le pasará el tiempo total que ha transcurrido en su programa hasta el momento, y realizará la acción adecuada para ese momento específico en el tiempo. Volverá inmediatamente después (sin demoras ni nada).
Para hacer eso, primero necesitará saber cuánto dura un solo ciclo del patrón. Luego puede usar el operador de módulo para averiguar qué tan avanzado está el ciclo actual. A partir de ahí, todo lo que necesita hacer es tener algunas if
condiciones para determinar qué hacer en un momento dado.
Esto es lo que podría parecer para su patrón "5 segundos encendido, 5 segundos apagado":
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);
}
Es cierto que llamar constantemente digitalWrite()
cuando técnicamente no es necesario no es muy eficiente. Sin embargo, no debería causar ningún daño y es bastante fácil de optimizar si es necesario.
Para usar el ejemplo anterior en un boceto, solo debe llamarlo loop()
y pasar el número que obtiene millis()
; p.ej:
void loop()
{
const unsigned long totalTime = millis();
pattern5on5off(totalTime);
// call other patterns here...
}
Otros patrones serán más complejos, pero siguen el mismo principio. Simplemente usaría if
declaraciones apropiadas para expresar su lógica.
Lo vital para recordar es que la función representa un momento específico en el tiempo. Nunca debe pausar o retrasar el programa, de lo contrario evitará que se ejecuten los otros patrones.
Editar: Tiempo en el primer ciclo
Como jfpoilpret señaló en los comentarios, el primer ciclo comenzará en un punto aleatorio. Esto se debe a que la primera vez que se llama millis()
en loop()
, no empezará a 0 (el dispositivo ya han estado funcionando durante un corto tiempo antes de que loop()
obtiene la llamada). Sin embargo, es fácil de resolver, si es necesario.
Lo harías compensando el totalTime
valor por el valor que obtuviste la primera vez loop()
. Por ejemplo:
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..
}