Anzeige

Flugzeugbeleuchtung mit Arduino

Ich habe von Stephan die Anfrage bekommen, wie man eine Flugzeugbeleuchtung mit Arduino bauen kann. Er schreibt:

»Hallo, da wir gerade beim Thema blinken sind,  ich suche einen Sketch für eine Flugzeugbeleuchtung (Boeing). Es gäbe im Internet zwar jede Menge für RC Flugzeuge, jedoch helfen die mir nicht da Signale von der Fernsteuerung ausgelesen werden. Ich möchte ein Standmodell beleuchten. Könnt ihr mir dabei behilflich sein?«

Stephan

Tja, da bin ich doch gern dabei. Da ich keine Ahnung davon habe, welche Beleuchtung es an Flugzeugen gibt, habe ich mir das auf Youtube angesehen. Captain Joe erklärt da die Beleuchtung eines Airbusses (https://www.youtube.com/watch?v=A1eqrunJuc0). Ich weiß nicht genau, ob es bei Boeing genau so ist, aber das Prinzip ist es bestimmt. Also:

Welche Lampen gibt es an einem Flugzeug? 

Flugzeugbeleuchtung mit Arduino Position der Lampen
Taxi LightEin 400 Watt Scheinwerfer am Bugfahrwerk (links), der nach vorne strahlt
Takeoff LightEin 600 Watt Scheinwerfer am Bugfahrwerk (rechts) der für den Start verwendet wird
Runway Turnoff LightLeicht Links und Rechts abstrahlend am Bugfahrwerk um während des Taxis und Takeoffs die Umgebung zu beleuchten
Wing & Engine Scan LightVom Rumpf aus beleuchten diese Scheinwerfer die Triebwerke und Tragflächen, sie ermöglichen es, nach Eisbildung zu prüfen
Anti-Collision BeaconEin heller roter Stroboskop-Blitz unter und / oder auf dem Rumpf
Landing LightsScheinwerfer (2x 600W), die nach nach vorn strahlen, um die Landebahn zu beleuchten. Sie sind in den Tragflächen eingelassen und fahren nach unten vorn aus (Start und Landung).
Navigation Lights (Position Lights)Rechts = grün, links = rot, dauerleuchtend im 110° Abstrahlwinkel, hinten weißes Licht 140°, damit können andere Piloten sehen, wohin sich das Flugzeug bewegt
High Intensity Strobe LightZwei Lichtblitze jeweils am Ende der Tragflächen und eines am Ende des Rumpfes – blitzen jede Sekunde einmal
Logo LightsIm Stabilisator, sie beleuchten die Rückflosse des Flugzeuges, um für Sichtbarkeit zu sorgen

Für ein schönes Modell lege ich mal noch zwei weitere Lichtquellen an. Eine für das Cockpit und eine für die Kabinenbeleuchtung.

Die Lichtblitz-Intervalle folgen einer speziellen Animation. Die Strobes blitzen zwei mal auf, dann gibt es eine Pause, dann blitzt das Anti-Collision Beacon, dann gibt es wieder eine Pause. Ich habe das mal in der folgenden Tabelle aufgeführt:

Pausenzeiten (ms) ->50505040050400
Strobe Lights (Tragflächen)HIGHLOWHIGHLOWLOWLOW
Anti-Collision BeaconLOWLOWLOWLOWHIGHLOW

Nun scheint es verschiedene Zustände des Flugzeuges zu geben. Ich nenne sie mal: Taxi, Takeoff, Climbing / Landing, In flight.


All OffGroundedTaxiTakeoffClimbing / LandingIn Flight
Taxi LightsLOWLOWHIGHHIGHLOWLOW
Takeoff LightsLOWLOWLOWHIGHLOWLOW
Runway Turnoff LightsLOWLOWHIGHLOWLOWLOW
Wing Engine Scan LightsLOWHIGHHIGHHIGHHIGHHIGH
Anti-Collision BeaconLOWLOWHIGH (Flashing)HIGH (Flashing)HIGH (Flashing)HIGH (Flashing)
Landing LightsLOWLOWLOWHIGHHIGHLOW
Navigation LightsLOWHIGHHIGHHIGHHIGHHIGH
High Intensity Strobe LightsLOWLOWLOWHIGH (Flashing)HIGH (Flashing)HIGH (Flashing)
Logo-LightsLOWHIGHHIGHHIGHHIGHHIGH
CockpitLOWHIGHHIGHHIGHHIGHHIGH
KabineLOWHIGHHIGHLOWHIGHHIGH

Schaltplan: Flugzeugbeleuchtung mit Arduino

Flugzeugbeleuchtung mit Arduino Schaltplan

Die Schaltung besteht aus einer Menge an Reihenschaltungen aus je einer LED und einem Vorwiderstand von 220 Ohm. Für die Blitze sollte man Ultra-Bright-LEDs verwenden. Die drei Navigaion Lights müssen jeweils einen Vorwiderstand bekommen. Das ist nervig, verhindert aber, dass sonst nur die LED mit dem kleinsten Innenwiderstand leuchtet. Bei unterschiedlichen Farben wäre das sonst unvermeidbar. Zusätzlich kommt noch ein Taster in die Schaltung, der dem Durchschalten der Zustände dient. 

Code

Gut. Damit lässt sich doch schon mal was anfangen. Im Programm verwende ich eine Status-Variable (myState). Sie merkt sich den Zustand, in dem sich das Flugzeug befindet. Welche Zustände das sind, lässt sich hier unten im Array sehen. Es speichert die Beleuchtungszustände pro Status. Das bedeutet, dass zum Beispiel im Status 4 die ersten drei LEDs ausgeschaltet sein sollen, alle anderen sollen eingeschaltet sein.

int beleuchtungsZustaende[9][11] = {
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  // state 0 All Off
  {0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1},  // state 1 Grounded
  {1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1},  // state 2 Taxi
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0},  // state 3 Takeoff
  {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},  // state 4 Climbing
  {0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1},  // state 5 In Flight
  {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},  // state 6 Landing
  {1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1},  // state 7 Taxi
  {0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1}   // state 8 Grounded
};

