Universal-Fernbedienung IR Codes und Dreambox

Hallo,

ich bin jetzt bei der vorerst letzten Funktion meiner Multimediabox, damit sie erstmal laufen kann.
Dazu möchte ich gerne meine ganzen Fernbedienungen einlesen irgendwie speichern und wieder ausgeben können.
Zu dem "irgendwie speichern" weiß ich noch nicht genau, wie ich es letztendlich machen möchte.
In der Box befindet sich u.a. auch ein RaspberryPi, dass mit dem Ardunio verbunden ist.
Entweder, wird also auf dem RaspberryPi gespeichert, auf einer SDCard die direkt mit dem Ardunio verbunden ist oder komplett ausgelagert in einer App, die den Code an das Arduino schickt - das ist aber noch ferne Zukunftsmusik.

Momentan scheitere ich daran die Signale meiner Fernbedienungen einzulesen und wieder auszugeben.
Dabei hängt es vor allem an der selben Stelle an der meine one4all URC 7960 ebenfalls scheiterte.
Ich bekomme es einfach nicht hin die Fernbedienung der Dreambox einzulesen bzw. wieder auszugeben.
Alle anderen Geräte (Fernseher, AV-Receiver, IR-Playstation Brücke) funktionieren einwandfrei.

Verbaut habe ich als IR-Diode/Emitter eine TSAL6200 und als IR-Empfänger/Transistor einen TSOP1738 von Vishay .

Ich benutze die library von Ken Shirriff.

Ich habe den Sketch IRrecvDemo.ino getestet:

