IR Fernbedienungen

Über den Beitrag

In meinem letzten Beitrag hatte ich mich mit Infrarot (IR) Näherungssensoren beschäftigt. In diesem Beitrag möchte ich bei dem Thema Infrarot bleiben, jedoch geht es diesmal um IR Fernbedienungen. Zunächst gehe ich – recht detailliert – auf die Übertragungstechnik per IR ein. Dann werde ich erklären, wie man IR Fernbedienungen selber baut. Zum Schluss möchte ich zeigen, wie man mithilfe einer geeigneten Bibliothek eine IR Fernbedienung zur Fernsteuerung seiner Projekte einsetzen kann. Ihr könnt natürlich auch direkt zu dem letzten Kapitel übergehen, wenn euch die Hintergründe weniger interessieren oder ihr keine Zeit habt.

Sammlung alter IR Fernbedienungen
Ihr habt noch alte IR-Fernbedienungen? Nicht wegschmeißen! (Quelle: siehe Danksagung)

IR Datenübertragung

Wie die meisten sicherlich wissen, handelt es sich bei Infrarotstrahlung um nicht sichtbares Licht. Das Infrarotspektrum schließt sich dem sichtbaren Spektrum im längerwelligen Bereich an. Infrarotstrahlung wird auch als Wärmestrahlung bezeichnet. Mehr über Infrarotstrahlung im Allgemeinen findet ihr zum Beispiel hier auf Wikipedia.

Da jeder warme Körper je nach Temperatur mehr oder weniger infrarotes Licht abstrahlt, ist die IR Strahlung allgegenwärtig. Damit kann sie gezielte Signalübertragungen beeinträchtigen. IR Fernbedienungen nutzen einen Trick, indem sie gepulste Signale senden. Dadurch unterscheiden sich die Signale deutlich von der Umgebungsstrahlung, welche entsprechend herausgefiltert werden kann. Meistens verwenden IR Fernbedienungen eine Pulsfrequenz von 38 Kilohertz.

Infrarotempfänger

Infrarote Strahlung lässt sich mittels IR-sensitiver Fotodioden detektieren. Ich habe diese Art von IR Sensoren in meinem letzten Beitrag beschrieben. Ihr habt sie vielleicht schon mal als „Flame-Sensoren“ auf entsprechenden Modulen gesehen.

IR-Fotodiode: sieht aus wie eine schwarze LED
IR-Fotodiode: sieht aus wie eine schwarze LED

Mit solchen Fotodioden fängt man jedoch die gesamte IR Strahlung ein, egal ob gepulst oder ungepulst. Wenn ihr nur die gepulste Strahlung aus dem Infrarotlichtsalat herausfischen wollt, müsst ihr solche „Dreibeiner“ verwenden:

Infrarotempfänger für gepulstes Licht
Infrarotempfänger für gepulstes Licht

Ihr findet diese Empfänger unter der Bezeichnung VS1838B oder TSOPxx38 mit xx = z.B. 18, 22, 24, 48. Enden die Bezeichnungen nicht auf 38, wie z.B. beim TSOP2256, dann liegt die Pulsfrequenz nicht bei 38 kHz, sondern in diesem Beispiel bei 56 kHz. Eine Übersicht über die Nomenklatur von IR Empfängern findet ihr hier.

Auch ein Empfänger für gepulste Signale enthält zunächst einmal eine normale IR Fotodiode (siehe Schema unten). Die AGC Einheit (automatic gain control) verstärkt das Signal. Der Bandpassfilter reinigt es und schließlich wandelt der Demodulator es in ein kontinuierliches Signal um (kontinuierlich in Bezug auf die 38 kHz). Am Ende sitzt ein Transistor, der im Falle eines ankommenden Signals nach Ground durchschaltet. Damit geht Pin 1 des Empfängers von HIGH auf LOW. Hinweis: nicht alle IR Empfänger haben dieselbe Pinbelegung – schaut ins Datenblatt. Auch im Fritzing Schaltbild weiter unten habe ich eine andere Belegung (weil ich nur dieses Bauteil gefunden habe).

Schema eines Infrarotempfängers für gepulste Signale
Schema eines Infrarotempfängers für gepulste Signale

IR Fernbedienungen: Analyse der Signale

Ich möchte nun zeigen, wie ihr ein IR Signal analysieren könnt. Weiter unten verwende ich dazu eine komfortablere Bibliothek. Ich finde es aber ganz spannend, das auch einmal „zu Fuß“ zu machen.

Zunächst aber die Schaltung dazu. Beachtet dabei erst mal nur den Empfängerteil (an Pin 2), zum Sendeteil (an Pin 5) kommen wir später.

Arduino Schaltung zum Senden und Empfangen von IR Signalen
Arduino Schaltung zum Senden und Empfangen von IR Signalen

