IR-Fernbedienung mit Smarthome

IR-Fernbedienungen gibt es für viele Geräte. Manche dieser Geräte können nicht ins Smarthome eingebunden werden. Hierfür gibt es Bridges, die eine Kommunikation zwischen Smarthome und Endgerät mittels Infrarotübertragung herstellen können.

Ich möchte in meinem Projekt zeigen, wie ich meine Smart Home inkompatible Stereoanlage steuern kann. Dabei verwende ich den ESP8266, Infrarot-Dioden, einen Infrarot-Empfänger und ein paar weitere Komponenten. Zusätzlich habe ich für das entstandene Gerät ein 3D gedrucktes Gehäuse erstellt.

Wie funktionieren IR-Fernbedienungen?

Die Kommunikation zwischen Endgerät und Fernbedienung wird über Lichtsignale hergestellt. Die Lichtwellen sind im für den Menschen nicht sichtbaren Infrarot Bereich. IR-Signale lassen sich für das menschliche Auge sichtbar machen, wenn man z. B. die Handykamera vor die Sendeöffnung der Fernbedienung hält. Dann kann man das Leuchten der Fernbedienung sehen. Handy Kameras reagieren auch auf Infrarot Licht.

In der Fernbedienung ist ein Sender für Infrarot-Signale verbaut. Im Endgerät ist ein Empfänger verbaut. Wie beim Morsen gibt es eine Sprache, die beide verstehen. So wird bei jedem Tastendruck eine Zeichenfolge von der Fernbedienung gesendet, die dem Endgerät sagt, welche Taste aktuell gedruckt wurde. So kann das Gerät verschiedenste Befehle empfangen und darauf reagieren.

Weitere Informationen zum Thema Fernbedienung gibts natürlich bei Wikipedia.

https://de.wikipedia.org/wiki/fernbedienung

Woher bekomme ich die Kommandos, Befehle der Fernbedienung?

Viele Hersteller verwenden unterschiedliche Befehle, Kommandos für die Kommunikation ihrer IR-Fernbedienungen. Das ist sinnvoll, da beim Ausschalten des Radios nicht unbedingt der Videorekorder eine Aufnahme starten soll.

Bauteile

Aufbau Breadboard

Der Infrarot-Empfänger benötigt eine Spannungsversorgung von 3V. Die empfangen Daten sendet der Sensor über einen Kanal an den ESP8266. Vorsicht mit der Polarität. Wird der IR-Sensor falsch angeschlossen, kann er die gesamte Schaltung beschädigen.

Steckplatine ESP8266 IR Sensor

Programm zur Auswertung der Signale

Ich verwende für mein Projekt die Bibliothek „IRremoteESP8266„. Daraus habe ich mir das Beispiel für das Empfangen von IR-Signalen übernommen.

https://github.com/crankyoldgit/IRremoteESP8266/blob/master/examples/IRrecvDumpV2/IRrecvDumpV2.ino

Datensignale IR-Fernbedienung auswerten

Das Programm wird auf den ESP8266 übertragen. Danach wird die Fernbedienung vor den Sensor gehalten. Beim Drücken einer Taste auf der Fernbedienung wird der gesendete Befehl vom ESP8266 ausgewertet. Das Ergebnis wird über das Serial Terminal ausgegeben.

Serial Terminal ESP8266 IR Protokoll
Serial Terminal ESP8266 IR Protokoll
Anwendungsbeispiel ESP8266 IR-Sensor
Anwendungsbeispiel ESP8266 IR-Sensor

Senden eigener IR-Signale mit ESP8266

Für das Senden von IR-Signalen mit einem ESP8266 habe ich mir folgende Schaltung einfallen lassen.

Schaltplan und Platine Dioden

Bauteile IR-Sender Smarthome

Gehäuse für 3D-Drucker

Das Gehäuse wurde mit FreeCad erstellt. Unter folgendem Link kann das 3D-File heruntergeladen werden. https://www.thingiverse.com/chrisbue/designs

Gehäuse IR-Fernbedienung ESP8266 3D Druck
Gehäuse IR-Fernbedienung ESP8266 3D Druck