Ich füge gleich noch ein paar wiederholende Muster fest (z. B. ist Taxi sowohl State 2 als auch State 7), um eine schöne Abfolge zu erreichen (also vom Start bis zur Landung).

Alle LED-Pins werden auch in einem Array gespeichert. 

int ledPins[11] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

Nun können die LEDs also je nach Zustand ein- und ausgeschaltet werden. Der Status ändert sich, wenn man den Button drückt, der in die Schaltung integriert ist. Damit lassen sich also alle Beleuchtungszustände durchschalten:

  buttonState = digitalRead(buttonPin);
  if ((buttonState != lastButtonState) && (buttonState == LOW)) {
    myState++;
    if (myState >= 9) myState = 0;
  }

Die Methode zeigeBeleuchtung übernimmt die gesamte Ausgabe. Sie schaltet je nach Status (myState) durch eine for-Schleife die einzelnen LEDs ein- und aus.

void zeigeBeleuchtung() {
  for (int i = 0; i < 11; i++) {
    digitalWrite(ledPins[i], beleuchtungsZustaende[myState][i]);
  }
}

Der gesamte Code sieht dann so aus:

int ledPins[11] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int buttonPin = 13;

int beleuchtungsZustaende[9][11] = {
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  // state 0 All Off
  {0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1},  // state 1 Grounded
  {1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1},  // state 2 Taxi
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0},  // state 3 Takeoff
  {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},  // state 4 Climbing
  {0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1},  // state 5 In Flight
  {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},  // state 6 Landing
  {1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1},  // state 7 Taxi
  {0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1}   // state 8 Grounded
};

int myState = 0;
int buttonState;
int lastButtonState;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  for (int i = 0; i < 11; i++) {
    pinMode(ledPins[i], OUTPUT);
  }
}

void zeigeBeleuchtung() {
  for (int i = 0; i < 11; i++) {
    digitalWrite(ledPins[i], beleuchtungsZustaende[myState][i]);
  }
}