GND des Empfängers kommt an GND, VCC an 5 Volt und DATA an einen I/O Pin (hier 2). Den Empfänger kann man auch direkt an die 5V Versorgung des Arduinos hängen, denn er verbraucht weniger als 1 mA Strom.

Signalstruktur von IR Fernbedienungen

Signale von IR Fernbedienungen sind sozusagen zweifach gepulst. Ein Signal besteht aus einer Folge von Pulsen, wobei jeder Puls eine Breite von mehreren hundert Mikrosekunden bis einigen Millisekunden aufweist. Diese Pulse nenne ich mal Hauptpulse, da mir nichts Besseres einfiel. Das ist also kein Fachbegriff. Zwischen den Hauptpulsen gibt es unterschiedlich lange Pausen. Die Hauptpulse bestehen wiederum aus vielen 38 kHz Pulsen.

Hier ein typisches Beispiel eines IR Signals:

IR-Sendesignal am Oszilloskop
IR-Sendesignal am Oszilloskop

Die Hauptpulse sind gut zu erkennen. Ihr seht auch, dass das Signal im Grunde aus zwei identischen Hauptpulsfolgen besteht, die durch eine längere Pause getrennt sind. Das ist nicht ungewöhnlich bei IR Fernbedienungen.

Bei höherer Auflösung kommen dann die 38 kHz Pulse innerhalb Hauptpulse zum Vorschein. Hier ein Beispiel eines aufgezogenen Hauptpulses:

Ein höher aufgelöster Hauptpuls - ihr erkennt die 38 kHz Pulse
Ein höher aufgelöster Hauptpuls – ihr erkennt die 38 kHz Pulse

Auf der Empfängerseite werden die 38 kHz Pulse demoduliert. Außerdem wird das Signal aufgrund des oben beschriebenen Aufbaus der Empfänger umgekehrt. Das heißt, LOW wird HIGH und umgekehrt. Hier seht ihr wieder das Signal vom vorletzten Bild, aber am Empfänger:

Das demodulierte Signal auf der Empfängerseite - die 38 kHz Pulse sind verschwunden
Das demodulierte Signal auf der Empfängerseite – die 38 kHz Pulse sind verschwunden

Der Auswertesketch für Signale am Empfänger

Bei der Auswertung geht es nun darum die Puls- und „Pausenbreiten“ zu vermessen. Das macht man am besten, indem man zunächst eine geeignete Zeiteinheit (timeSegment) definiert, die die Auflösung darstellt. Im nachfolgenden Sketch prüft der Arduino nach jedem Ablauf einer Zeiteinheit, ob der Datenpin am IR Empfänger HIGH oder LOW ist. Die Zeiteinheiten werden addiert bis ein HIGH/LOW bzw. LOW/HIGH Wechsel stattfindet. So hangelt man sich Stück für Stück durch das Signal.

Der Zähler für die Pulsbreite (bzw. Pausenbreite) ist der pulseWidthCounter. Die Puls-Pausen Paare werden als Array gespeichert (irSignal). Die Paare werden durch den pulseCounter gezählt. Das Ende eines Signals ist erreicht, wenn über längere Zeit kein Puls mehr kommt (maxCount ist erreicht).

Bei diesem Verfahren sind zwei Dinge zu beachten:

  1. Die Überprüfung des Pinstatus mittels digitalRead ist mit ca. drei Mikrosekunden (jedenfalls auf dem UNO) recht langsam. Die direkte Abfrage des Eingangsregisters über (PIND & (1<<PD2)) ist wesentlich schneller.
  2. Ist timeSegment zu klein, muss der Pinstatus sehr häufig abgefragt werden. Die zum Auslesen benötigte Zeit summiert sich dann, selbst mit der schnellen Methode, zu einem signifikanten Fehler. Ist timeSegment zu groß, werden Anfang und Ende der Pulse entsprechend unscharf. Zwanzig Mikrosekunden haben sich Wert bewährt.

Ist ein Signal vollständig übertragen, dann wird es auf dem seriellen Monitor einmal übersichtlich paarweise und einmal als Array ausgegeben. Letzteres könnt ihr direkt in den Sendesketch, den wir gleich besprechen, hineinkopieren. Der letzte gemessene Wert entspricht maxCount. Diesen brauchen wir nicht, da er nicht mehr zum Signal gehört. Entsprechend lasse ich ihn in der Array-Ausgabe weg.

unsigned int pulseWidthCounter, pulseCounter;
unsigned int maxCount = 60000;
const int timeSegment = 20;
bool completed;
unsigned int irSignal[100][2];

void setup() {
  Serial.begin(9600);
  Serial.println("IR Decoder Sketch - ready");
}

