Interrupt: Lauflicht mit Fernbedienung

Lesezeit: 7 Minuten

Lösung
Seite als PDF

Die Fernbedienung steuert verschiedene Lauflichter. Sie leuchten jeweils solange, bis eine beliebige andere Taste auf der Fernbedienung gedrückt wird.
Taste 1 → die LEDs leuchten nacheinander für 100 ms,
Taste 2 → die LEDs leuchten nacheinander für 100 ms vor und zurück
Taste 3 → LEDs blinken zufällig oft nacheinander

So sieht es aus:

Benötigte Bauteile:

  • 5 LEDs
  • 3 Widerstände 220 Ω (gelbe, rote und grüne LED)
  • 2 Widerstände 100 Ω (blaue und weiße LED)
  • Infrarot-Empfänger
  • Keyes-Fernbedienung
  • Leitungsdrähte

Beachte die ➨Vorwiderstände verschiedener LEDs

Baue die Schaltung auf.
(Fahre mit der Maus über das Bild, um die Bezeichnungen der Bauteile zu sehen)

Ach­te auf die Pin­be­le­gung der Infra­ro­tem­pfän­ger.

Achte darauf, dass die Batterie richtig eingelegt wurde. Der Minus-Pol liegt oben.

Benötigte Bibliothek:

Suche die Bibliothek IRremote ...

… kli­cke auf Instal­lie­ren.

Die Fern­be­die­nung sen­det beim Druck auf die Tas­ten einen Zah­len­code.

Tastencodes Keyes-Fernbedienung

Pfeil oben
Tastencode70
Pfeil linksTaste OKPfeil rechts
Tastencode686467
Pfeil unten
Tastencode21
Taste 1Taste 22Taste 3
Tastencode222513
Taste 4Taste 5Taste 6
Tastencode122494
Taste 7Taste 8Taste 9
Tastencode82890
Taste *Taste 0Taste #
Tastencode668274

➨Tastencodes OpenSmart Fernbedienung

➨Testprogramm beliebige Fernbedienung

Die Tas­ten­codes kannst du mit fol­gen­dem Pro­gramm her­aus­fin­den. Sie wer­den im Seri­el­len Moni­tor ange­zeigt.

// benötigte Bibliothek einbinden
# include "IRremote.h"

// der Pin, an dem der Infrarot-Empfänger angeschlossen ist
int EmpfaengerPin = 2;

void setup() 
{
  // Seriellen Monitor starten
  Serial.begin(9600);
  
  // Infrarot-Empfänger starten
  IrReceiver.begin(EmpfaengerPin);
}

void loop() 
{
  // decode() -> Daten lesen
  if (IrReceiver.decode()) 
  {
    // kurzes delay, damit nur ein Tastendruck gelesen wird
    
    delay(200);

    // resume -> nächsten Wert lesen
    IrReceiver.resume();

    /*
      der Empfänger empfängt zwischendurch Signale, 
      die nicht ausgewertet werden können
      es sollen deshalb nur die korrekt erkannten Tasten ausgewertet werden
      die Dezimalwerte der korrekten erkannten Tasten liegen zwischen > 0 und < 95
      es wird abgefragt, ob das empfangene Kommando decodedIRData.command
      zwischen 0 und (&&) 95 liegt
    */
    if (IrReceiver.decodedIRData.command > 0 && IrReceiver.decodedIRData.command < 95) 
    {
      Serial.print("Dezimalwert: ");

      // IrReceiver.decodedIRData.command = Wert der gedrückten Taste
      Serial.print(IrReceiver.decodedIRData.command);
      Serial.print(" -> ");

      // Werte abfragen und anzeigen
      if (IrReceiver.decodedIRData.command == 22) Serial.println("Taste 1");
      if (IrReceiver.decodedIRData.command == 25) Serial.println("Taste 2");
      if (IrReceiver.decodedIRData.command == 13) Serial.println("Taste 3");
      if (IrReceiver.decodedIRData.command == 12) Serial.println("Taste 4");
      if (IrReceiver.decodedIRData.command == 24) Serial.println("Taste 5");
      if (IrReceiver.decodedIRData.command == 94) Serial.println("Taste 6");
      if (IrReceiver.decodedIRData.command == 8) Serial.println("Taste 7");
      if (IrReceiver.decodedIRData.command == 28) Serial.println("Taste 8");
      if (IrReceiver.decodedIRData.command == 90) Serial.println("Taste 9");
      if (IrReceiver.decodedIRData.command == 82) Serial.println("Taste 0");
      if (IrReceiver.decodedIRData.command == 66) Serial.println("Taste *");
      if (IrReceiver.decodedIRData.command == 74) Serial.println("Taste #");
      if (IrReceiver.decodedIRData.command == 68) Serial.println("Pfeil links");
      if (IrReceiver.decodedIRData.command == 67) Serial.println("Pfeil rechts");
      if (IrReceiver.decodedIRData.command == 70) Serial.println("Pfeil oben");
      if (IrReceiver.decodedIRData.command == 21) Serial.println("Pfeil unten");
      if (IrReceiver.decodedIRData.command == 64) Serial.println("OK");
    }
  }
}