void loop() {
  buttonState = digitalRead(buttonPin);
  if ((buttonState != lastButtonState) && (buttonState == LOW)) {
    myState++;
    if (myState >= 9) myState = 0;
  }

  zeigeBeleuchtung();
  lastButtonState = buttonState;
  delay(10);
}

Nun sollen die Beacon- und Strobe-Lichter aber natürlich blinken. Da ich dafür keine Delays verwenden will, muss ich Timer-Funktionen einsetzen. Ich lege also zwei Arrays an. flashTimeouts speichert die oben erwähnten Wartezeiten, während flashBehaviour steuert, ob die Beacon- oder Strobe-LEDs an oder aus sein sollen. 

Der Einfachheit zu liebe betrachte ich zwei unterschiedliche Zustände. Beim ersten sollen sowohl die Beacon- als auch die Strobe-LED blitzen:

if ((beleuchtungsZustaende[myState][4] == 1) && (beleuchtungsZustaende[myState][7] == 1)) {
    digitalWrite(ledPins[4], flashBehaviour[0][flashPosition]);
    digitalWrite(ledPins[7], flashBehaviour[1][flashPosition]);
    if (flashTimer + flashTimeouts[flashPosition] < millis()) {
      flashPosition++;
      flashTimer = millis();
      if (flashPosition > 5) flashPosition = 0;
    }
}

Beim zweiten blitzt nur die Beacon-LED:

if ((beleuchtungsZustaende[myState][4] == 1) && (beleuchtungsZustaende[myState][7] == 0)) {
    digitalWrite(ledPins[4], flashBehaviour[0][flashPosition]);
    if (flashTimer + flashTimeouts[flashPosition] < millis()) {
      flashPosition++;
      flashTimer = millis();
      if (flashPosition > 5) flashPosition = 0;
    }
}

Ringsherum noch etwas Timer-Magie und dann sieht der zusammenhängende Code so aus:

int ledPins[11] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int buttonPin = 13;

int beleuchtungsZustaende[9][11] = {
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  // state 0 All Off
  {0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1},  // state 1 Grounded
  {1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1},  // state 2 Taxi
  {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0},  // state 3 Takeoff
  {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},  // state 4 Climbing
  {0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1},  // state 5 In Flight
  {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},  // state 6 Landing
  {1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1},  // state 7 Taxi
  {0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1}   // state 8 Grounded
};

int flashTimeouts[6] = {50, 50, 50, 400, 50, 400};
int flashBehaviour[2][6] = {{0, 0, 0, 0, 1, 0}, {1, 0, 1, 0, 0, 0}};
int flashPosition = 0;

long flashTimer = 0;

int myState = 0;
int buttonState;
int lastButtonState;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  for (int i = 0; i < 11; i++) {
    pinMode(ledPins[i], OUTPUT);
  }
}

void zeigeBeleuchtung() {
  for (int i = 0; i < 11; i++) {
    digitalWrite(ledPins[i], beleuchtungsZustaende[myState][i]);
  }
  if ((beleuchtungsZustaende[myState][4] == 1) && (beleuchtungsZustaende[myState][7] == 1)) {
    digitalWrite(ledPins[4], flashBehaviour[0][flashPosition]);
    digitalWrite(ledPins[7], flashBehaviour[1][flashPosition]);
    if (flashTimer + flashTimeouts[flashPosition] < millis()) {
      flashPosition++;
      flashTimer = millis();
      if (flashPosition > 5) flashPosition = 0;
    }
  }

  if ((beleuchtungsZustaende[myState][4] == 1) && (beleuchtungsZustaende[myState][7] == 0)) {
    digitalWrite(ledPins[4], flashBehaviour[0][flashPosition]);
    if (flashTimer + flashTimeouts[flashPosition] < millis()) {
      flashPosition++;
      flashTimer = millis();
      if (flashPosition > 5) flashPosition = 0;
    }
  }
}

void loop() {
  buttonState = digitalRead(buttonPin);
  if ((buttonState != lastButtonState) && (buttonState == LOW)) {
    myState++;
    flashTimer = millis();
    flashPosition = 0;
    if (myState >= 9) myState = 0;
  }

  zeigeBeleuchtung();
  lastButtonState = buttonState;
  delay(10);
}