void loop() {
  pulseCounter = 0;
  if(!(PIND & (1<<PD2))){
    completed = false;
    
    while(!completed){

      pulseWidthCounter = 0;
      while(!(PIND & (1<<PD2))){
        pulseWidthCounter++;
        delayMicroseconds(timeSegment);
      }
      irSignal[pulseCounter][0] = pulseWidthCounter;
      
      pulseWidthCounter = 0;
      while((PIND & (1<<PD2)) && (pulseWidthCounter < maxCount)){
        pulseWidthCounter++;
        delayMicroseconds(timeSegment);
      }
      irSignal[pulseCounter][1] = pulseWidthCounter;
      if(pulseWidthCounter >= maxCount){
        completed = true;
      }
      
      pulseCounter++;
      if(pulseWidthCounter >= maxCount){
        completed = true;
      }
    }

    Serial.println("IR Signal erhalten:");
    for(int i=0; i<pulseCounter; i++){
      Serial.print(irSignal[i][0]);
      Serial.print(" | ");
      Serial.println(irSignal[i][1]);
    }
    Serial.println();
    Serial.print("{");
    for(int i=0; i<(pulseCounter-1); i++){
      Serial.print(irSignal[i][0]);
      Serial.print(",");
      Serial.print(irSignal[i][1]);
      Serial.print(",");
      if(i==(pulseCounter-2)){
        Serial.print(irSignal[i+1][0]);
      }
    }  
    Serial.println("}");
  }
}

 

Die Ausgabe an einem konkreten Beispiel

Zum Testen habe ich die Fernbedienung meines Sat-Receivers, genaugenommen die „Programm +“ – Taste, ausgewählt. Diese habe ich übrigens auch für die Oszilloskop Messungen weiter oben benutzt. Um aus den Zahlen die Pulsbreiten in Mikrosekunden zu errechnen, müsst ihr sie natürlich noch mit zwanzig multiplizieren. Ich fand es aber übersichtlicher, mit den kleineren Zahlen zu arbeiten.

Ausgabe des IR Decoder Sketches
Ausgabe des IR Decoder Sketches

Eigene IR Fernbedienungen bauen

Und jetzt können wir das eben analysierte Signal nehmen und es mit einer IR LED senden. Wir bauen sozusagen eine eigene Fernbedienung bzw. simulieren die vorhandene Fernbedienung. Aber zunächst muss ich noch ein bisschen ausholen und erklären wie man ein 38 kHz Signal erzeugt.

Erzeugen eines 38 kHz Puls Signals

IR LEDs

Als Infrarotquelle benutzt Ihr am besten eine IR LED. Sie funktioniert im Prinzip wie eine LED für das sichtbare Licht. Auch IR LEDs gibt es in unterschiedlichen „Farben“, sprich in verschiedenen Wellenlängen. Gängig sind dabei 850 oder 940 nm. Nach meinen Recherchen scheint 940 nm besser zu den meisten Empfängern zu passen. Ansonsten unterscheiden sich die IR LEDs vor allem in ihrer maximalen Stromstärke. Die von mir verwendeten IR LEDs haben eine Stromstärke von 100 mA bei 1,2 bis 1,5 Volt. Bei der Festlegung von Vorwiderständen ist zu beachten, dass gepulst effektiv nur die halbe Stromstärke fließt. Zudem sind die IR Signale sehr kurz. Trotzdem sollte man erwägen, eine externe Stromquelle zu verwenden und diese wie in meiner Schaltung oben mit einem Transistor zuzuschalten. Als Vorwiderstand habe ich 15 Ohm verwendet.

IR LED
Eine IR LED

Pulssignale mit IR LEDs erzeugen

Um die IR LED nun mit 38 kHz pulsen zu lassen, kann man theoretisch die Funktion tone(pin, Frequenz) bzw. noTone() benutzen. Weitere Informationen zu dieser Funktion findet ihr hier. Für tone() muss man einen PWM-fähigen Pin wählen. Tatsächlich habe ich mit tone(5, 38000) schöne Pulse der richtigen Breite an Pin 5 erzeugen können:

38 kHz Puls für IR Fernbedienungen  mit der tone() Funktion
38 kHz Puls mit der tone() Funktion

Die tone() Funktion hatte ich schon in meinem letzten Beitrag über Selbstbau-Näherungssensoren erfolgreich verwenden können. Also wollte ich auch hier über tone – delay – noTone – delay mein Signal zusammenbasteln. Aus mir schleierhaften Gründen funktionierte das aber nicht. Hat jemand eine Idee dazu? Nehmen vielleicht die tone / noTone Befehle zu viel Zeit in Anspruch? Die Variante tone(pin, Frequenz, Länge), also ohne delay und noTone funktioniert übrigens auch nicht, da Länge in Millisekunden angegeben wird, was für diesen Zweck zu grob ist.

Wie auch immer, es gibt noch zwei Alternativen die funktionieren. Entweder ihr kreiert die Signale über die digitalWrite Funktion oder über die schnellere Variante des direkten Portzugriffs. Hier der Sketch dazu:

