Mit einer Plattform wie Arduino ist es sicherlich möglich, mehrere Muster gleichzeitig zu verarbeiten, und es gibt eine Reihe von Möglichkeiten, wie Sie dies tun können.
Eine Methode, die ich in Betracht ziehen würde, ist das Schreiben von Funktionen, die jedes Muster effektiv mathematisch darstellen. Sie würden nur die Gesamtzeit übergeben, die bisher in Ihrem Programm vergangen ist, und es wird die entsprechende Aktion für diesen bestimmten Zeitpunkt ausführen. Es wird sofort danach zurückkehren (keine Verzögerungen oder irgendetwas).
Dazu müssen Sie zunächst wissen, wie lange ein einzelner Zyklus des Musters dauert. Sie können dann den Modulo-Operator verwenden, um herauszufinden, wie weit Sie durch den aktuellen Zyklus sind. Von dort aus müssen Sie lediglich einige if
Bedingungen festlegen, um zu bestimmen, was zu einem bestimmten Zeitpunkt zu tun ist .
So könnte es für Ihr Muster "5 Sekunden ein, 5 Sekunden aus" aussehen:
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);
}
Zugegeben, ständig anzurufen, digitalWrite()
wenn Sie es technisch nicht brauchen, ist nicht sehr effizient. Es sollte jedoch keinen Schaden anrichten und ist bei Bedarf recht einfach zu optimieren.
Um das obige Beispiel in einer Skizze zu verwenden, müssen Sie es nur aufrufen loop()
und die Nummer übergeben, von der Sie erhalten millis()
. z.B:
void loop()
{
const unsigned long totalTime = millis();
pattern5on5off(totalTime);
// call other patterns here...
}
Andere Muster sind komplexer, folgen jedoch demselben Prinzip. Sie müssten nur geeignete if
Anweisungen verwenden, um Ihre Logik auszudrücken.
Das Wichtigste ist, dass die Funktion einen bestimmten Zeitpunkt darstellt. Das Programm sollte niemals angehalten oder verzögert werden, da sonst die anderen Muster nicht ausgeführt werden können.
Bearbeiten: Timing im ersten Zyklus
Wie in den Kommentaren erwähnt, beginnt der allererste Zyklus an einem zufälligen Punkt. Dies liegt daran , das erste Mal , Sie rufen millis()
in loop()
, wird es nicht bei 0 beginnen (das Gerät bereits für kurze Zeit in Betrieb gewesen sein, bevor loop()
wird aufgerufen). Bei Bedarf ist es jedoch leicht zu lösen.
Sie würden dies tun, indem Sie den totalTime
Wert um den Wert versetzen, den Sie beim ersten Mal erhalten haben loop()
. Zum Beispiel:
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..
}