Обработка нескольких паттернов одновременно возможна с такой платформой, как Arduino, и вы можете сделать это несколькими способами.
Одним из методов, который я бы рассмотрел, является написание функций, которые эффективно представляют каждый шаблон математически. Вы просто передали бы его общее время, которое прошло в вашей программе, и оно выполнит соответствующее действие для этого конкретного момента времени. Он вернется сразу после этого (без задержек или чего-либо).
Чтобы сделать это, вам сначала нужно узнать, как долго длится один цикл паттерна. Затем вы можете использовать оператор по модулю, чтобы выяснить, как далеко вы прошли текущий цикл. Оттуда все, что вам нужно сделать, это иметь некоторые if
условия, чтобы определить, что делать в любой момент времени.
Вот как это может выглядеть для вашей схемы «5 секунд включено, 5 секунд выключено»:
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);
}
По общему признанию, постоянно звонить, digitalWrite()
когда вам технически не нужно, не очень эффективно. Это не должно причинить никакого вреда, и его довольно легко оптимизировать при необходимости.
Чтобы использовать приведенный выше пример в наброске, вам нужно просто позвонить loop()
и передать номер, с которого вы получили millis()
; например:
void loop()
{
const unsigned long totalTime = millis();
pattern5on5off(totalTime);
// call other patterns here...
}
Другие шаблоны будут более сложными, но будут следовать тому же принципу. Вы бы просто использовали соответствующие if
выражения, чтобы выразить свою логику.
Важно помнить, что функция представляет определенный момент времени. Он никогда не должен приостанавливать или задерживать программу, иначе это предотвратит запуск других шаблонов.
Изменить: время в первом цикле
Как отметил jfpoilpret в комментариях, самый первый цикл начнется в случайной точке. Это происходит потому , что первый раз , когда вы звоните millis()
в loop()
, он не запустится при 0 (устройство уже работает в течение короткого времени , прежде чем loop()
будет вызвана). Это легко решить, хотя, если это необходимо.
Вы бы сделали это, сместив totalTime
значение на то значение, которое вы получили в самый первый раз loop()
. Например:
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..
}