Zusammengebaut

Beim Zusammenbau ist zu beachten, dass die IR-Platine sowohl von der beschrifteten Seite als auch von der unbeschrifteten Seite bestückt werden kann. Im Entwicklungsprozess hat sich herausgestellt, dass der Wemos D1 ESP8266 mit Chip nach unten besser in das Gehäuse passt. Dadurch lässt sich der USB Stecker leichter einstecken. Auch die LED des ESP8266 ist durch die IR Dioden schöner zu sehen, wenn der WEMOS D1 ESP8266 mit ESP Chip nach unten eingebaut ist.

Program für ESP8266

Ich verwende in meinem Smarthome MQTT als Kommunikationsprotokoll über mein WLAN. Daher benötige ich für meine ESP8266 IR-Fernbedienung eine Möglichkeit, über das MQTT-Protokoll den gewünschten IR-Befehl zu übertragen. Der übertragene Befehl wird dann durch den ESP8266 empfangen und über die IR Dioden in Richtung der Hifi-Anlage gesendet.

Includes

In meinem Programm verwende ich Includes aus dem Projekt „IRremoteESP8266“ und einen Include der mir die WLAN und MQTT aufbaut. Mein „Mqtt Include-File ESP8266 MqttSetup.h“ Projekt.

Anpassungen am Programm

Für meine Anwendung möchte ich IR Signale des Herstellers Panasonic verwenden. Daher sende ich über den Aufruf:

irsend.sendPanasonic(address, data);

Gegebenenfalls muss dieser Befehl auf den jeweiligen Anwendungsfall angepasst werden. Dazu bitte ich sich das Projekt „IRremoteESP8266“ genauer anzuschauen, da hier die verschiedenen Protokolle der Hersteller aufgeführt sind.

Die zweite Änderung bezieht sich auf die Ziele:

#define mqtt_topic_ir_device "topic/for/ir_hifi/connection"

Hier habe ich eingetragen, unter welcher Überschrift (Topic) die IR-Fernbedienung im MQTT Netzwerk Befehle empfangen wird.

MQTT Nachricht für „on“ und „off“ über IR-Fernbedienung

Möchte ich meine Hifi Anlage einschalten oder ausschalten, so kann ich nun über MQTT eine Nachricht erzeugen.

Topic:

topic/for/ir_hifi/connection

Message:

{address:16388, data:88341947}

Programm, Source, Code, …

#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include "MqttSetup.h"

#define mqtt_topic_ir_device "topic/for/ir_hifi/connection"

IRsend irsend(4);  // Set the GPIO to be used to sending the message. ESP8266 GPIO 4 (D2).

StaticJsonDocument<200> jsonReceived;

void setup() {

  irsend.begin();
  Serial.begin(115200);

  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  setupWifiMqtt();

  delay(1000);

  subscribeWifiMqtt(mqtt_topic_ir_device);
  setWifiMqttMessageCallback( mySpecialCallback );

}

void loop() {
}

void mySpecialCallback( char* messageTopic, char* message ){

  digitalWrite(LED_BUILTIN, LOW);
  
  if(strcmp(messageTopic, mqtt_topic_ir_device) == 0){

    Serial.println(message);

    deserializeJson(jsonReceived, message);

    JsonVariantConst adressJson = jsonReceived["address"];
    JsonVariantConst dataJson = jsonReceived["data"];

    Serial.println(adressJson.as<int>());
    Serial.println(dataJson.as<int>());

    uint16_t address = adressJson.as<int>();

    uint32_t data = dataJson.as<int>();

    jsonReceived.clear();

    char buffer[64];
    sprintf(buffer, "konverted address:%d data:%d}", address, data);
    Serial.println(buffer);

    Serial.println("Send IR");
    irsend.sendPanasonic(address, data);
  }

  digitalWrite(LED_BUILTIN, HIGH);
}

uint32_t wrap(uint64_t n, uint32_t syn) {

    if (n < std::pow(2, 32) - syn) {
        return static_cast<uint32_t>(n) + syn;
    }

    return syn;
}