Hallo liebe Leserinnen und Leser!
Nachdem es in letzter Zeit etwas ruhig geworden ist hier im Blog, gibt es heute wieder ein Tutorial für euch! Dieses mal geht es um das Schalten von Infrarot-Geräten über einen Arduino (bzw. daran angeschlossenen Raspberry Pi / Banana Pi /PC etc.). Die Wahl viel hierbei auf einen Arduino, da sich damit der steuernde Server frei wählen lässt – die Ansteuerungslogik der IR-Diode läuft also auf dem Arduino.
IR-Geräte sind sehr weit verbreitet (Fernseher, Receiver, Stereoanlagen usw.), daher spielen sie meiner Meinung nach auf Grund ihrer Vielzahl eine wichtige Rolle im „smart home“. Zudem lassen sie sich durch die Einbindung im Heimnetz auch bequemer bedienen, z.B. über Sprachsteuerung, eine Smartphone-App oder über die Smartwatch.
1. Benötigte Komponenten
- Arduino (Modell relativ egal, für meinen Prototypen nutze ich einen Leonardo, dieser wird noch durch einen Pro Micro ersetzt)
- IR-Receiver
- IR-Diode
- geeigneter Widerstand
- USB-Kabel
- Jumper-Kabel
- Raspberry Pi / Banana Pi / PC als Steuerungsserver
2. Arduino als IR-Empfänger und Decoder
Im ersten Schritt müssen eure Fernbedienungen für die gewünschten zu steuernden Geräte erst einmal eingelesen werden, um zu sehen, welches Signal diese von sich geben, wenn eine Taste gedrückt wurde. Dazu benötigt ihr den Arduino sowie den IR-Receiver. Um die Codes am PC darstellen zu können, muss der Arduino noch mit einem USB-Kabel mit einem Rechner mit installierter Arduino-IDE verbunden werden.
Hier ist eine Grafik, die den Anschluss des Receivers an den Arduino (hier: Receiver VS1838B an Arduino Leonardo) darstellt:
Widerstände werden bei diesem Empfänger nicht benötigt, sodass der Aufbau sehr simpel ist.
Um die Fernbedienungen decodieren zu können, benötigen wir noch eine Bibliothek für den Arduino, die uns diese Arbeit abnimmt. Dazu laden wir uns „Arduino-IRremote“ von shirriff herunter. Dies ist über GitHub möglich. Folgt dazu diesem Link und klickt unten bei „Latest release“ auf „IRremote.zip“. Für die Installation der Library in der Arduino IDE folgt einfach der offiziellen Arduino-Anleitung hierzu.
Ladet nun das mitgelieferte Beispiel IRrecvDump in der Arduino IDE:
Schließt den Arduino mit Transmitter jetzt an euren PC an und übertragt den Sketch auf den Arduino. Öffnet nun den seriellen Monitor in der Arduino IDE:
Wenn ihr auf einer Fernbedienung einen Knopf drückt, sollte der Arduino den übertragenen Code auslesen und euch über die serielle Schnittstelle Ausgeben. Führt das für alle gewünschten Fernbedienungen und Knöpfe aus. Notiert dabei z.B. in einem einfachen Textdokument, welcher Code von welcher Fernbedienungstaste gesendet wurde. Dieser Arbeitsschritt nimmt einige Zeit in Anspruch, gerade wenn ihr viele Fernbedienungen habt. Einmal ausgelesen könnt ihr die Codes dann aber ab sofort mit eurem Arduino nutzen.
Hier eine Simulation des Ganzen (startet die Simulation, öffnet unter dem Code-Editor den seriellen Monitor und klickt mit der Maus auf beliebige Tasten der Fernbedienung).
3. IR-Signale mit dem Arduino senden
Um IR-Signale von eurem Arduino aus senden zu können benötigt ihr die IR-Diode. Diese kann wie folgt angeschlossen werden:
Achtet darauf, einen geeigneten Widerstand einzusetzen – dimensioniert diesen lieber anfangs etwas größer, wenn ihr euch nicht sicher seid, welcher passend ist. Die HIGH-Spannung unterscheidet sich je nach Arduino Board – entweder 3,3V oder 5V. Auch bei den Dioden gibt es Unterschiede in der Durchlassspannung. Zur Berechnung kann ich auch diese Seite empfehlen.
Nun können wir den Arduino-Sketch programmieren. Dieser wird später über die serielle Schnittstelle Befehle entgegennehmen und über den IR-Transmitter an die entsprechenden Geräte schicken. Das Grundgerüst des Sketches kann so aussehen (Namen der Geräte anpassen):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include <IRremote.h> IRsend irsend; void setup() { Serial.begin(9600); } void loop() { String content = ""; char character; // Read serial command to string while(Serial.available()) { character = Serial.read(); content.concat(character); } // Apple remote if (content.startsWith("apple")){ } // Trekstor remote else if (content.startsWith("trekstor")){ } // Sony remote else if (content.startsWith("sony")){ } } |
Nun können wir in die entsprechenden Bereiche die Codes unserer Fernbedienungen, die wir im vorherigen Schritt ausgelesen haben, eintragen. Der erweiterte und damit fertige Sketch kann so aussehen (aus Platz- und Übersichtlichkeitsgründen wurden hier nur die Codes für die Apple-Fernbedienung eingetragen):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #include <IRremote.h> IRsend irsend; void setup() { Serial.begin(9600); } void loop() { String content = ""; char character; // Read serial command to string while(Serial.available()) { character = Serial.read(); content.concat(character); } // Apple remote if (content.startsWith("apple")){ if (content.substring(6) == "up") { Serial.println(content); irsend.sendNEC(0x77E15057, 32); } else if (content.substring(6) == "down") { Serial.println(content); irsend.sendNEC(0x77E13057, 32); } else if (content.substring(6) == "left") { Serial.println(content); irsend.sendNEC(0x77E19057, 32); } else if (content.substring(6) == "right") { Serial.println(content); irsend.sendNEC(0x77E16057, 32); } else if (content.substring(6) == "center") { Serial.println(content); irsend.sendNEC(0x77E13A57, 32); } else if (content.substring(6) == "menu") { Serial.println(content); irsend.sendNEC(0x77E1C057, 32); } else if (content.substring(6) == "play") { Serial.println(content); irsend.sendNEC(0x77E1FA57, 32); } else { Serial.println("unknown"); } } // Trekstor remote else if (content.startsWith("trekstor")){ } // Sony remote else if (content.startsWith("sony")){ } } |
Nachdem der Sketch auf den Arduino übertragen wurde, können wir unsere Geräte nun schon testweise über die serielle Konsole der Arduino-IDE schalten. Öffnet dazu wieder den „seriellen Monitor“ und gebt einen gewünschten Befehl ein, aus meinem Beispiel z.B. „apple_play“ um die Musik-/Video-Wiedergabe auf dem Macbook zu starten bzw. zu pausieren. Klappt das Schalten über diese Befehle bereits, so ist die Arbeit auf dem Arduino bereits abgeschlossen.
4. Anschluss an Server (Raspberry Pi, Banana Pi, PC,…)
Als nächstes wollen wir den Arduino an einen Raspberry / Banana Pi oder PC anschließen, um die Fernbedienungsfunktion auch über eine Web-Schnittstelle zu realisieren.
Anmerkung: Da das Gerät, an dem der Arduino angeschlossen wird, die Zeit über laufen muss, wenn z.B. über das Smartphone geschalten werden soll, empfiehlt sich die Nutzung eines sparsamen Servers. Daher fiel meine Wahl auf einen Banana Pi, da dieser sowieso 24/7 im entsprechenden Raum läuft. Natürlich geht auch jeglicher andere PC, auf dem Linux und Python läuft. Im Nachfolgenden werde ich der Einfachheit halber nur Banana und Raspberry Pi erwähnen, andere Server funktionieren natürlich ebenso.
Damit kann man die Tastenbefehle nach fertiger Konfiguration auch über eine Smartphone- / Tablet-App oder Sprachsteuerung absenden.
Zunächst müssen wir nach Anschluss des Arduino an den Raspberry / Banana Pi herausfinden, unter welcher seriellen Schnittstelle dieser erkannt wurde. Dazu im Terminal „dmesg“ vor- und nach dem Einstecken des Arduinos ausführen und schauen, welche Schnittstelle nach dem Einstecken hinzugekommen ist. Dieses ist dann der gesuchte serielle Port.
Analog zur Steckdosensteuerung über raspberry-remote habe ich beschlossen, mir einen kleinen Socket-Server in Python zu schreiben, der Befehle entgegennimmt und an die serielle Schnittstelle weitergibt. Hier ist der Quellcode:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | import socket import serial import sys from thread import * HOST = '' # Symbolic name meaning all available interfaces PORT = 3333 # Arbitrary non-privileged port s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print 'Socket created' #Bind socket to local host and port try: s.bind((HOST, PORT)) except socket.error , msg: print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1] sys.exit() print 'Socket bind complete' #Start listening on socket s.listen(10) print 'Socket now listening' #Function for handling connections. This will be used to create threads def clientthread(conn): #infinite loop so that function do not terminate and thread do not end. while True: #Receiving from client data = conn.recv(1024) lenght_data = len(data) if lenght_data >0: if (data[:5] == "apple") or (data[:4] == "sony") or (data[:8] == "trekstor"): arduino_serial(data) else: print "not implemented protocol" else: print data if not data: break #came out of loop conn.close() #Function for talking to Arduino via serial connection def arduino_serial(data): #serial stuff TODO ser = serial.Serial('/dev/ttyACM0', 9600) ser.write(data) #now keep talking with the client while 1: #wait to accept a connection - blocking call conn, addr = s.accept() print 'Connected with ' + addr[0] + ':' + str(addr[1]) #start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function. start_new_thread(clientthread ,(conn,)) s.close() |
Speichert das Script z.B. unter dem Namen „socket_ir.py“ auf eurem Raspberry / Banana Pi an und passt hier den seriellen Port an euren an und auch die Namen der Geräte. Falls ihr bereits einen anderen Dienst unter der genutzten Port-Nummer auf eurem Gerät laufen habt, müsst ihr auch hier noch eine andere Nummer wählen. Nun könnt ihr den Socket-Server als Daemon starten via „sudo python socket_ir.py&“. Den Socket-Server nutzen wir nun, um auf ihn über ein PHP-Script zuzugreifen, das Befehle von Smartphones und anderen Geräten über die HTTP-Schnittstelle entgegennimmt.
Anmerkung: Nachfolgend wird davon ausgegangen, dass ihr auf eurem Webserver einen Apache-Server o.ä. mit PHP laufen habt. Sollte dieser noch nicht installiert sein, müsst ihr diesen noch installieren, bevor ihr weitermachen könnt. Hierzu finden sich unzählige Anleitungen für verschiedenste Betriebssysteme und Webserver im Netz, sodass ich darauf verweise.
Das entsprechende PHP-Script ist relativ kurz und sollte selbsterklärend sein:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php $source = $_SERVER['SERVER_ADDR']; $target = $_SERVER['SERVER_ADDR']; $port = 3333; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket\n"); socket_bind($socket, $source) or die("Could not bind to socket\n"); socket_connect($socket, $target, $port) or die("Could not connect to socket\n"); if (isset($_GET['command'])) $nCommand=$_GET['command']; else $nCommand=""; socket_write($socket, $nCommand, strlen ($output)) or die("Could not write output\n"); ?> |
Speichert es als irsend.php unter „/var/www/“ [bei Apache; bei Verwendung eines anderen Webservers evtl. abweichend]. Das Script nimmt über GET ein Argument namens „command“ entgegen, welches den Wert eines Sendebefehls bekommen soll, um euer Gerät zu schalten. Um bei meinem Beispiel mit dem Macbook zu bleiben, könnte ich auf diesem nun die Wiedergabe starten, in dem ich z.B. im Smartphonebrowser die folgende URL öffne:
1 | [IP-Server]/irsend.php?command=apple_play |
Klappt das schalten über dem manuellen Aufruf der entsprechenden URL können wir nun weitermachen, die Smartphone-App und Sprachsteuerung einzurichten.
5. Steuern über Smartphone- / Tablet-App und Sprachsteuerung
5.1 Einrichtung von netio
Als App habe ich „netio“ im Einsatz, eine kleine, schnelle App, mit der ihr einfach eigene virtuelle Fernbedienungen erstellen könnt. Diese ist kostenpflichtig und wird zu oft ändernden Preisen angeboten. Ich habe um die 4€ gezahlt und meiner Meinung nach ist die App jeden Cent wert.
Ladet euch also die App im entsprechenden Store herunter (erhältlich für iOS und Android). Anschließend müsst ihr auch noch einen Account für netio auf deren Homepage erstellen. Damit könnt ihr nun den bequemen Online-Editor nutzen, um neue Fernbedienungen anzulegen.
Im Online-Editor müsst ihr nun zuerst eine neue Konfiguration anlegen. Name und Beschreibung könnt ihr frei wählen, beim Gerät solltet ihr euer Smartphone- oder Tablet-Modell auswählen, um die richtige Größe der Fernbedienung im Editor angezeigt zu bekommen. Fügt zudem noch eine neue Verbindung beliebigen Namens ein und tragt dort die IP-Adresse eures Servers ein, an dem der Arduino angeschlossen ist. Als Protokoll wählt ihr „http“ mit Port 80 (Standard bei Apache).
Anschließend könnt ihr in dieser Konfiguration eine neue Seite anlegen mit beliebigem Namen und Label. Als Verbindung tragt ihr den Namen der eben angelegten Verbindung ein.
Nun könnt ihr über „Add Item“ verschiedene Knöpfe auf eurer virtuellen Fernbedienung anlegen. Designt also erst einmal eure Fernbedienung und fügt dann bei jeder Taste über „Add Attribute“ ein „sends“ hinzu, indem ihr die URL eures Sendebefehls ab der IP eintragt, also z.B. „/irsend.php?command=apple_play“.
Ihr könnt übrigends auch mehrere sends-Attribute hinzufügen, die bei Knopfdruck nacheinander abgearbeitet werden. Das ist z.B. zur Wahl eines bestimmten TV-Senders praktisch, den ihr so als Shortcut auf der Fernbedienung habt. Gebt dabei die komplette Reihenfolge der Tastendrücke in der Konfiguration an. Bei manchen Geräten muss zudem zwischen den Befehlen eine kurze Pause eingefügt werden, das ist ebenfalls möglich bei netio:
Speichert nun die Konfiguration online ab und öffnet die App auf eurem Smartphone oder Tablet. Dort meldet ihr euch in der Seitenleiste erst einmal in eurem netio-Account an und tippt auf „SYNC“:
Eure eben erstellte Fernbedienung (bzw. Fernbedienungen) sollte nun erscheinen und funktionieren.
5.2 Einrichtung von AIVC
Als Sprachsteuerung unter Android nutze ich wie bei den Funksteckdosen auch schon die App „AIVC“, die es in einer kostenlosen und kostenpflichtigen Variante im Google Play Store gibt. Wenn nicht schon vorhanden, ladet euch die App herunter und installiert sie auf eurem Smartphone/Tablet. Eine detaillierte Konfigurationsanleitung zu der App habe ich bereits im Artikel „Funksteckdosen mit Android-Sprachsteuerung (AIVC) und Widget schalten“ gegeben, sodass ich an dieser Stelle hierauf verweise und nur eine kurze Bilderstrecke zur Konfiguration der IR-Geräte erstellt habe, an der ihr euch orientieren könnt:
Und damit sind wir auch schon am Ende dieses Tutorials angelangt. Ich hoffe euch gefällt die Anleitung und ihr habt sie problemlos umsetzen können (sofern gewollt).
Bei Fragen, Problemen und Anregungen könnt ihr natürlich wie immer das Kommentarfeld unten benutzen.
Hallo Alex! Ich habe das Tutorial zwar noch nicht nachgebaut, finde deine Anleitungen aber immer spitze! Sehr detailliert und gut verständlich – Hut ab! Mach bitte weiter so!
Danke! Das hört man gerne.
Hi!
Eine andere Idee: Warum nicht einfach LIRC benutzen am Raspberry Pi? Damit sollte es genau so umsetzbar sein und einen Arduino braucht man dann auch nicht ;-)
Hey Steve,
du hast recht – mit LIRC sollte es auch ohne Arduino gehen. Wie beschrieben ist der Arduino-Weg aber der flexiblere, da mann damit nicht auf einen Server mit Infrarot-Empfänger und -Sender angewiesen ist. Auch hat der IR-Empfänger vom Banana Pi unter LIRC bei mir nur eine meiner Fernbedienungen überhaupt erkannt – daher habe ich mich für die Lösung mit Arduino entschieden.
Hallo,
schöne Idee! Das Python socket Script sollte allerdings mit root Rechten gestartet werden müssen, wenn auf den seriellen Port zugegriffen werden muss.
Hi Marcus,
ja – da hast du recht! Wird ausgebessert.
Danke!
Hallo,
gibt es auch die Möglichkeit mehrere ir-LEDs an den Aeduino anzuschließen?
Hallo Heinz,
ich habe es selbst noch nicht getestet, aber es gibt eine abgeänderte Library, die das unterstützen sollte: https://github.com/khair-eddine/Arduino-IRremote
(siehe auch https://github.com/shirriff/Arduino-IRremote/issues/128)
Hallo! Hat das schon jemand mit mehreren Sendern hinbekommen? Wollte nur mal nachfragen, bevor ich die Teile bestelle ;-)
Hi Bücherwurm,
ich bin zumindest noch nicht dazu gekommen, werde das aber demnächst nachholen und hier berichten.
Hallo zusammen,
habe jetzt mehrere Sender an meinem Leonardo laufen. Dazu habe ich die Library erweitert (analog zu dem obigen Link, der nur für den Arduino Uno etc. funktioniert): https://github.com/alexbloggt/Arduino-IRremote/tree/alexbloggt-patch-1
Funktioniert auch problemlos auf meinem Pro Micro.
Hi, in den netio-Screenshots hast du eine FB für den FireTV angelegt wenn ich das richtig seh. Darf man fragen wie? Thx
Hi Mogido,
dazu läuft auf meinem Banana Pi ein Socket-Server, der sich per ADB mit dem Fire-TV verbindet und die Befehle von netio entgegennimmt.
Moin!
Was wäre denn der günstigste Arduino, den man dafür verwenden könnte? Möchte ungern zu viel für dafür ausgeben, vielleicht hat ja einer einen Tipp für mich.
Hi Manfred,
am Besten mal in diesen Artikel schauen. USB-Schnittstelle am Arduino ist hier von Vorteil für einen einfachen Anschluss (z.B. Uno, Leonardo, Pro Micro, Nano aus China für 2-4€).
Hi,
Ich würde gerne mit einem IR-Sender die Geräte im Wohnzimmer steuern können.
Leider jedoch ist mein Raspberry Pi im Flur. Da dieser jedoch für die Funksteckdosen mit einem 433mHz Sender ausgestattet ist, hatte ich überlegt ob eine Möglichkeit existiert den Sender für die Datenübertragung zu Nutzen? Leider jedoch bin ich auf dem Gebiet noch nicht so bewandert.
Existieren da schon Ansätze oder Lösungen?
Hallo Fabian,
da gibt es zahlreiche Möglichkeiten. Die einfachste wäre, den Raspberry ins Wohnzimmer zu stellen – sofern möglich. Vermutlich ist das aber nicht möglich, daher deine Frage.
Die zweite Möglichkeit wäre, den Raspberry mit 433MHz Sender dort zu lassen, wo er ist und im Wohnzimmer einen Arduino mit 433MHz Empfänger und IR-Transmitter zu platzieren. Die Kommunikation zwischen Raspberry Pi und Arduino über 433MHz Funk habe ich in dem Artikel zum Lichtwecker beschrieben. Sofern es vom Wohnzimmer zum Flur nicht allzu weit ist, sollte das auch mit billigen 433MHz Sendern und Empfängern funktionieren.
Noch eine Möglichkeit wäre, es abseits des Raspberry Pis zu realisieren mit einem ESP8266. Das ist ein WLAN-Chip, der auch als Mikrocontroller (wie ein Arduino) benutzt werden kann. Je nach Ausführung ist dieser für 1-5€ in China zu bekommen. IRRemote gibt es auch dafür (habe ich noch nicht getestet, da meine ESP8266 noch nicht angekommen sind) und dank WLAN sollte es hier keine Reichweitenprobleme geben.
Ah ok, richtig das versetzen des Raspberry ist nicht möglich bzw. gewünscht. Die Anleitung des Lichtweckers hatte ich noch nicht gesehen. Sollte aber genau das bewirken was ich brauche. Werde ich mal ausprobieren. Vielen Dank.
Moin, also der Verwendungszweck ist mir klar. Jedoch denke ich das es trotz der „Standalone“ Variante einfach zu Unhandlich ist. Ich verwende eine Universalfernbedienung mit der ich sämtliche LEDs ansteuern kann sowie natürlich die Geräte. Mit deiner hier vorgestellten Lösung müsste man die IR Diode immer wieder neu positionieren um wirklich alle Geräte erreichen zu können.
Hallo Robert,
klar – eine Universalfernbedienung kann oft die einfachere Lösung sein. Es lassen sich aber auch mehrere Sende-Dioden (am Arduino Uno + Leonardo jew. 3) anschließen, sodass man mit einem Arduino eigentlich einen kompletten Raum abdecken kann.
Guten Tag,
Habe eine ähnliches Projekt vor zu bauen.
Welche IR-Diode hast du verwendet?
Hast du vielleicht ein Link für mich ?
Hallo Markus,
puh – ich habe mir irgendwann man eine Packung IR-LEDs auch China geholt, wo genau ich die her habe, weiß ich leider nicht mehr :(
Hallo Alex,
vielen Dank für deinen Beitrag und überhaupt schmöker ich gerade gern durch deine Texte in deinem Blog; auch wenn ich nur einen Teil davon verstehen, denn ich versuche mich gerade an meinen ersten Schritten in Sachen Arduino (und überhaupt ist mein Interesse in dem ganzen Elektronik-Bereich noch recht neu) und da schien mir eine Universalfernbedienung ein nützliches Utensil zu sein. Ein bisschen was habe ich auch, denke ich zumindest, schon gelernt. Nun habe ich deinen Sketch zum Senden von IR-Signalen angepasst und auf meinen Arduino Uno übertragen und es gab keinerlei Reaktion. Nach etwas hin und her probieren habe ich einfach direkt deinen Sketch genommen (auch wenn hier kein Apple im Raum ist) und auch da zeigt die LED keine Reaktion. Bei anderen Sketch-Beispielen aus der IRremote-Bibliothek funktioniert sie aber (auch wenn ich manchmal den Pin ändern muss). Ich bin bei deinem Beispiel an Pin 13. Vielleicht liegt es auch einfach daran, dass ich nicht die richtigen Befehle in den seriellen Monitor eingebe. „apple_play“ oder ähnliches bringt leider keine Reaktion. Hast du einen Hinweis, wo der Fehler liegen könnte oder wo ich mich noch einmal schlau machen könnte?
Hallo Andreas,
der Pin zum Senden sollte beim Arduino Uno aufgrund eines anderen Timers Pin 3 sein.
Hallo,
Bitte im Tutorial den Sprachsteuerung-Teil um Alexa bzw. Echo ergänzen, wäre sehr dankbar!
Und Paypal Spende ermöglichen, dann kann man sich auch mit ein paar Euronen dankbar zeigen.
Viele Grüße,
Johann