Universalfernbedienung

Universalfernbedienung

 25.12.2013 -  Sebastian Pech -  ~5 Minuten

Der erste Teil aus dem Bereich Home automation umfasst meine Entwicklung einer Universalfernbedienung. Im Handel gibt es diese Geräte in einer großen Anzahl als Fernsteuerungen. Mein Ziel in diesem Projekt besteht darin die Fernbedienungen komplett überflüssig zu machen. Mittels eines einfachen Befehls per Handy, Tablet oder Sprache sollen alle beteiligten Geräte automatisch eingeschaltet und richtig eingestellt werden. Beispielsweise würde der Befehl „Kino an“ dafür sorgen das mein Verstärker, TV und Blu-ray-Player eingeschaltet wird. Beim TV und dem Verstärker wird dann der Player als Quelle eingestellt. Zusätzlich muss die Beleuchtung im Raum gedimmt werden. Mittels „Kino aus“ werden dann wieder alle Geräte ausgeschaltet.

Grundidee

Grundlage für die Steuerung der Geräte per Infrarot ist der Arduino Uno . Die Arduino-Plattform ist eine aus Soft- und Hardware bestehende Physical-Computing-Plattform. Beide Komponenten sind im Sinne von Open Source quelloffen. Die Hardware besteht aus einem einfachen I/O-Board mit einem Mikrocontroller und analogen und digitalen Ein- und Ausgängen. Die Entwicklungsumgebung verwendet die Programmiersprache Processing, die auch technisch weniger Versierten den Zugang zur Programmierung und zu Mikrocontrollern erleichtern soll. Arduino kann verwendet werden, um eigenständige interaktive Objekte zu steuern oder um mit Softwareanwendungen auf Computern zu interagieren (z. B. Adobe Flash, Processing, Max/MSP, Pure Data, SuperCollider, diversen Skriptsprachen, Terminal, vvvv etc.). (Quelle: Wikipedia )

Die Infrarotprotokolle unterscheiden sich nicht nur von Hersteller zu Hersteller sondern zum Teil auch von Gerät zu Gerät. Um die korrekten Signale senden zu können müssen die richtigen Signale ermittelt werden. Infrarotsender funktionieren nach dem Prinzip einer LED, welche in einem bestimmten Intervall ein- und ausgeschaltet wird. Typischerweise umfasst die Modulation der Frequenz (also das ein- und ausschalten) 36, 38 oder 40KHz. Der aktive Zustand der LED wird dabei „mark“ genannt und der inaktive Zustand „space“. Für jede Taste einer Fernbedienung gibt es ein eigenen Code der die Schaltzeiten bestimmt. Eine detaillierte Erklärung ist auf der Webseite von Ken Shirriff zu finden.

IR Empfänger

Für den Empfang von Infrarot Signalen habe ich mir das IR-Empfänger-Modul TSOP 4838 bei Conrad bestellt. Das Modul lässt sich einfach an den Arduino anschließen. Da der Empfänger für den Spannungsbereich -0.3 – 6.0 V ausgelegt ist kann dieser direkt an den 5V Anschluss des Arduino angeschlossen werden. Die Vgrnd werden ebenfalls an den Ground (GND) vom Arduino angeschlossen. Die Datenleitung kommt an einen der freien PWM Steckplätze (Bsp. 11 – Siehe Abbildung)

Zur Abfrage der Daten kommt die, aus dem oben erwähnten Artikel, erstellt IRremote Library zum Einsatz. Standardmäßig werden von der Bibliothek die Formate NEC, SONY, RC5, RC6, DISH, SHARP, PANASONIC, JVC, SANYO und MITSUBISHI unterstützt. Die Bibliothek gibt es auf Github Das Beispielprogramm IRrecord wird auf dem Arduino übertragen und danach die Fernsteuerung des Gerätes auf den Empfänger ausgerichtet. Dabei sollte auf dem Serial Monitor der korrekte Code erscheinen.

Das Programm gibt für meinen YAMAHA auf Anhieb den NEC Code 0x5EA1E817 für einen der Kanäle aus. Ernüchterung trat bei der Fernsteuerung für meinen neuen Samsung UE40F6170 3D-LED-Backlight-Fernseher auf, ebenso wie dem LG Blu-ray-Player. Beide Fernbedienungen erzeugen im IRrecvDump nur eine Ausgabe eines unbekannten Protokolls und dem RAW Output. Auf der Mikrocontroller Webseite konnte ich jedoch ermitteln, dass SAMSUNG für seine Fernbedienungen das Format „1 Start-Bit + 32 Daten-Bits + 1 Stop-Bit “ nutzt. Da das Startbit hier aus zwei 4500µs Pulsen besteht und die anderen Format in der Regel nur ein High und einen Low Pulse nutzen musste ich eine eigene Routine schreiben. Diese funktionierte danach interessanterweise auch mit der LG Fernbedienung. Im Folgenden meine Anpassungen als Vervollständigung.