Beispiel:

Durch Drücken der Taste Pfeil nach oben wird eine LED eingeschaltet, Pfeil nach unten schaltet sie wieder aus.

# include "IRremote.h"

int EmpfaengerPin = 2;

int LED = 3;

void setup()
{
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial) {;}

  // Empfänger starten
  IrReceiver.begin(EmpfaengerPin);

  pinMode(LED, OUTPUT);
}

void loop()
{
  // Daten lesen
  if (IrReceiver.decode())
  {
    // oben
    if (IrReceiver.decodedIRData.command == 70 )
    {
      digitalWrite(LED, HIGH);
    }

    // unten
    else if (IrReceiver.decodedIRData.command == 21)
    {
      digitalWrite(LED, LOW);
    }

    delay(200);

    // nächsten Wert lesen
    IrReceiver.resume();
  }
}

Binde die benötigte Bibliothek ein und definiere die Variablen.

# include "IRremote.h"

// Pin für den Auslöser des Interrupts
int InterruptPin = 2;

// Array mit 5 Elementen und den zugehörigen Ports
int LED[5] = {3, 4, 5, 6, 7};

// Anzahl der LEDs feststellen
int LEDMax = sizeof(LED) / sizeof(LED[0]);

// Variable im Flash-Speicher ablegen
volatile bool Status = true;

int Leuchtdauer = 100;</irremote.h>

Der setup-Teil. Beachte die Kommentare

void setup()
{
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial) {;}
  
  // Zufallsgenerator starten
  randomSeed(analogRead(0));

  // Empfänger starten

  IrReceiver.begin(InterruptPin);

  for (int i = 0; i < LEDMax; i++)
  {
    pinMode(LED[i], OUTPUT);
  }

  // Funktion Schalten() dem Interrupt-Pin zuordnen
  attachInterrupt(digitalPinToInterrupt(InterruptPin), Schalten, FALLING);
}

attachInterrupt()

Im loop-Teil musst du zunächst die Tastencodes abfragen und anschließend die Tastencodes mit ➨switch auswerten:

void loop()
{
  // Daten lesen
  if (IrReceiver.decodedIRData.address == 0)
  {
    if (IrReceiver.decode()) 
    {
      delay(200);

      Status = true;
      /*
        solange der Status true ist, wird die jeweilige while-Schleife
        ausgeführt, ein weiterer Druck auf eine Taste der Fernbedienung löst
        den Interrupt aus
        -> Status wird zu false, die while-Schleife wird nicht erneut   
        ausgeführt
      */
      switch (IrReceiver.decodedIRData.command) 
      {
        // Taste 1: Lauflicht vor
        case 22:
          while (Status) LauflichtHin();
          break;

        // Taste 2:  LEDs leuchten vor und zurück
        case 25:
          while (Status) LauflichtHinUndHer();
          break;

        // Taste 3: LEDs blinken nacheinander
        case 13:
          while (Status) LauflichtMitBlinken();
          break;
      }

      // nächsten Wert lesen
      IrReceiver.resume();
    }
  }
}

Beginne mit der Programmierung für die Lauflichter.

Schreibe ➨Funktionen für die den Tasten der Fernbedienung zugeordneten Ereignisse:

LEDBlinken()
LauflichtHin()
LauflichtHinUndHer()
LauflichtMitBlinken()

und die durch den Interrupt ausgelöste Funktion Schalten(). Sie ändert den Zustand von Status auf false.

void LEDBlinken(int LEDNummer, int Anzahl)
{
  for (int i = 0; i <= Anzahl; i ++)
  {
    digitalWrite(LEDNummer, HIGH);
    delay(Leuchtdauer);
    digitalWrite(LEDNummer, LOW);
    delay(Leuchtdauer);
  }
}

void LauflichtHin()
{
  for (int i = 0; i < LEDMax; i ++)
  {
    digitalWrite(LED[i], HIGH);
    delay(Leuchtdauer);
    digitalWrite(LED[i], LOW);
  }
}

void LauflichtMitBlinken()
{
  for (int i = 0; i < LEDMax; i++)
  {
    int Anzahl = random(1, 5);

    /* aktuelle LED i einschalten
      → Funktion LEDBlinken aufrufen
    */
    LEDBlinken(LED[i], Anzahl);
  }
}

void LauflichtHinUndHer()
{
  for (int i = 0; i < LEDMax; i++)
  {
    digitalWrite(LED[i], HIGH);
    delay(Leuchtdauer);
    digitalWrite(LED[i], LOW);
  }

  // und wieder zurück
  for (int i = LEDMax - 1; i >= 0; i--)
  {
    digitalWrite(LED[i], HIGH);
    delay(Leuchtdauer);
    digitalWrite(LED[i], LOW);
  }
}

void Schalten() 
{
  Status = false; 
}

Startseite
Aufgaben A-Z
Suchen
Downloads
Fehlermeldungen
Seite als PDF

Verwandte Aufgaben:


Letzte Aktualisierung: 4. Okt 2023 @ 11:06