Ich hab eine Nutzerfrage von Falk bekommen. Wie kann man eine LED ein- und ausfaden, während gleichzeitig zwei andere LEDs in unterschiedlichen Geschwindigkeiten blinken? In diesem Projekt geht es darum, einen Leuchtturm und zwei Leuchttonnen für eine Modelleisenbahn zu betreiben. Man nennt diese Signale in der Seefahrt übrigens Befeuerung. Sehen wir uns das genauer an.
Bauteile
- 1x *
- 3x Widerstand 220 Ohm
- 3x LEDs Grün, Rot, Gelb
Schaltplan
Die Schaltung besteht aus der Teilschaltungen, die sich jeweils aus einem Vorwiderstand von 220 Ohm (rot-rot-braun, bzw. rot-rot-schwarz-schwarz) und einer LED zusammensetzen.
Code: Leuchtturm und Leuchttonnen mit Arduino
Sehen wir uns erst einmal den Code für eine einzelne LED an. Zuerst müssen wir doch eine ganze Menge an Hilfsvariablen deklarieren. Neben dem Pin, an dem die LED angeschlossen ist, legen wir das Array led1Timeout an. Es speichert die Dauer der einzelnen Leuchtphasen. Die erste Phase soll 500, die zweite 1000 Millisekunden dauern. Die Phasen repräsentieren abwechselnd leuchten und nicht leuchten. Da es in der Arduino-Sprache C keine Methode gibt, um die Länge eines Arrays zuverlässig zu erfragen, legen wir eine Variable an, die die Länge des Arrays speichert: led1Phases.
Die Variable led1Phase speichert die aktuelle Phase der LED, d.h. also in diesem Fall entweder 0 oder 1. Die Variable led1State wird bei jedem Phasenwechsel umgekehrt und im späteren Programmverlauf verwendet, um die LED ein- oder auszuschalten. Als letzte Variable benötigen wir led1Timer. Sie wird für die Timer-Funktion benötigt. Was Timer funktionieren habe ich hier für dich zusammengefasst: Timer mit Arduino – Alternative zu Delays.
int led1Pin = 2; // LED Pin für Tonne 1 (rote LED) int led1Timeout[] = {500,1000}; // Phasendauer Led 1 int led1Phases = 2; // speichert die Anzahl der Phasen int led1Phase = 0; // aktuelle Phase der LED int led1State = 1; // LED Zustand 1 = an, -1 = aus long led1Timer = 0; // LED timer
In der setup()-Methode konfigurieren wir den led1Pin als OUTPUT und starten den Timer.
void setup() { pinMode(led1Pin, OUTPUT); // Pin wird als Output deklariert led1Timer = millis(); // Start des Timers }
Im Loop prüfen wir erstmal den Timer. Wenn er abgelaufen ist, wird die Phase der LED erhöht: led1Phase++. Nun müssen wir prüfen, ob es überhaupt so viele LED-Phasen gibt. Wenn nicht, wird led1Phase auf 0 gesetzt. Die Variable led1State wird mit -1 multipliziert, was zu einer Wertumkehrung führt. Diese nutzen wir, um die LED ein- oder auszuschalten, je nachdem, ob led1State größer oder kleiner 0 ist.
void loop() { // LED 1 Handling if (millis()>led1Timer+led1Timeout[led1Phase]){ // prüft den Timer led1Phase++; // erhöht die Leuchtphase um 1 if (led1Phase>led1Phases-1){ // falls Leuchtphasenmaximum überschritten led1Phase = 0; // Leuchtphase zurücksetzen } led1Timer = millis(); // Timer resetten led1State *= (-1); // LED Zustand wird umgekehrt if (led1State>0) digitalWrite(led1Pin, HIGH); // wenn LED Zustand > 0, schalte LED ein else digitalWrite(led1Pin, LOW); // wenn LED Zustand < 0, schalte LED aus } delay(20); // kurze Pause }
Hier nochmal der zusammenhängende Code für eine LED:
int led1Pin = 2; // LED Pin für Tonne 1 (rote LED) int led1Timeout[] = {500,1000}; // Phasendauer Led 1 int led1Phases = 2; // speichert die Anzahl der Phasen int led1Phase = 0; // Aktuelle Phase der LED int led1State = 1; // LED Zustand 1 = an, -1 = aus long led1Timer = 0; // LED timer void setup() { Serial.begin(115200); pinMode(led1Pin, OUTPUT); // Pin wird als Output deklariert led1Timer = millis(); // Start des Timers } void loop() { // LED 1 Handling if (millis()>led1Timer+led1Timeout[led1Phase]){ // prüft den Timer led1Phase++; // erhöht die Leuchtphase um 1 if (led1Phase>led1Phases-1){ // falls Leuchtphasenmaximum überschritten led1Phase = 0; // Leuchtphase zurücksetzen } led1Timer = millis(); // Timer resetten led1State *= (-1); // LED Zustand wird umgekehrt if (led1State>0) digitalWrite(led1Pin, HIGH); // wenn LED Zustand > 0, schalte LED ein else digitalWrite(led1Pin, LOW); // wenn LED Zustand < 0, schalte LED aus } delay(20); // kurze Pause }
Damit haben wir erstmal eine sehr komplizierte Version des Arduino-Blink-Beispiels erschaffen. Es ermöglicht uns aber, durch copy&paste mehr LEDs in unterschiedlichen Intervallen blinken zu lassen. Der folgende Code umfasst zwei unterschiedlich blinkende LEDs und eine ein- und ausfadende LED. Die fadende LED ist das Signalfeuer des Leuchtturms, die beiden blinkenden LEDs die der Tonnen.
int led1Pin = 2; // LED Pin für Tonne 1 (rote LED) int led2Pin = 3; // LED Pin für Tonne 2 (grüne LED) int led3Pin = 5; // LED Pin für Leuchtturm int led1Timeout[] = {500,1000}; // Phasendauer Led 1 int led2Timeout[] = {100,200,100,1500}; // Phasendauer Led 2 int led3Timeout[] = {500,500,1500}; // Phasendauer Led 3 int led1Phases = 2; // speichert die Anzahl der Phasen int led2Phases = 4; // speichert die Anzahl der Phasen int led3Phases = 3; // speichert die Anzahl der Phasen int led1Phase = 0; // Aktuelle Phase der LED int led2Phase = 0; // Aktuelle Phase der LED int led3Phase = 0; // Aktuelle Phase der LED int led1State = 1; // LED Zustand 1 = an, -1 = aus int led2State = 1; // LED Zustand 1 = an, -1 = aus int led3State = 0; // LED Zustand von 0 - 255 = Leuchtstärke long led1Timer = 0; // LED timer long led2Timer = 0; // LED timer long led3Timer = 0; // LED timer void setup() { Serial.begin(115200); pinMode(led1Pin, OUTPUT); // Pin wird als Output deklariert pinMode(led2Pin, OUTPUT); // Pin wird als Output deklariert led1Timer = millis(); // Start des Timers led2Timer = millis(); // Start des Timers } void loop() { // LED 1 Handling if (millis()>led1Timer+led1Timeout[led1Phase]){ // prüft den Timer led1Phase++; // erhöht die Leuchtphase um 1 if (led1Phase>led1Phases-1){ // falls Leuchtphasenmaximum überschritten led1Phase = 0; // Leuchtphase zurücksetzen } led1Timer = millis(); // Timer resetten led1State *= (-1); // LED Zustand wird umgekehrt if (led1State>0) digitalWrite(led1Pin, HIGH); // wenn LED Zustand > 0, schalte LED ein else digitalWrite(led1Pin, LOW); // wenn LED Zustand < 0, schalte LED aus } // LED 2 Handling if (millis()>led2Timer+led2Timeout[led2Phase]){ // prüft den Timer led2Phase++; // erhöht die Leuchtphase um 1 if (led2Phase>led2Phases-1){ // falls Leuchtphasenmaximum überschritten led2Phase = 0; // Leuchtphase zurücksetzen } led2Timer = millis(); // Timer resetten led2State *= (-1); // LED Zustand wird umgekehrt if (led2State>0) digitalWrite(led2Pin, HIGH); // wenn LED Zustand > 0, schalte LED ein else digitalWrite(led2Pin, LOW); // wenn LED Zustand < 0, schalte LED aus } // LED 3 Handling Fading if (millis()>led3Timer+led3Timeout[led3Phase]){ // prüft den Timer led3Phase++; // erhöht die Leuchtphase um 1 if (led3Phase>led3Phases-1){ // falls Leuchtphasenmaximum überschritten led3Phase = 0; // Leuchtphase zurücksetzen } led3Timer = millis(); // Timer resetten } if (led3Phase==0) { // wenn led3State == 0, dann einfaden analogWrite(led3Pin, map(millis()-led3Timer,0,led3Timeout[0],0,255)); } else if (led3Phase==1) { // wenn led3State == 1, dann ausfaden analogWrite(led3Pin, 255-map(millis()-led3Timer,0,led3Timeout[0],0,255)); } else if (led3Phase==2){ // wenn led3State == 1, dann ausschalten analogWrite(led3Pin, 0); } delay(20); // kurze Pause }
Wenn dir das Projekt gefallen hat und du von weiteren interessanten Projekten inspiriert werden willst, sieh dir doch mal mein neues E-Book »Arduino Projekte Volume 1« an!
- Die beliebtesten Arduino-Projekte von StartHardware
- Inklusive Schaltplan, Beschreibung und Code
- Arduino-Schnellstart-Kapitel
- Kompakter Programmierkurs
Guten Tag allerseits,
Gibt es die Möglichkeit den vollständigen Code zu erhalten.
Grüße
Hi Stephan, meinst du den Code von dem Beispiel oben? Den könntest du einfach per Copy&Paste in einen leeren Arduino-Sketch kopieren. Liebe Grüße Stefan
Hi Stefan,
Ich hab das jetzt mal in die Software kopiert! leider gibt es in Zeile 26 eine Fehlermeldung. Ich verwende einen Nano, da ich unzählige rumliegen habe…
int led1Pin = 2; // LED Pin für Tonne 1 (rote LED)
int led1Timeout[] = {500,1000}; // Phasendauer Led 1
int led1Phases = 2; // speichert die Anzahl der Phasen
int led1Phase = 0; // aktuelle Phase der LED
int led1State = 1; // LED Zustand 1 = an, -1 = aus
long led1Timer = 0; // LED timer
void setup() {
pinMode(led1Pin, OUTPUT); // Pin wird als Output deklariert
led1Timer = millis(); // Start des Timers
}
void loop() {
// LED 1 Handling
if (millis()>led1Timer+led1Timeout[led1Phase]){ // prüft den Timer
led1Phase++; // erhöht die Leuchtphase um 1
if (led1Phase>led1Phases-1){ // falls Leuchtphasenmaximum überschritten
led1Phase = 0; // Leuchtphase zurücksetzen
}
led1Timer = millis(); // Timer resetten
led1State *= (-1); // LED Zustand wird umgekehrt
if (led1State>0) digitalWrite(led1Pin, HIGH); // wenn LED Zustand > 0, schalte LED ein
else digitalWrite(led1Pin, LOW); // wenn LED Zustand led1Timer+led1Timeout[led1Phase]){ // prüft den Timer
led1Phase++; // erhöht die Leuchtphase um 1
if (led1Phase>led1Phases-1){ // falls Leuchtphasenmaximum überschritten
led1Phase = 0; // Leuchtphase zurücksetzen
}
led1Timer = millis(); // Timer resetten
led1State *= (-1); // LED Zustand wird umgekehrt
if (led1State>0) digitalWrite(led1Pin, HIGH); // wenn LED Zustand > 0, schalte LED ein
else digitalWrite(led1Pin, LOW); // wenn LED Zustand led2Timer+led2Timeout[led2Phase]){ // prüft den Timer
led2Phase++; // erhöht die Leuchtphase um 1
if (led2Phase>led2Phases-1){ // falls Leuchtphasenmaximum überschritten
led2Phase = 0; // Leuchtphase zurücksetzen
}
led2Timer = millis(); // Timer resetten
led2State *= (-1); // LED Zustand wird umgekehrt
if (led2State>0) digitalWrite(led2Pin, HIGH); // wenn LED Zustand > 0, schalte LED ein
else digitalWrite(led2Pin, LOW); // wenn LED Zustand led3Timer+led3Timeout[led3Phase]){ // prüft den Timer
led3Phase++; // erhöht die Leuchtphase um 1
if (led3Phase>led3Phases-1){ // falls Leuchtphasenmaximum überschritten
led3Phase = 0; // Leuchtphase zurücksetzen
}
led3Timer = millis(); // Timer resetten
}
if (led3Phase==0) { // wenn led3State == 0, dann einfaden
analogWrite(led3Pin, map(millis()-led3Timer,0,led3Timeout[0],0,255));
} else if (led3Phase==1) { // wenn led3State == 1, dann ausfaden
analogWrite(led3Pin, 255-map(millis()-led3Timer,0,led3Timeout[0],0,255));
} else if (led3Phase==2){ // wenn led3State == 1, dann ausschalten
analogWrite(led3Pin, 0);
}
delay(20); // kurze Pause
}
Danke,
Ich habe von deinem Script „Leuchtturm-Tonne“ das Programmteil vom Leuchtturm für mein Programm Modellflugzeugbeleuchtung verwendet. Ich verwende dazu einen Arduino Pro Min mit zusätzlicher kleiner Verstärkerplatine. Geschaltet werden die Positionslichter (rot/grün/weiß) Landescheinwerfer, Doppelblitz an den Tragflächen und einfach Blitz an der Rumpfober- und Unterseite. Das ganze Script habe ich mir aus Programmen im Internet zusammen gesucht und zusammen gestellt. Was ich nicht geschafft habe, war ein Programmteil für ein auf- und abschwellendes Licht für das Seitenruder oben. Jetzt funktioniert alles so wie ich mir das vorstelle. Vielen Dank.
LG Hartmut
Hallo Hartmut,
vielen Dank für deinen netten Kommentar. Schön, dass dir der Beitrag geholfen hat. Ich hab übrigens mal ein Tutorial für eine Flugzeugbeleuchtung geschrieben. Ist ohne anschwellendes Licht, aber vielleicht für dich auch spannend: https://starthardware.org/flugzeugbeleuchtung-mit-arduino/
Liebe Grüße
Stefan