const int irLEDPin = 5;

void setup() {
  pinMode(irLEDPin, OUTPUT);
}

void loop() { 
  //PORTD |= (1<<PD5);                // much faster than digitalWrite
  digitalWrite(irLEDPin, HIGH);   // too slow: 3 microseconds (Arduino UNO / Atmega 328P)
  delayMicroseconds(13);            // does not work - switch to 10 or 9 µs
  //PORTD &= ~(1<<PD5);
  digitalWrite(irLEDPin, LOW);    // again 3 microseconds
  delayMicroseconds(13);            // does not work - switch to 10 or 9 µs
}

 

Entscheidet ihr euch für digitalWrite, dann müsst ihr die delays von 13 µs auf 10 Mikrosekunden verkürzen, da die digitalWrite Funktion ca. 3 µs benötigt (jedenfalls auf dem Arduino UNO). Sonst passiert das:

Signalerzeugung für IR Fernbedienungen mit digitalWrite und 13µs delay - die Pulsbreite wird zu groß
Signalerzeugung mit digitalWrite und 13µs delay – die Pulsbreite wird zu groß

Wählt ihr die Variante mit dem Direktzugriff, könnt ihr bei 13 µs bleiben. Den Messergebnissen zufolge müsstet Ihr sogar auf 14 µs gehen (siehe nächstes Bild). Interessanterweise scheint eine Mikrosekunde irgendwo verschluckt zu werden!? Kann mir das jemand erklären? Egal, ich habe es bei 13 Mikrosekunden belassen und es hat funktioniert. 

Signalerzeugung für IR Fewrnbesienungen über direkten Portzugriff und 13 µs delay - etwas zu kurz
Signalerzeugung über direkten Portzugriff und 13 µs delay – etwas zu kurz

Es gibt noch weitere Methoden schnelle PWM Signal zu erzeugen (über die internen Timer der AVR MCUs), das würde hier aber zu weit führen. 

Der Sendesketch

Der folgende Sketch simuliert die „Programm +“ Taste meiner Fernbedienung. Die Schaltung dazu entspricht immer noch dem Fritzing Schema von weiter oben. Alle zehn Sekunden wird das Programm hochgeschaltet. Ein automatischer Hochzapper sozusagen. Ziemlich schlicht, aber ich möchte damit auch nur das Prinzip verdeutlichen. Wenn ihr noch mehr Signale einarbeitet und diese dann Tastern zuordnet, könnt ihr auf diese Weise eine ganze Fernbedienung nachbauen.

Der Sketch sollte nicht schwer zu verstehen sein. Verwendet wird das zuvor dekodierte Signal. Die Länge des Arrays wird über seine Größe in Bytes ermittelt. Die pulseIR Funktion habe ich mir aus einem Adafruit Tutorial ausgeliehen und modifiziert.

Ich habe das ganze ausprobiert und es funktioniert.

const int timeSegment = 20;
const int irLEDPin = 5;
int irSignal[] = {48,42,47,43,92,87,92,43,47,42,47,87,92,43,47,43,47,42,47,43,46,4538,47,43,47,42,93,87,92,42,47,43,47,87,92,42,47,43,47,42,48,42,47};

int irSignalLength;
unsigned long phase;

void setup() {
  irSignalLength = sizeof(irSignal)/2; // One int = Two bytes
  pinMode(irLEDPin, OUTPUT);
}

void loop() {
  int i = 0;
  
  phase = 20*irSignal[i];
    pulseIR(phase);
    i++;
  do{
    phase = 20*irSignal[i];
    delayMicroseconds(phase);
    i++;
    phase = 20*irSignal[i];
    pulseIR(phase);
    i++;
  }while(i<irSignalLength);

  delay(10000);
}

void pulseIR(long microsecs) {
  cli();  // interrupts switched off
  
  while (microsecs > 0) {
  // 38 kHz is about 13 microseconds high and 13 microseconds low
  PORTD |= (1<<PD5);                // much faster than 
  //digitalWrite(irLEDPin, HIGH);   // too slow: 3 microseconds (Arduino UNO / Atmega 328P)
  delayMicroseconds(13);            // 10 microseconds, if you chose digitalWrite
  //digitalWrite(irLEDPin, LOW);    // again 3 microseconds
  PORTD &= ~(1<<PD5);
  delayMicroseconds(13);            // 10 microseconds, if you chose digitalWrite
  microsecs -= 26;
  }
  
  sei();  // interrupts switched on
}

 

IR Fernbedienungen mit der IRLib2 Bibliothek

