Interrupt: Lauflicht mit Fernbedienung

Lesezeit: 8 Minuten

Lösung
Seite als PDF
Navigation

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
  • 5 Widerstände > 100 Ω
  • Infrarot-Empfänger
  • Keyes-Fernbedienung
  • Leitungsdrähte

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 des Infra­ro­tem­pfän­gers.

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

Benötigte Bibliothek:

Arduino IDE 1.8x:
Sketch → Bibliothek einbinden → Bibliotheken verwalten

Suche die Bibliothek IRremote ...

… kli­cke auf Instal­lie­ren.

Arduino IDE 2.x:

Die Anleitung bezieht sich auf die Version 3.x der Bibliothek IRremote.

🔗 Anpassung von der Version 2.7x zu 3.x (externer Link, abgerufen am 24.4.2022)

🔗 Umwandlung von Zahlensystem (externer Link, abgerufen am 24.4.2022)

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

Die Tastencodes beziehen sich auf die Keyes-Fernbedienung oder die Opensmart-Fernbedienung.

Tastencodes Keyes-Fernbedienung (hexadezimal und dezimal)

obenlinksrechtsuntenOK1234
0x46
70
0x44
68
0x43
67
0x15
21
0x40
64
0x16
22
0x19
25
0xD
13
0xC
12
56789+0#
0x18
24
0x5E
94
0x8
8
0x1C
28
0x5A
90
0x42
66
0x52
82
0x4A
74

Tastencodes Opensmart-Fernbedienung (hexadezimal und dezimal)

Ein/ausMenuTest+| ◄ ◄►►|0-
0x45
69
0x47
71
0x44
68
0x40
64
0x40
64
0x7
7
0x15
21
0x9
9
0x16
22
0x19
25
C123456789
0xD
13
0xC
12
0x18
24
0x5E
94
0x8
8
0x1C
28
0x5A
90
0x42
66
0x52
82
0x4A
74

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.

# include <IRremote.h>

int EmpfaengerPin = 2;

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

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

void loop()
{
  // Daten lesen
  if (IrReceiver.decode())
  {
    /*
      printIRResultMinimal zeigt die verwendete Taste
      P = Protokoll
      C = Kommando in Hex
    */

    Serial.print(F("P = Protokoll C = Taste hexadezimal: "));
    IrReceiver.printIRResultMinimal(&Serial);
    Serial.print(F(" Dezimal: "));
    Serial.println(IrReceiver.decodedIRData.command);

    delay(200);

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

Die rot umrandeten Werte werden von der Keyes-Fernbedienung ausgegeben, die blau umrandeten stammen von einer TV-Fernbedienung. Weil die Fernbedienung kontinuierlich abgefragt wird, kommen zwischendurch auch Hex-Werten 0x0 und Dezimalwerte 0 vor.

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 == 0x46)
    {
      digitalWrite(LED, HIGH);
    }

    // unten
    else if (IrReceiver.decodedIRData.command == 0x15)
    {
      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;

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);
  }

  // Methode 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 0x16:
          while (Status) LauflichtHin();
          break;

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

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

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

Die Methode Schalten() setzt den Status auf false.

void Schalten() 
{
  Status = false; 
}

Beginne mit der Programmierung für die Lauflichter.

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

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

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 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 LauflichtMitBlinken()
{
  for (int i = 0; i < LEDMax; i++)
  {
    int Anzahl = random(1, 5);

    /* aktuelle LED i einschalten
      → Methode LEDBlinken aufrufen
    */
    LEDBlinken(LED[i], Anzahl);
  }
}
void loop()
{
  // Daten lesen
  if (IrReceiver.decode())
  {
    // auskommentieren, wenn die Tastencodes bekannt sind
    /*
      Serial.print(F("P = Protokoll C = Taste hexadezimal: "));
      IrReceiver.printIRResultMinimal(&Serial);
      Serial.print(F(" Dezimal: "));
      Serial.println(IrReceiver.decodedIRData.command);
    */
    switch (IrReceiver.decodedIRData.command)
    {
      // Taste 1: Lauflicht vor
      case 0x16:
        LauflichtHin();
        break;

      // Taste 2:  LEDs leuchten vor und zurück
      case 0x19:
        LauflichtHinUndHer();
        break;

      // Taste 3: LEDs blinken nacheinander
      case 0xD:
        LauflichtMitBlinken();
        break;
    }
    // nächsten Wert lesen
    IrReceiver.resume();
  }
}

Jetzt fehlt noch die Methode Schalten(), die für das Beenden der Lauflichter sorgen soll.
Ich habe verschiedene Infrarot-Empfänger getestet. Bei einigen kam es gelegentlich vor, dass durch eine Veränderung der Spannung der Interrupt ausgelöst wurde.

void Schalten()
{
  Status = false;
}

Startseite
Aufgaben A-Z
Suchen
Downloads
Fehlermeldungen
Seite als PDF

Verwandte Aufgaben:


Letzte Aktualisierung: 30. Apr 2022 @ 17:34