Arduino mehrere Loops gleichzeitig schalten?
Hallo, ich bin noch relativ neu beim Arduino und wollte mal etwas probieren. Ich möchte über jeden PIN eine LED mit einer anderen Frequenz blinken lassen. Allerdings weiß ich nicht, wie ich die jewaligen Loops gleichzeitig schalten kann und ob dies überhaupt möglich ist. Könnte mir vielleicht jemand helfen?
Ich bedanke mich im vorraus schonmal über antworten
LG
3 Antworten
Das ist relativ einfach! Alles, was Du brauchst ist ein Zeitgeber. Das kann eine RTC sein, Software oder Hardware oder ein einfacher Timerinterrupt.
Nehmen wir den Timer. Wie der benutzt wird ist hier nachzulesen:
https://www.exp-tech.de/blog/arduino-tutorial-timer
Für jede LED braucht man dann nur zwei Variablen. Eine (kann const sein um RAM zu sparen) für die Dauer und eine zum zählen.
Das einfachste ist es, die LEDs mit in die ISR aufzunehmen, da wo "timer++" steht. Hier einfach für jede LED eine IF Abfrage:
if (!(--zLED1))
Das bedeutet "Ziehe 1 von zLED1 ab und wenn dann NICHT(!) etwas (⋄0) drin ist, dann mach…
Eine IF Abfrage wird ausgelöst, wenn in der zu prüfenden Variable keine Null drin ist. Mit dem ! dreht man das um, man will die Null als Auslöser.
if (!(--zLED1))
{ zLED1=dLED1;
//hier LED toggeln, also aus AUS mach EIN und umgekehrt.
}
zLEDx ist also ein Countdown, ist der abgelaufen wird die LED umgeschaltet und der Zähler wieder auf seinen ursprünglichen Wert gestellt, der Countdown beginnt von vorne.
Im Setup muss man natürlich die Variablen mit einem Wert füllen, zLEDx für das erste mal zählen vorbereiten. Steht da irgendwas drin, kann es u.U. sehr lange dauern bis die LED das erste mal an bzw. aus geht! Also im Setup z.B.
zLED1=dLED1=500;
schreiben!
Diese Variablen muss man natürlich global deklarieren, sonst hat die ISR keinen zugriff bzw. in der ISR generiert werden die nach Ablauf der ISR ungültig.
Möchte man aus dem Hauptprogramm auf diese Variablen zugreifen, muss man die unbedingt als "volatile", also z.B. "unsigned volatile int zLED1" deklarieren. Das bedeutet, dass der inhalt sich "von selbst" innerhalb eines Programms ändern kann. Macht man das nicht, arbeitet das programm zum Teil mit veralteten kopien im prozessorregister was dann zu den interessantesten Fehlfunktionen führen kann. Zum Beispiel kann dann ein Byte vom INT mit dem neuen Wert, die andere Hälfte noch mit dem alten Wert verwendet werden, dann werden natürlich ganz neue Zahlen erfunden.
P.S.:
Das schöne an dem Timer der die LED steuert ist, dass man da auch ein Flag benutzen kann die LED überhaupt ein- und auszuschalten. Ist das Flag gesetzt, werden die Blink-IFs ausgeführt, sonst nicht.
Dann kann man im Hauptprogramm durch setzen und löschen des Flags das Blinken bequem ein- und ausschalten.
Praktisch alle meiner Programme mit blinkenden LEDs arbeiten so, denn im Programm braucht man dann nur ein- und ausschalten und die LED blinkt weiter während das Programm was anderes macht. Natürlich kann man auch die Frequenz verstellen (dLEDx) um z.B. bei einer ERROR LED verschiedene Fehlerarten anzeigen zu können, also schnell und langsam blinken bzw. an und aus.
Nein, man kann aber über eine Differenzrechnung mit milis() abfragen welche LED dran ist.
Ist net möglich. Du kannst immer nue einen Prozess gleichzeitig laufen lassen. Sogar morderne PCs können meistens nur 8 gleichzeitig machen. Sie schalten nur schnell genug hin und her.
Ein Lösungsansatz wäre, wenn du das ggT aller Frequenzen berechnest und das dann mit entsprechenden Abständen taktest.
Ach, moderne Heim-PCs kommen gerne auch auf 16 Threads