Die meisten von euch werden IR Fernbedienungen einsetzen wollen, um Projekte fernzusteuern und nicht um vorhandene Geräte zu bedienen. Dafür ist die bisher erläuterte Vorgehensweise ein wenig komplex. Außerdem stellt sich noch die Frage, wie man ein Signal als mit einem Soll übereinstimmend definieren kann. Denn wenn ihr mehrere Male ein Signal aufzeichnet, dann seht ihr, dass die gemessene Länge der einzelnen Pulse etwas variiert.

Fleißige und schlaue Leute haben für die Erkennung und Codierung der Signale von IR Fernbedienungen Bibliotheken entwickelt. Diese basieren auf dem Umstand, dass man die Signale von IR Fernbedienungen bestimmten Protokollen zuordnen kann, wie zum Beispiel NEC, Sony, Panasonic usw. Diese haben bestimmte Muster und erlauben es, die Signalfolgen in einem kompakten Wert anstelle eines unhandlichen Arrays darzustellen. 

Es gibt eine Reihe guter Bibliotheken dazu. Der Klassiker schlechthin ist IRRemote von Ken Shirriff. Ich persönlich empfehle aber die Bibliothek IRLib2, da sie mit einer Vielzahl an Boards kompatibel ist. Bei der Installation ist zu beachten, dass die Bibliothek eigentlich eine Bibliothekensammlung ist. Wenn ihr die Zip-Datei herunterladet, dürft ihr sie deshalb nicht direkt im library Ordner entpacken. Stattdessen entpackt ihr die Zip-Datei irgendwo und kopiert dann die Hauptordner in das Arduino library Verzeichnis. Über die bequeme Arduino Bibliotheksverwaltung findet man die Bibliothek nicht.

Ein gutes Tutorial zu der Bibliothek findet ihr hier auf den Adafruit Learning Seiten. Ich möchte hier nur einen Kurzeinstieg geben.

IR Fernbedienungen: Signale dekodieren mit IRLib2

Nach der Installation der Bibliothek nehmt das Beispiel dump.ino ohne weitere Anpassung. Die Schaltung zu dem Sketch ist immer noch dieselbe wie zu Beginn dieses Beitrages.

/* dump.ino Example sketch for IRLib2
   Illustrates how to receive an IR signal, decode it and print
   information about it to the serial monitor.
*/
//This includes everything. Not generally recommended.
//It's better to include only the parts of library you really need.
//But for this example it's quick and easy. See "comboDump" example
//for a more efficient way.
#include "IRLibAll.h"

IRrecvPCI myReceiver(2); //create receiver and pass pin number
IRdecode myDecoder;   //create decoder

void setup() {
  Serial.begin(9600);
  delay(2000); while (!Serial); //delay for Leonardo
  myReceiver.enableIRIn(); // Start the receiver
  Serial.println(F("Ready to receive IR signals"));
}

void loop() {
  //Continue looping until you get a complete signal received
  if (myReceiver.getResults()) {
    myDecoder.decode();           //Decode it
    myDecoder.dumpResults(true);  //Now print results. Use false for less detail
    myReceiver.enableIRIn();      //Restart receiver
  }
}

 

Als Fernbedienung habe ich ein sehr handliches und günstiges Modell ausgewählt. Solche Fernbedienungen gibt es in großer Auswahl bei Amazon oder eBay:

IR Fernbedienung

Dann habe ich die Signale der Tasten 1, 2 und 3 dekodiert. Hier die Ausgabe des dump.ino Sketches für die Taste 1:

IR Fernbedienungen dekodieren mit IRLib2
IR Fernbedienungen dekodieren mit IRLib2

Entscheidend ist der „Value“ (rot markiert), in diesem Fall FD08F7. Das ist schon etwas umgänglicher als die langen Zahlenreihen zuvor, nicht wahr?

Ein einfaches Anwendungsbeispiel

Mit den entsprechenden Codes kann man dann alles Steuerbare fernsteuern, sei es Lampen, Autos, Musik oder was auch immer. Hier ein ganz kleines Beispiel bei dem mit meiner Fernbedienung jeweils eine von drei LEDs angeschaltet wird, ein LED-Zapper sozusagen.

#include "IRLibAll.h"

IRrecvPCI myReceiver(2); 
IRdecode myDecoder;   
const int led1 = 10;
const int led2 = 11;
const int led3 = 12;

void setup() {
  pinMode(led1,OUTPUT);
  pinMode(led2,OUTPUT);
  pinMode(led3,OUTPUT);
  myReceiver.enableIRIn(); // Start the receiver
}

void loop() {
  if (myReceiver.getResults()) {
    myDecoder.decode();           //Decode it
    switch(myDecoder.value){
      case 0xFD08F7:
        switchOnLed(led1);    
        break;
      case 0xFD8877:
         switchOnLed(led2);  
        break;
      case 0xFD48B7:
         switchOnLed(led3);     
        break;
    }           
  }
  myReceiver.enableIRIn();      //Restart receiver
}

