Interrupt: Lauflicht mit Fernbedienung

Lesezeit: 7 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:
Sketch → Bibliothek einbinden → Bibliotheken verwalten

Suche die Bibliothek IRremote ...

… kli­cke auf Instal­lie­ren.

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 12.3.2021)

Umwandlung von Zahlensystem (externer Link, abgerufen am 12.3.2021)

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

  // 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);
  
  // 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: 26. Jul 2021 @ 19:24