Viel Spaß beim Nachbauen. Übrigens empfehle ich die Verwendung von SMD-LEDs für die Modell-Beleuchtung, da diese super klein sind. Zum Verkabeln kann man Lackdraht verwenden. Ist aber nicht so einfach im Handling. Allerdings ist das eine schöne Herausforderung. Du schaffst das schon :-) Der Torben hat das hier mal erklärt: SMD-LEDs und Lackdraht löten.

Wenn dir das Projekt gefallen hat und du von weiteren interessanten Projekten inspiriert werden willst, sieh dir doch mal mein neues E-Book an!

Darin findest du die beliebtesten Arduino-Projekte von StartHardware. Jedes Projekt umfasst Schaltplan, Bauteile, Beschreibung und Code. Für Einsteiger gibt es ein Arduino-Schnellstart-Kapitel und einen kompakten Programmierkurs. Zusätzlich findest du Zwischenkapitel mit Expertenwissen zu den Komponenten, die verwendet werden. Alle Code-Beispiele gibt es natürlich als Download.

Weitere Informationen findest du auf der Produktseite. Klicke jetzt auf den Button, um Details anzusehen.


Jetzt bist du gefragt: Welches Projekt würdest du gern auf dieser Seite finden? *


6 thoughts on “Flugzeugbeleuchtung mit Arduino

  1. Hallo Stefan,
    das ist echt eine super Hilfestellung – auch super erklärt.

    Falls man das “digitales Blinken” durch rampenförmiges / dimmendes Verhalten von den (Beacon)-LEDs haben möchte (4 Stück), wie könnte man dies machen?
    Ginge dies über Timings oder
    PWMs nutzen oder
    über Transistor ansteuern,
    wenn diese asynchron Blinken sollten?

    1. Hi Chris, vielen Dank für die netten Worte. Hast du für das Verhalten, dass du willst ein vielleicht ein Video-Beispiel? Dann kann ich mir das besser vorstellen. Ich habe nur das hier gefunden: https://www.youtube.com/watch?v=ZbXejOGsK1E – Da wirk aber alles synchron und digital. Wenn ich dich richtig verstehe, willst du die roten Beacons aber ein- und ausfaden, richtig? Was bedeutet asynchron in diesem Zusammenhang? Asynchron zu den weißen Strobe-Lights? Liebe Grüße Stefan

      1. Hallo Stefan,
        erstmal danke für die Antworten. Ich weiß nicht ob Stephans-Projekt dann störe bzw. es dort nicht so komplex werden braucht…Sorry schon mal @ Stephan.

        Konkret geht es bei mir um diese Flugzeug:
        https://www.youtube.com/watch?v=GSnLV_KxKcE

        Falls die Digicams keinen Streich bei den Aufnahmen gespielt haben, dann sehe ich folgende Herausforderungen:
        https://www.youtube.com/watch?v=_vFvwrOcUBg

        – Faden/Schwellende Beleuchtungen (+ ggf. Simulation laufende Rundumlichter wie bei deinem Videobespiel https://www.youtube.com/watch?v=ZbXejOGsK1E
        mit 2 oder 3 LEDs)
        – Blitzlichter, die langsam voneinander driften d.h. nicht mehr im Gleichtakt (ggf. nur ein Thema der Ausgänge – eher unwichtig)
        – Blitzlichter, die eine high high high low low high high high low low low Sequenz haben
        (Das ist bei dem Code oben ja im Prinzip schon drin – glaube ich.)

        // ggf. 74HC595 Schieberegister Implementierung, um nicht alles Ausgänge zu belegen.
        (Vielleicht komme ich aber auch mit low current LEDs hin und kann sie dann parallel schalten. Ich muss das mal mit passenden SMD LEDs aufbauen.)

        VG Chris

        1. Hi Chris,

          bin mir mit dem Rundumlicht immer noch nicht sicher, wie das genau aussehen soll, aber das Fading kannst du tatsächlich per PWM realisieren. Das überlasse ich aber aus zeitlichen Gründen erstmal dir. Trotzdem hab ich mich mal dem asynchronen Blinken angenommen. Hier mein Beispiel und viel Erfolg. Wenn du nicht weiter kommst, melde dich wieder. Spannendes Flugzeug übrigens. Krasser Nachbrenner! Gut, dass ich das nicht volltanken muss :-D

          int ledPins[11] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
          int buttonPin = 13;

          int beleuchtungsZustaende[9][11] = {
          {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // state 0 All Off
          {0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1}, // state 1 Grounded
          {1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1}, // state 2 Taxi
          {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0}, // state 3 Takeoff
          {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, // state 4 Climbing
          {0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1}, // state 5 In Flight
          {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, // state 6 Landing
          {1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1}, // state 7 Taxi
          {0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1} // state 8 Grounded
          };

          int flashTimeouts1[] = {950, 50}; // off, on
          int flashTimeouts2[] = {100, 50, 400, 50}; // off, on, off, on ...

          int flashEntries1 = 2;
          int flashEntries2 = 4;

          int flashPosition1 = 0;
          int flashPosition2 = 0;

          long flashTimer1 = 0;
          long flashTimer2 = 0;

          int myState = 0;
          int buttonState;
          int lastButtonState;

          void setup() {
          Serial.begin(115200);
          pinMode(buttonPin, INPUT_PULLUP);
          for (int i = 0; i < 11; i++) { pinMode(ledPins[i], OUTPUT); } } void zeigeBeleuchtung() { for (int i = 0; i < 11; i++) { digitalWrite(ledPins[i], beleuchtungsZustaende[myState][i]); } if ((beleuchtungsZustaende[myState][4] == 1) && (beleuchtungsZustaende[myState][7] == 1)) { if (flashPosition1%2==0) digitalWrite(ledPins[4], LOW); else digitalWrite(ledPins[4], HIGH); if (flashPosition2%2==0) digitalWrite(ledPins[7], LOW); else digitalWrite(ledPins[7], HIGH); if (flashTimer1 + flashTimeouts1[flashPosition1] < millis()) { flashPosition1++; flashTimer1 = millis(); if (flashPosition1 >= flashEntries1) flashPosition1 = 0;
          }
          if (flashTimer2 + flashTimeouts2[flashPosition2] < millis()) { flashPosition2++; flashTimer2 = millis(); if (flashPosition2 >= flashEntries2) flashPosition2 = 0;
          }
          }

          if ((beleuchtungsZustaende[myState][4] == 1) && (beleuchtungsZustaende[myState][7] == 0)) {
          if (flashPosition1%2==0) digitalWrite(ledPins[4], LOW);
          else digitalWrite(ledPins[4], HIGH);

          if (flashTimer1 + flashTimeouts1[flashPosition1] < millis()) { flashPosition1++; flashTimer1 = millis(); if (flashPosition1 >= flashEntries1) flashPosition1 = 0;
          }
          }

          }

          void loop() {
          buttonState = digitalRead(buttonPin);
          if ((buttonState != lastButtonState) && (buttonState == LOW)) {
          myState++;
          flashTimer1 = millis();
          flashTimer2 = millis();
          flashPosition1 = 0;
          flashPosition2 = 0;
          if (myState >= 9) myState = 0;
          }

          zeigeBeleuchtung();
          lastButtonState = buttonState;
          delay(10);
          }

  2. Hi Stefan, das ist ja toll, kann ich den Code einfach in die IDE einfügen oder muss da noch was geändert werden,? Auf SMD LEDs kann ich verzichten da es ein sehr großes aufgehäntes Modell ist (teilweise werden 10mm LEDs verwendet.

    1. Ja genau. Sollte einfach so klappen. Vielleicht musst du die Zeiten vom Array flashTimeouts
      anpassen, aber du brauchst keine Bibliotheken oder sonst was. Schick mir gern Fotos, wenn es funktioniert. Dann füge ich sie in den Beitrag ein. Und halt mich gern auf dem Laufenden :-)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

 

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.