void switchOnLed(int pin){
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(pin, HIGH);
}

 

Und hier die Schaltung dazu:

Ferngesteuerter LED Zapper
Ferngesteuerter LED Zapper

Eine weitere Anregung

Vor einiger Zeit habe ich einen Beitrag mit dem Titel „Eigene Funkprotokolle“ geschrieben. Darin ging es um die Kommunikation mit 433 MHz Modulen mittels eigens entwickelter Protokolle. Die dort vorgestellten Methodiken lassen sich auf die Infrarottechnik übertragen. So könnt ihr dann z.B. auch Text senden, Messergebnisse oder Ähnliches. Schaut mal rein, wenn ihr Interesse habt.

Danksagungen

Die Fernbedienung im Beitragsbild stammt von hojun Kang auf Pixabay. Der Arduino im Hintergrund des Beitragsbildes stammt von Seven_au, ebenfalls Pixabay. Allerdings habe ich das Bild noch weichgezeichnet. Die Fernbedienungssammlung habe ich Mirko Maibach auf Pixabay zu verdanken.

Chris Young (cyborg5) danke ich für seine Bibliothek und das Tutorial.

 

23 thoughts on “IR Fernbedienungen

  1. Hallo Wolfgang,
    ich habe mir heute mal eine Empfangsschaltung gebaut und folgenden Code gefunden:
    #include
    #include

    const int RECV_PIN = 2;
    IRrecv irrecv(RECV_PIN);
    decode_results results;

    void setup(){
    Serial.begin(9600);
    irrecv.enableIRIn();
    irrecv.blink13(true);
    }

    void loop(){
    if (irrecv.decode(&results)){
    Serial.println(results.value, HEX);
    irrecv.resume();
    }
    }

    Für meinen Sony Lautsprecher bekomme ich beispielsweise fürs Einschalten den Wert 5499 .
    Für Audio In den Wert 1B99 .
    Wie kann ich diese Werte senden ?
    Der Befehl
    IRsend irsend; // Pin 3
    irsend.sendSony(0x5499, 15);
    für Port 3 scheint nicht zu funktionieren (soll angeblich Port 3 sein, die anderen Ausgänge bei meinem Nano liefern auch kein Signal).
    Eine Unschönheit bei meinem Arduino Receiver ist (das gleiche Problem habe ich auch mit deinem Code),
    dass der Arduino auch wenn ich keine Taste auf der IR-Fernbedienung drücke alle paar Sekunden einen
    Code auf dem Seriellen Monitor ausgibt. Bei diesem Code ist es nur eine Zeile, bei deinem ein halber Bildschirm voller Code.
    Jetzt müsste ich nur noch den Code 5499 senden können, den mir der Receiver liefert.

    1. Hallo Michael,
      wie du siehst, sind die Kommentarfelder nicht gut für Code geeignet, weil der Text als HTML interpretiert wird. Dadurch gehen Einrückungen verloren und alles in eckigen Klammern wird für HTML-Anweisungen gehalten.

      Welche Bibliothek verwendest du? Dann kann ich da mal nachschauen. Du könntest auch mal probieren die IRLib2 zu nehmen, die ich auch verwendet habe. Dort kannst du den Beispielsketch dump.ino oder comboDump.ino zum Dekodieren nehmen. Und mit dem Beispielsketch send.ino kannst du die gefundenen Codes dann versenden. Das ist eigentlich selbsterklärend. Wenn es nicht geht, dann würde ich auch mal ein, zwei andere Fernbedienungen ausprobieren und schauen, ob es damit funktioniert. Dann wüsstest du, ob du ein generelles Problem hast oder ob die Fernbedienung tatsächlich so speziell ist, dass man die Signale nicht richtig nachstellen kann. Viel Erfolg – lass dich nicht entmutigen.
      VG, Wolfgang

  2. Ich habe einen Sony SRS-X88 Lautprecher an meinem Computer.
    Mithilfe eines Arduinos würde ich diesen gerne einschalten und auf Audio In umschalten, damit ich es nicht jedes mal manuell mit der Fernbedienung tun muss.

    Ich habe mir zum Auslesen einen IR Remote Control Decoder T.I.T aus Tschechien gekauft.
    Dieser zeigt mir für die Einschalt-Taste die Werte
    System 99, Format 6124C8, Data 15
    und für die Audio In Taste
    System 99, Format 6124C8, Data 6C
    Kann ich mit diesen Daten was anfangen und mithilfe eines Arduinos diese Daten senden ?
    Viele Grüße,
    Michael

    1. Hi, ob es möglich ist allein mit diesen Daten das Signal der Fernbedienung zu simulieren, kann ich nicht beantworten. Da sechsstellige Format sieht eigentlich viel versprechend aus, aber ich weiß nicht, was Data bedeutet. Ich würde versuchen, das Signal über die IRLib2 zu analysieren, so wie im Beitrag beschrieben. Da bekommst du dann einen Wert („Value“) und idealerweise musst den dann einfach nur senden. Die IRLib2 hat dafür auch ei en Beispielsketch. Wenn das nicht geht, dann kann man probieren, das Signal „manuell“ zu analysieren und dann nachzustellen, so wie ich das im Beitrag gemacht habe. Prinzipiell kann man jedes IR-Signal nachbauen. VG, Wolfgang

      1. Hallo Wolfgang,
        vielen Dank für deine Rückmeldung.
        Data steht wohl für Daten, da es der einzige Wert ist, der sich je nach Taste ändert.
        Volume Plus –> System 99, Format 6124C8, Data 12
        Volume Minus –> System 99, Format 6124C8, Data 13
        USB-A –> System 99, Format 6124C8, Data 00
        USB-B –> System 99, Format 6124C8, Data 04
        Vermutlich ist Data eine zweistellige Hexadezimalzahl (das Messgerät kann dort bis zu 4 Stellen anzeigen) bei mir ist es jedoch nur z.B. für USB-A Data 00– d.h. 2 Stellen.

        1. Wenn sich der sechsstellige Code ändern würde, würde ich sagen, dass ist der Code für die Taste. Da er das nicht tut, kann er es nicht sein. Und Data ist ein bisschen kurz. Wie gesagt, ich würde einfach mal versuchen, das Signal mit dem dump.ino Sketch zu analysieren. Das ist schnell gemacht.

          1. Hallo Wolfgang,
            ich habe ein interessantes pdf gefunden(ist noch nicht ganz, was ich suche)
            chrome-extension://efaidnbmnnnibpcajpcglclefindmkaj/https://www.vishay.com/docs/80071/dataform.pdf

            Die Theorie scheint ein wenig komplexer zu sein, es werden beispielsweise „Leader code“, Data word, Address Code, invertierter Adress Code, Data Code und invertierter Data Code übertragen, letztere in einer Schleife, solange die Taste gedrückt gehalten wird, z.B. alle 108ms …
            In meinem Fall muss ja auch nicht nur für Volume Plus die Data 12 übertragen werden, sondern auch das System 99 und das gewählte Sony Format 6124C8 .
            Eine Hexadezimalzahl (16-ner System, 0..9,A,B,C,D,E,F) benötigt 4 Bit, d.h. Data 12 wären zwei Hexadezimalzahlen, also 8 Bit. Die 99 könnte der Adresscode sein (?), also auch 8 Bit.

            1. Vielleicht ist es bei deiner Fernbedienung komplizierter als bei anderen Fernbedienungen, aber ich würde trotzdem erst einmal versuchen, die Signale mithilfe der Bibliothek versuchen auszulesen. Das ist in 5, vielleicht 10 min erledigt. Und wenn es nicht geht, kann man immer noch weiter recherchieren oder die Signale notfalls „zu Fuß“ auslesen, so wie am Anfang des Beitrages beschrieben.

  3. Schon wieder war der Wolfgang schon hier….. Herzlichen Dank für diesen Artikel. Besonders die Signalanalyse hat sehr viel zu meinem Verständnis beigetragen. Noch immer arbeite ich am Steppermotor–Projekt in dem ich bereits durch Deinen Timer Artikel sehr viel erreichen konnte. Nun hatte ich die Idee, das ganze per Fernbedienung zu steuern. Der Tip mit der IRLib2 ist wirklich ein guter. Leider funktioniert „IRrecvPCI myReceiver(); “ beim Uno nicht auf anderen Pins außer PIN 2 und 3. Ich vermute daher, dass Hardware Interrupts Verwendung finden. Etwas ärgerlich ist, dass ich die Hardware Interrupts für Hall Sensoren eingeplant hatte die nun scheinbar doch auf PCINT umgebastelt werden müssen. Oder übersehe ich hier eine Möglichkeit der IRLib2 doch noch höhere PINs für den Empfang zu nutzen?
    Viele Grüße

    1. Hallo Leif, ich kann dir die Frage nicht beantworten. Die Library ist etwas verzweigt, deswegen konnte ich zumindest auf die Schnelle nicht sehen wie der Interruptpin implementiert wird. Du könntest die Frage auf Github direkt an den Autor der Bibliothek richten. Ich habe leider nicht die Zeit mich da tiefer hineinzuarbeiten.
      VG, Wolfgang

  4. Hallo Wolfgang,
    ist es möglich, mehrere dieser IR Fernbedienungen innerhalb einen Raumes zu verwenden, ohne dass diese sich gegenseitig stören ?

    Codieren lassen sich diese ja scheinbar nicht.

    Hast du da Erfahrungen ?

    Danke und Gruß,
    Frank

    1. Hi Frank, ich gehe davon, dass gleiche IR Fernbedienungen auch immer identische Signale geben und sich so gegenseitig stören. Ich gehe aber auch davon dass unterschiedliche Modelle unterschiedliche Signale geben. Eine Übereinstimmung wäre schon ein sehr großer Zufall. VG, Wolfgang

  5. Hallo Wolle,
    vielleicht kannst du noch mal helfen? Im „Led-Zapper“ möchte ich mit einer Taste, z.B. 0, sicherstellen, dass alle Leds aus sind. Muss ich dazu eine eigene Funktion (switchOfLed) schreiben?

    1. Hallo Hans-Georg, du meinst den Sketch „remote_simple_example“, richtig? Ja, entweder du schreibst eine eigene Funktion, oder du definierst eine nicht vorhandene LED, z.B.
      const int led999 = 999;
      Dann ordnest du die der Taste 0 zu und änderst switchOnLED in

      void switchOnLed(int pin){
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      if(pin!=999){
      digitalWrite(pin, HIGH);
      }
      }

      Pragmatischer Ansatz. VG, Wolfgang

      1. Hallo Wolle,
        ich liebe pragmatisch. An das „negative“ Abfragen muss ich mich gewöhnen, ist aber eine einfache Sache um bei mehreren Zuständen alle sozusagen einzuschließen. Vielen Dank
        Schorsch

  6. Moin Wolle,
    alles gut. Habe mich belesen und habe mich für die Hex-Variante entschieden. Dank des Sketches zum Auslesen habe ich jetzt für alle FB die Codes und gut ist. Danke , du Guter. Ich habe noch nicht genau verstanden, wo/wie ich den Signal-Pin für IR-Modul zuweise. Soll das diese Zeile sein
    IRrecvPCI myReceiver(2); ? Für PIN 11 also
    IRrecvPCI myReceiver(11);
    Danke

    1. Genauso ist es. Die übergebene Zahl ist die Pinnummer für das IR Signal, sprich dieser Pin kommt an den Datenpin des IR Empfängers.

  7. Hallo Wolfgang,
    deine Projekte und Erklärungen sind der Hammer, das verstehe sogar ich als Arduino-Dau. Ich kämpfe seit einer Woche mir der IR-Geschichte, ich nutze ein KY-44 Modul von Fundoino und die gleiche FB, wie du. Leider geht bei mir nur etwas spontan. Dein Sketch zum Dekodieren hat mir andere Codes geliefert. Und dass nur spontan. Aber es geht. Meine Frage: Kann ich mir die Codes auch dezimal anzeigen lassen und wie baue ich die dann im „Led-Stripper“ ein. Danke

    1. Hallo Hans-Georg,
      also verallgemeinert ausgedrückt willst du ein IR Signal dekodieren und es dann per Arduino/IR-LED versenden, richtig? Möglichkeit 1: der unbequeme Weg, ohne Bibliothek wie ich ihn im Beitrag beschrieben habe. Möglichkeit 2: mit Bibliothek, dann bekommst du Codes wie zum Beispiel im Beitrag: NEC(1), FD08F7.
      Ich vermute, du willst einen solchen Code in dezimal übersetzen, um ihn dann irgendwie senden zu können. Diese Codes sind nicht aber nicht ganz so einfach mit einer einfachen Formel in sendefähigen Code übersetzbar. Aber das brauchst du ja auch gar nicht. Gehe in die Beispielsketche der IRLib2 und wähle den Sketch „send“. Da setzt du einfach den Code ein, z.B. so
      mySender.send(SONY,0xa8bca, 20); //Sony DVD power A8BCA, 20 bits

      oder so:
      mySender.send(NEC,0x61a0f00f,0); //NEC TV power button=0x61a0f00f

      Oder hab ich dein Anliegen falsch verstanden?

      VG, Wolfgang

  8. Das ist genau das, woran ich gerade arbeite.

    Mein Ansatz ist es aber, dass ich NICHT den 38kHz-Ton an und ausschalte. (Das hat bei dir ja auch nicht funktioniert so ohne Probleme)

    Ich schalte den Ton auf einem Pin ein und lasse ihn an (solange ich sende) Ein zweiter PIN wird über einen Timer ein und ausgeschaltet im Rythmus des Codes. Zwischen den beiden Pins kann man dann mit einem Optokopler das Signal abgreifen, was am Ausgang des Optokoplers dann bereit steht die IR-LED zu treiben.

    Wichtig ist es einen Optokopler zu nutzen, der nur in eine Richtung Strom am Eingang annimmt oder noch eine Diode in Reihe zu schalten. Dann mischt man auf diese Weise die beiden Signale und bekommt genau das heraus was man braucht.

    Wenn man die „Hauptpulse“ – wie du sie genannt hast – mit einem Timer macht, sind aber zwei Timer nötig.

Schreibe einen Kommentar

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