IRemote.h

#define SAMSUNG32 11

class IRrecv
{
[...]
long decodeSamsung32(decode_results *results);
[...]

IRemoteInt.h

#define SAMSUNG32_HDR_MARK  4500
#define SAMSUNG32_HDR_SPACE 550
#define SAMSUNG32_BIT_MARK  550
#define SAMSUNG32_ONE_SPACE 1650
#define SAMSUNG32_ZERO_SPACE  560

#define SAMSUNG32_BITS 32

IRemote.cpp

int IRrecv::decode(decode_results *results) {
[...]
#ifdef DEBUG
    Serial.println("Attempting SAMSUNG32 decode");
#endif
    if (decodeSamsung32(results)) {
        return DECODED;
    }
[...]
}

long IRrecv::decodeSamsung32(decode_results *results) {
    unsigned long long data = 0;
    int offset = 1;

    if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG32_HDR_MARK)) {
        return ERR;
    }
    offset++;
    if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG32_HDR_MARK)) {
        return ERR;
    }
    offset++;

    // decode address
    for (int i = 0; i < SAMSUNG32_BITS; i++) {
        if (!MATCH_MARK(results->rawbuf[offset++], SAMSUNG32_BIT_MARK)) {
            return ERR;
        }
        if (MATCH_SPACE(results->rawbuf[offset],SAMSUNG32_ONE_SPACE)) {
            data = (data << 1) | 1;
        } else if (MATCH_SPACE(results->rawbuf[offset],SAMSUNG32_ZERO_SPACE)) {
            data <<= 1;
        } else {
            return ERR;
        }
        offset++;
    }

    if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG32_HDR_SPACE)) {
        return ERR;
    }

    results->value = data;
    results->decode_type = SAMSUNG32;
    results->bits = SAMSUNG32_BITS;
    return DECODED;
}

Beispiel: IRrecvDump

Hier muss der if/else Block noch um den neuen Type ergänzt werden.

else if (results->decode_type == SAMSUNG32) {
    Serial.print("Decoded SAMSUNG32: ");
}

IR Sender

Für das Senden nutze ich die IR-Sendediode TSAL 6200 (5 mm, Wellen-Länge 940 nm). Da die Betriebsspannung geringer ist als die Ausgangsspannung des Arduino muss die Diode mit einem Vorwiderstand betrieben werden (siehe vorherige Abbildung). Standardmäßig nutzt die Bibliothek den PWM PIN 3 für das Senden (im Header hinterlegt). Mit dem Aufruf sendNEC konnte der YAMAHA Verstärker sofort angesteuert werden.

irsend.sendNEC(0x5EA1E817, 32);

Für den SAMSUNG TV und den LG Blu-ray-Player fehlt jetzt noch das Gegenstück zum Senden der Codes. Hierzu musste ich wieder die Bibliothek erweitern.

IRemote.h

class IRsend
{
[...]
    void sendSamsung32(unsigned long data);
[...]

IRemote.cpp

void IRsend::sendSamsung32(unsigned long data) {
    enableIROut(38);
    mark(SAMSUNG32_HDR_MARK);
    space(SAMSUNG32_HDR_MARK);
    for (int i=0; i < 32; i++) {
        mark(SAMSUNG32_BIT_MARK);
        if (data & TOPBIT) {
            space(SAMSUNG32_ONE_SPACE);
        } else {
            space(SAMSUNG32_ZERO_SPACE);
        }
        data <<= 1;
    }
    mark(SAMSUNG32_HDR_SPACE);
    space(0);
}

Nächste Schritte

Mit den Anpassungen konnte ich die vorhandenen Fernbedienungen abfragen und die Codes an die Geräte senden. Zur vollständigen Integration muss der Arduino in Zukunft in die Haussteuerung integriert werden. Außerdem müssen alle Befehle der verschiedenen Fernbedienungen einmal ermittelt werden. Letzteres ist eine reine Fleißarbeit. Ersteres werde ich in den kommenden Tagen und Wochen beschreiben.