Ü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.
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.
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:
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).
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.
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:
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:
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:
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:
- 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.
- 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.
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.
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:
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:
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.
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:
Dann habe ich die Signale der Tasten 1, 2 und 3 dekodiert. Hier die Ausgabe des dump.ino Sketches für die Taste 1:
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:
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.
Hallo Herr Ewald, gestatten Sie mir eine Frage, wie viel ist maximale Entfernung zwischen Arduino bzw.IR und Fernbedienung, bei mir beträgt 1 Meter und er schaltet nicht sauber also ich meine drücke und ein oder drücke und aus, das mag bei mir nicht muss immer sehr oft 2 oder 3 mal drücke würden Sie mir bitte helfen das zu verstehen?
Ich bedanke mich sehr schon in voraus.
MFG A. Tommasi
Hallo Herr Tommasi,
sie haben eine fertige Fernbedienung (also keinen Selbstbau) und auf der anderen Seite den Arduino mit IR Empfängerdiode, richtig? Und haben sie die IRLib2 zum Decodieren der Signale genutzt? Hat das problemlos funktioniert? Auch da nur 1 m Reichweite?
Normalerweise kann man mehrere Meter Reichweite von einer Fernbedienung erwarten. Ist die Fernbedienung so ein günstiges Teil, wie ich es verwendet habe? Vielleicht ist die Batterie schwach. Haben sie vielleicht noch eine andere Fernbedienung, die sie mal testen können, z.B. vom Fernseher?
VG, Wolfgang Ewald
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.
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
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
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
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.
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.
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.
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.
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
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
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
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
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?
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
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
Danke vielmals, du hast mich gerettet, die IRLab2 ist viel leichter zu handeln, als die IRreceiver.
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
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.
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
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
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.
Interessanter Ansatz – cool!