/*
 * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }
  delay(100);
}

Dabei kommen allerdings mehrere und dann auch noch wechselnde Codes bei raus:

Durchlauf 1 Durchlauf 2 Durchlauf 3 Durchlauf 4 Durchlauf 5
F7D5FC52
3A5D99A3
F7D5FC52
3A5D99A3
3A5D99A3
EE1AAFE4
EE1AAFE4
23986D1A
479AE45F
EE1AAFE4
F7D5FC52
3A5D99A3
F7D5FC52
F7D5FC52
F7D5FC52
97307A58
97307A58
4E59E22
97307A58
97307A58
F7D5FC52
F7D5FC52
F7D5FC52
F7D5FC52
F7D5FC52
D9435459
D9435459
49684660
D9435459
D9435459

Wie man sieht, sind die Werte teilweise ähnlich, aber nie identisch...

Ich habe auf verschiedene weise versucht dies dann mittels

  irsend.sendNEC(0xF7D5FC52, 32);

zu senden - teilweise auch mit einem delay von 10-50 zwischen den einzelnen Codes, allerdings erfolglos...

Der Sketch IRrecvDump.ino der dabei war liefert mit Immer

F7D5FC52
Unknown encoding: F7D5FC52 (32 bits)

und dann bei jedem Tastendruck eine andere Ausgabe der Raw Daten

F7D5FC52
Unknown encoding: F7D5FC52 (32 bits)
Raw (18): -13558 250 -1100 250 -2200 250 -750 200 -2750 250 -1250 250 -1200 250 -900 200 -2050 250 
F7D5FC52
Unknown encoding: F7D5FC52 (32 bits)
Raw (18): -16764 300 -1050 250 -2200 250 -700 300 -2700 300 -1200 250 -1250 250 -850 250 -2050 300 
F7D5FC52
Unknown encoding: F7D5FC52 (32 bits)
Raw (18): -3610 250 -1100 250 -2200 250 -750 200 -2750 250 -1250 250 -1200 250 -900 200 -2050 250 
F7D5FC52
Unknown encoding: F7D5FC52 (32 bits)
Raw (18): -16764 250 -1100 250 -2200 250 -700 250 -2750 250 -1200 250 -1250 250 -900 250 -2050 200 
F7D5FC52
Unknown encoding: F7D5FC52 (32 bits)
Raw (18): -10138 250 -1100 250 -2200 250 -700 250 -2750 250 -1200 250 -1250 250 -850 250 -2050 250

Wobei ich eher vermute, dass der "Rest" (also dass, was bei dem IRrecvDemo.ino Sketch noch mit empfangen wurde einfach verschluckt wird).
Ein einfaches Senden des F7D5FC52 Codes bringt leider auch nichts.

Um alle möglichkeiten auszuschöpfen habe ich noch die Daten gemäß dieser Anleitung komplett als RAW-Daten ausgeben lassen und dann die kompletten Werte (138 Werte) ausgeben lassen - erfolglos.

Ich hoffe hier hat jemand eine zündende Idee, wie ich den Code der Fernbedienung so auslese, dass er reproduzierbar und vollständig ist und wie ich ihn wieder ausgebe.

Vielen Dank!

Ich vermute mal, dass die Dreambox ein spezielles IR-Protokoll nutzt, dass nicht unterstützt wird. Google hat irgendwas mit TWIRP ausgespuckt, sagt mir aber auch nix...

Wenn dein RaspberryPi und deine Dreambox beide am Netzwerk hängen, wäre es vielleicht eine Alternative die Dreambox direkt über das Netzwerk zu steuern, ähnlich wie über das Webinterface. Der RasPi muss dafür nur einen html-Link aufrufen, z.B. über ein Python-Script.

Nutzte das bei mir mit einer VU+, dürfte aber mit der Dreambox bestimmt genauso funktionieren.

Ja das ist theoretisch möglich.
Allerdings nur dann, wenn die Dreambox schon gestartet ist.
Apps die das WebIf aufrufen oder über die internen Ports die Dreambox steuern gibt es ja bereits - allesamt aber natürlich nur nutzbar, wenn die Dreambox gestartet ist, da sie kein WOL unterstützt bzw. meine hängt über WLAN drin. Die also doppelt nicht :smiley:
Eigentlich SOLLTE es doch egal sein, welches protokoll das ist oder?
Solange ich die RAW-Daten nehme und diese zurück gebe, versteht mein System zwar nicht, was es da genau schickt, aber es sollte zumindest etwas so zurück geben, dass die Dreambox es versteht :slight_smile:

Ich danke dir auf jeden Fall schon mal für die Antwort.
Auch wenn es jetzt nicht die Lösung ist, aber immerhin ist TWIRP schon mal ein Anfang.

eventuell weiß hier ja jemand sogar mehr oder hat noch eine Idee dazu.

Also ich habe es jetzt noch ein paar mal versucht und dabei tatsächlich etwas brauchbares gefunden.
Mit der Instructables Lösung bekomme ich einen "Code" der so aussieht:

delayMicroseconds(12008); pulseIR(320);
delayMicroseconds(1040); pulseIR(280);
delayMicroseconds(2140); pulseIR(280);
delayMicroseconds(660); pulseIR(300);
delayMicroseconds(2640); pulseIR(300);
delayMicroseconds(1180); pulseIR(280);
delayMicroseconds(1180); pulseIR(300);
delayMicroseconds(800); pulseIR(280);
delayMicroseconds(1980); pulseIR(280);
delayMicroseconds(12700); pulseIR(300);
delayMicroseconds(1040); pulseIR(300);
delayMicroseconds(2520); pulseIR(280);
delayMicroseconds(680); pulseIR(280);
delayMicroseconds(660); pulseIR(280);
delayMicroseconds(660); pulseIR(280);
delayMicroseconds(2660); pulseIR(320);
delayMicroseconds(640); pulseIR(300);
delayMicroseconds(660); pulseIR(280);
delayMicroseconds(15924); pulseIR(320);
delayMicroseconds(1040); pulseIR(280);
delayMicroseconds(2140); pulseIR(280);
delayMicroseconds(660); pulseIR(280);
delayMicroseconds(2660); pulseIR(300);
delayMicroseconds(1160); pulseIR(300);
delayMicroseconds(1180); pulseIR(280);
delayMicroseconds(820); pulseIR(300);
delayMicroseconds(1980); pulseIR(280);
delayMicroseconds(12680); pulseIR(320);
delayMicroseconds(1020); pulseIR(300);
delayMicroseconds(1480); pulseIR(300);
delayMicroseconds(1740); pulseIR(280);
delayMicroseconds(660); pulseIR(280);
delayMicroseconds(660); pulseIR(300);
delayMicroseconds(2640); pulseIR(300);
delayMicroseconds(660); pulseIR(280);
delayMicroseconds(660); pulseIR(300);
delayMicroseconds(15804); pulseIR(320);
delayMicroseconds(1040); pulseIR(280);
delayMicroseconds(2140); pulseIR(280);
delayMicroseconds(660); pulseIR(300);
delayMicroseconds(2640); pulseIR(300);
delayMicroseconds(1180); pulseIR(280);
delayMicroseconds(1180); pulseIR(280);
delayMicroseconds(840); pulseIR(280);
delayMicroseconds(1980); pulseIR(280);
delayMicroseconds(12680); pulseIR(320);
delayMicroseconds(1040); pulseIR(280);
delayMicroseconds(1480); pulseIR(320);
delayMicroseconds(1720); pulseIR(280);
delayMicroseconds(660); pulseIR(300);
delayMicroseconds(660); pulseIR(280);
delayMicroseconds(2660); pulseIR(280);
delayMicroseconds(660); pulseIR(300);
delayMicroseconds(660); pulseIR(280);
delayMicroseconds(12780); pulseIR(320);
delayMicroseconds(1020); pulseIR(300);
delayMicroseconds(2120); pulseIR(300);
delayMicroseconds(660); pulseIR(280);
delayMicroseconds(2660); pulseIR(280);
delayMicroseconds(1180); pulseIR(280);
delayMicroseconds(1180); pulseIR(300);
delayMicroseconds(800); pulseIR(280);
delayMicroseconds(2000); pulseIR(280);
delayMicroseconds(12700); pulseIR(320);
delayMicroseconds(1020); pulseIR(300);
delayMicroseconds(1320); pulseIR(300);
delayMicroseconds(1840); pulseIR(280);
delayMicroseconds(660); pulseIR(300);
delayMicroseconds(660); pulseIR(280);
delayMicroseconds(2660); pulseIR(280);
delayMicroseconds(660); pulseIR(280);
delayMicroseconds(660); pulseIR(300);

Damit kann ich die Dreambox Ein- und Ausschalten.
Da mir der Code sehr lang vorkam, habe ich immer mal an den "auffälligen Stellen" Teile probiert und konnte feststellen, dass dieser Abschnitt hier auch die Dreambox Ein- und Ausschaltet:

delayMicroseconds(12680); pulseIR(320);
delayMicroseconds(1040); pulseIR(280);
delayMicroseconds(1480); pulseIR(320);
delayMicroseconds(1720); pulseIR(280);
delayMicroseconds(660); pulseIR(300);
delayMicroseconds(660); pulseIR(280);
delayMicroseconds(2660); pulseIR(280);
delayMicroseconds(660); pulseIR(300);
delayMicroseconds(660); pulseIR(280);
delayMicroseconds(12780); pulseIR(320);
delayMicroseconds(1020); pulseIR(300);
delayMicroseconds(2120); pulseIR(300);
delayMicroseconds(660); pulseIR(280);
delayMicroseconds(2660); pulseIR(280);
delayMicroseconds(1180); pulseIR(280);
delayMicroseconds(1180); pulseIR(300);
delayMicroseconds(800); pulseIR(280);
delayMicroseconds(2000); pulseIR(280);

Jetzt muss ich nur noch zwei sachen schaffen:
1.: Ich muss eine Automatisierung entwickeln, die mir direkt den gekürzten, wichtigen Teil ausgibt, damit der Code nicht unnötig lang ist. (eher sekundär, da ich mit Fleiß auch selbst alles durchtesten kann)
2.: Ich muss das Ganze irgendwie in eine art Protokoll verpacken, um diese Pulse in komprimierter Fassung im Arduino zu speichern.

Problem ist nämlich, dass ich mit der kompletten Aufzeichnung (ungekürzt) gerade einmal 11 Tasten im Ardunio speichern kann. Abgesehen davon, dass die Fernbedienung eigentlich 40 Tasten hat, sollte das Arduino noch eine ganze Reihe anderer Funktionen leisten, als "nur" eine Universalfernbedienung zu sein.

Ich danke für Hilfe!

hi,

ich würde da eher mal in dream-foren suchen, wie zb im IHAD-forum, oder gleich dort fragen. meine harmony kann meine DM8000 problemlos schalten.

gruß stefan

Das Thema ist zu speziell glaube ich.
Ich werde zwar den Versuch mal starten, aber außer diesem Beitrag habe ich nichts gefunden, was auch nur annähernd so "Elektronisch" ist. In dem Beitrag geht es darum, wie man mit einem Arduino, welches man per IR steruert, Befehle per TCP Protokoll an die Dreambox sendet.
Problem ist halt nur, dass die Dreambox dafür an sein muss.
Bei Betrachtung des RAW-Codes ist mir aufgefallen, dass es immer 9 Blöcke sind, in denen Ein- und Ausgeschaltet wird.
Dabei müssen mindestens 2 spezifische 9er Blöcke aufeinander folgen mit einer Pause dazwischen von ungefähr
12680µs - 15944µs dazwischen.
Diese Blöcke habe ich versucht zu vereinheitlichen und zu verkleinern.
Die "On"-Zeit bewegt sich meist zwischen 240 und 320µs.
Diese konnte ich einheitlich als 260µs senden und bisher gab es dabei keine Probleme - somit ist schon mal die "On-Zeit" in eine funktion gewandert, die einfach diese Zeit die IR-Diode einschaltet bzw Pulsieren lässt.
Nun muss noch die Pause zwischen den Pulsen irgendwie komprimiert im Arduino hinterlegt werden.

Die langen Pausen zwischen den beiden 9er Blöcken von 12680µs - 15944µs lasse ich dabei einfach einheitlich z.B. 14000µs sein.
Das klappt bisher auch problemlos (leider nur mit 3 Tasten getestet).

Jetzt kommt aber der Killer:
Innerhalb eines 9er Blocks ist die Pause zwischen 700µs und 2700µs.
Ich könnte daher die "Off-Zeiten" zwischen den Pulsen durch 20 teilen und müsste für jede Pause "nur" ein Byte belegen.

Das Senden von Ein/Aus sieht dann etwa so aus:

  byte teilEins[8] = {54,129,35,35,36,135,35,35};
  dreamboxSend(teilEins);
  delayMicroseconds(14000);
  byte teilZwei[8] = {54,109,35,135,61,61,43,101};
  dreamboxSend(teilZwei);

Nicht wundern, dass ich nur einen 8er array habe.
Der jeweils erste Puls hat ja keine Pause.
Die Funktion DreamboxSend sieht so aus:

void dreamboxSend(byte thisSend[8])
{
  
  //erster Puls
  cli();  // this turns off any background interrupts
  for(int i=0; i<10; i++)
  {
    // 38 kHz is about 13 microseconds high and 13 microseconds low
    digitalWrite(IRledPin, HIGH);  // this takes about 3 microseconds to happen
    delayMicroseconds(10);         // hang out for 10 microseconds
    digitalWrite(IRledPin, LOW);   // this also takes about 3 microseconds
    delayMicroseconds(10);         // hang out for 10 microseconds    
  } 
  sei();  // this turns them back on

  //die 8 weiteren Pulse
  for(int i=0; i<8; i++)
  {
    //IR-Diode auszeit
    delayMicroseconds(thisSend[i] * 20);

    //IR-Diode puls
    //10 Pulse   
    cli();  // this turns off any background interrupts
    for(int i=0; i<10; i++)
    {
      // 38 kHz is about 13 microseconds high and 13 microseconds low
      digitalWrite(IRledPin, HIGH);  // this takes about 3 microseconds to happen
      delayMicroseconds(10);         // hang out for 10 microseconds
      digitalWrite(IRledPin, LOW);   // this also takes about 3 microseconds
      delayMicroseconds(10);         // hang out for 10 microseconds    
    } 
    sei();  // this turns them back on
  
  } 
}

Was hat diese Maßnahme gebracht?
Gespeichert als Liste dieser On/Off Timings verbrauche ich pro Taste 368 Byte.
Durch dieses Verfahren sind es "nur" noch 260 Byte pro Taste.
Das ist mit 10400 Byte für 40 Tasten zwar immer noch zu viel, aber schon mal ein Anfang.

Vielleicht hat hier ja jemand mit mehr grips noch eine Idee wie man das Ganze noch kleiner bekommt.

Vielen Dank

Ich wollte nur mal Rückmeldung geben:

Weil mir im IHD Forum keiner helfen wollte, da ich keine echte Dreambox habe, sondern eine Sunray, musste ich den Weg alleine gehen.
Es gab außer dem preislichen Unterschied (600€ Differenz) übrigens Gründe, warum ich mich sogar bei gleichem Preis für eine Sunray entschieden hätte. Zum Einen wäre das die bereits verbaute WLAN Antenne, und zum Anderen (noch wichtiger) der TrippleTuner der DVB-S2,DVB-C und DVB-T unterstützt.
Bei ner echten Dreambox kann man nur DVB-S2 ODER DVB-C wählen.
Sollte man also umziehen und statt Kabel nur Satellit haben (oder umgekehrt), darf man das Gerät verkaufen und ein neues holen.
Naja. Mit dem unfreundlichen Forum dort bin ich jedenfalls durch.

Ich habe mir also die Codes aller Tasten (mehrfach pro Taste) als RAW-Daten ausgegeben.
Diese zum Vergleich in eine riesen Tabelle gepackt und mir angeschaut, welche Teile der 54 Codepaare gleich bleiben.
Übrigens werden IMMER 54 Codepaare gesendet.
Es funktioniert zwar auch, wenn man die ersten 9 Paare weglässt und nur von Code 10 bis 27 sendet, aber leider nicht ganz so reproduzierbar, als wenn man alles gesendet hätte (teilweise wurde es dann also nicht erkannt).

Der 54 Signale lange Code hat genau 10 individuelle Codepaare.
Jedes "mark" ist dabei identisch (zum Glück - das hat mir zumindest etwas das "entschlüsseln" verinfacht) und nur die Pausen dazwischen unterscheiden sich.
Ich habe alle Codes bzw. die Pause per Excel der länge nach ordnen lassen und dann je nach länge zusammengefasst.
So habe ich z.B. alle Pausen von 680µs - 720µs in einer 700µ Pause zusammengefasst.
Das Zusammenfassen war teilweise etwas "kniffelig", da sich die Bereiche - gerade bei den längeren Pausen - doch ziemlich unterscheiden (auch innerhalb ein und der selben Taste).
Herausgekommen sind somit 21 unterschiedliche Pausen.
Ich habe mir dann einen Dekoder programmiert, der die Codes nach meinen festgelegten Pausen erkennt und einordnet.
Die Ergebnisse waren da schon absolut reproduzierbar und ich erleichtert, dass bis hierhin schon mal alles "klappte" wie ich mir das dachte.

Als nächstes habe ich die "festen Codepaare", also die bei jeder Taste gleich sind, nur auf Richtigkeit überprüfen lassen und die "individuellen Codepaare" angelehnt an meinen eingeteilten Bereichen ausgeben lassen.
Für den Fall, das die festen Codepaare alle korrekt sind und die individuellen Codepaare in einem bekannten Bereich liegen, wird somit NUR der individuelle Code (bzw. dessen Pausen) ausgegeben.
Da Ganze habe ich dann so per SM ausgeben lassen, dass ich ich den "dekodierten Code" direkt kopieren konnte.

Das sieht dann so aus:

Bereit zum decodieren des IR-Codes!


Code empfangen:
Code konnte dekodiert werden!


------------Code zum copy and pasten:------------
sendDreamboxCode(79, 65, 80, 71, 65, 80, 68, 70, 65, 80);
----------------------------------------------------

Für den Fall, dass man eine Taste lange drückt passt das von mir festgelegte Muster mit 54 Codepaaren natürlich nicht mehr.
In dem Fall sieht die Ausgabe so aus:

Bereit zum decodieren des IR-Codes!

Code empfangen:
Achtung! Code Nummer 36 passt nicht zum erwarteten Muster. Es kam: delayMicroseconds(15944);pulseIR(260);
Achtung! Code Nummer 48 passt nicht zum erwarteten Muster. Es kam: delayMicroseconds(1780);pulseIR(240);


Das Muster war nicht wie erwartet!
Ursache 1: Taste zu lange gedrueckt. Nochmal versuchen ob das Problem besteht.
Ursache 2: IR-Code unbekannt. Bitte an der genannten Stelle den Programmcode anpassen.

Die Funktion sendDreamboxCode() wurde dann im eigentlichen Sende-Sketch programmiert.
Sie nimmt die Zahlen und schaut welche Bereiche diesen entsprechen.
Dann werden die gleichbleibenden Codes ausgegeben und an den wichtigen Stellen die individuellen Codes gesendet.

Ich hätte eigentlich auch die Pausen komplett ausgeben lassen können, aber ich dachte mir, dass ich Speicher spare, wenn ich statt einer Zahl wie 15900 lieber eine kleinere Zahl substituiere (von 0-255) und dann später ersetzen lasse.
Das geht zwar etwas auf die Rechenleistung, machte aber in meiner Überlegung dennoch Sinn.

Nun: Was hats gebracht?
Mein kompletter Sende-Sketch ist 5710 Byte groß.
Dabei wird über den SM eine Zahl von 0-39 eingegeben (die Fernbedienung hat 40 Tasten) und die entsprechende Taste dann vom Arduino gesendet.
Pro Taste werden zusätzliche 54 Byte verbraucht.
Zum Vergleich: Beim Senden des kompletten RAW Codes brauchte ich pro Taste 1090 Byte
Meine vorherige Lösung, nur 18 Codepaare zu senden funktionierte zwar in 97% der fälle, war aber etwas gefrickelt und hätte vorrausgesetzt, dass ich jeden Code manuell Teste, welcher Bereich funktionier (bzw. ob er das wirklich tut) und auch die timings optimiere, damit dieser Teilcode dann besser erkannt wird.

Alles sehr zeitintensiv und das dafür, dass es doch nicht "richtig" gemacht ist.
Diese Lösung verbrauchte immernoch 260 Byte - also fast 5mal so viel Speicher pro Taste, obwohl ich nur 1/3 des Gesamtcodes sendete.

Hi,

ich stehe grad auch vor dem Problem meine Dreambox per IR zu steuern.
Kannst du dein Sketch bitte einstellen?

Gruß