IRMP
Von Frank M. (ukw)
IRMP - Infrarot-Multiprotokoll-Decoder
Einleitung
Da RC5 nicht nur veraltet, sondern mittlerweile obsolet ist und immer mehr die elektronischen Geräte der fernöstlichen Unterhaltungsindustrie in unseren Haushalten Einzug finden, ist es an der Zeit, einen IR-Decoder zu entwickeln, der ca. 90% aller bei uns im täglichen Leben zu findenden IR-Fernbedienungen "versteht".
IRMP ist u.a. lauffähig auf folgenden AVR µCs:
- ATtiny87, ATtiny167
- ATtiny45, ATtiny85
- ATtiny84
- ATmega8, ATmega16, ATmega32
- ATmega162
- ATmega164, ATmega324, ATmega644, ATmega644P, ATmega1284
- ATmega88, ATmega88P, ATmega168, ATmega168P, ATmega328P
Es gibt aber auch Portierungen auf diverse PIC µCs - für den CCS- und C18-Compiler. Auch ist IRMP mittlerweile auf ARM STM32 lauffähig.
IRMP - der Infrarot-Fernbedienungsdecoder, der mehrere Protokolle auf einmal decodieren kann, beherrscht folgende Protokolle:
| Protokoll | Hersteller |
|---|---|
| SIRCS | Sony |
| NEC | NEC, Yamaha, Canon, Tevion, Harman/Kardon, Hitachi, JVC, Pioneer, Toshiba, Xoro, Orion, NoName und viele weitere japanische Hersteller. |
| SAMSUNG | Samsung |
| SAMSUNG32 | Samsung |
| MATSUSHITA | Matsushita |
| KASEIKYO | Panasonic, Technics, Denon und andere japanische Hersteller, welche Mitglied der "Japan's Association for Electric Home Application" sind. |
| RECS80 | Philips, Nokia, Thomson, Nordmende, Telefunken, Saba |
| RECS80EXT | Philips, Technisat, Thomson, Nordmende, Telefunken, Saba |
| RC5 | Philips und andere europäische Hersteller |
| DENON | Denon, Sharp |
| RC6 | Philips und andere europäische Hersteller |
| RC6A | Philips, Kathrein und andere Hersteller, z.B. XBOX |
| APPLE | Apple |
| NUBERT | Nubert, z.B. Subwoofer System |
| B&O | Bang & Olufsen |
| GRUNDIG | Grundig |
| NOKIA | Nokia, z.B. D-Box |
| SIEMENS | Siemens, z.B. Gigaset M740AV (ab ~15kHz, siehe Bemerkungen zu F_INTERRUPTS) |
| FDC | FDC Keyboard (ab ~15kHz) |
| RCCAR | RC Car: IR Fernbedienung für Modellfahrzeuge |
| JVC | JVC |
| NIKON | NIKON |
| RUWIDO | RUWIDO (z.B. T-Home-Mediareceiver, MERLIN-Tastatur (Pollin)) |
| KATHREIN | KATHREIN |
| NEC16 | JVC |
| NEC42 | JVC |
| LEGO | Lego |
| THOMSON | Thomson |
| BOSE | Bose (z.Zt. nur im SVN) |
Jedes dieser Protokolle ist einzeln aktivierbar. Wer möchte, kann alle Protokolle aktivieren. Wer nur ein Protokoll braucht, kann alle anderen deaktivieren. Es wird nur das vom Compiler übersetzt, was auch benötigt wird.
Der auf AVR- und PIC-µCs einsetzbare Source zu IRMP entstand im Rahmen des Word Clock Projektes.
Anlass für einen eigenen IRMP-Artikel ist folgender Thread in der Codesammlung: Beitrag: IRMP - Infrared Multi Protocol Decoder
Protokolle
Einige Hersteller verwenden ihr eigenes Protokoll, dazu gehören u.a. Sony, Samsung und Matsushita. Philips hat RC5 entwickelt und natürlich auch selbst benutzt. RC5 galt damals in Europa als das Standard-IR-Protokoll, welches von vielen europäischen Herstellern übernommen wurde. Mittlerweile ist RC5 fast gar nicht mehr anzutreffen - man kann es eigentlich als "ausgestorben" abhaken.
Auch die japanischen Hersteller haben versucht, einen eigenen Standard zu etablieren, nämlich das sog. Kaseikyo- (oder auch "Japan-") Protokoll. Dieses ist mit einer Bitlänge von 48 sehr universell und allgemein verwendbar. Richtig durchgesetzt hat es sich aber bis heute nicht. Ich selbst habe jedenfalls noch keine einzige Fernbedienung gesehen, die das Kaseikyo-Protokoll nutzt.
Heutzutage wird vornehmlich das NEC-Protokoll verwendet - und zwar von den unterschiedlichsten (Marken- und auch Noname-)Herstellern. Ich schätze den "Marktanteil" auf ca. 80% beim NEC-Protokoll. Fast alle Fernbedienungen im alltäglichen Einsatz verwenden bei mir den NEC-IR-Code. Das fängt beim Fernseher an, geht über vom DVD-Player zur Notebook-Fernbedienung und reicht bis zur Noname-MultiMedia-Festplatte - um nur einige Beispiele zu nennen.
Die von IRMP decodierten Protokolle haben etwas gemeinsames: Sie weisen alle ein Start-Bit auf, welches vom Timing her ausgezeichnet, d.h. einmalig ist.
Anhand dieses Start-Bit-Timings werden die verschiedenen Protokolle unterschieden. IRMP misst also das Timing des Start-Bits und stellt dann "on-thy-fly" seine Timingtabellen auf das erkannte Protokoll um, damit die nach dem Start-Bit gesandten Daten in einem Rutsch eingelesen werden können, ohne das komplette Telegramm (Frame) erst speichern zu müssen.
IRMP unterstützt folgende IR-Codings:
- Pulse Distance, typ. Beispiel: NEC, Sony
- Bi-Phase (Manchester), typ. Beispiel: RC5, RC6
- Serial (ab 1.9.5), typ. Beispiel: Netbox
Ein Puls-Distance-Protokoll erkennt man an folgenden Regeln:
- es gibt nur eine Pulslänge und zwei verschiedene Pausenlängen oder
- es gibt zwei verschiedene Pulslängen und nur eine Pausenlänge
Ein Bi-Phase-Protokoll erkennt man an:
- es kommen genau eine Pausen- und eine Pulslänge, sowie jeweils die doppelten Puls-/Pausenlängen vor
Typisches Kriterium für ein bitserielles Protokoll ist:
- es kommen Vielfache einer Grund-Puls-/Pausenlänge vor
Eine tabellarische Aufstellung der verschiedenen IR-Protokolle findet man hier: Die IR-Protokolle im Detail.
Die angegebenen Timingwerte sind Idealwerte. Bei einigen Fernbedienungen in der Praxis weichen sie um bis zu 40% voneinander ab. Deshalb arbeitet IRMP mit Minimum-/Maximumsgrenzen, um bzgl. des Zeitverhaltens tolerabel zu sein.
Download
Version 2.3.1, Stand vom 26.10.2012
Download Release-Version: Irmp.zip
IRMP & IRSND sind nun auch über SVN abrufbar: IRMP im SVN, Download Tarball
Achtung:
Die Version im SVN kann eine Zwischen- oder Test-Version sein, die nicht den hier dokumentierten Stand widerspiegelt! Im Zweifel verwendet man besser den obigen Download-Link auf Irmp.zip.
Die Software-Änderungen kann man sich hier anschauen: Software-Historie IRMP
Source-Code
Der Source-Code lässt sich einfach für AVR-µCs übersetzen, indem man unter Windows die Projekt-Datei irmp.aps in das AVR Studio 4 lädt.
Für andere Entwicklungsumgebungen ist leicht ein Projekt bzw. Makefile angelegt. Zum Source gehören:
- irmp.c - Der eigentliche IR-Decoder
- irmpprotocols.h - Sämtliche Definitionen zu den IR-Protokollen
- irmpsystem.h - Vom Zielsystem abhängige Definitionen für AVR/PIC/STM32
- irmp.h - Include-Datei für die Applikation
- irmpconfig.h - Anzupassende Konfigurationsdatei
WICHTIG
Im Applikations-Source sollte nur irmp.h per include eingefügt werden, also lediglich:
<c>
- include "irmp.h"
</c>
Alle anderen Include-Dateien werden automatisch über irmp.h "eingefügt". Siehe dazu auch die Beispieldatei main.c.
Auch auf PIC-Prozessoren ist IRMP lauffähig. Für den PIC-CCS-Compiler sind entsprechende Preprocessor-Konstanten bereits gesetzt, so dass man irmp.c direkt in der CCS-Entwicklungsumgebung verwenden kann. Lediglich eine kleine Interrupt-Routine wie
<c> void TIMER2_isr(void) {
irmp_ISR ();
} </c>
ist hinzuzufügen, wobei man den Interrupt auf 66µs (also 15kHz) stellt.
Für AVR-Prozessoren ist ein Beispiel für die Anwendung von IRMP in main.c zu finden - im wesentlichen geht es da um die Timer-Initialisierung und den Abruf der empfangenen IR-Telegramme.
Ebenso läuft IRMP mittlerweile auf STM32-Mikroprozessoren.
Die Konfiguration von IRMP wird über Parameter in irmpconfig.h vorgenommen, nämlich:
- Anzahl Interrupts pro Sekunde
- Unterstützte IR-Protokolle
- Hardware-Pin zum IR-Empfänger
- IR-Logging
Einstellungen in irmpconfig.h
IRMP decodiert sämtliche oben aufgelisteten Protokolle in einer ISR, siehe irmpconfig.h. Dafür sind einige Angaben nötig. Diese werden in irmpconfig.h eingestellt.
F_INTERRUPTS
Anzahl der Interrupts pro Sekunde. Der Wert kann zwischen 10000 und 20000 eingestellt werden.
Standardwert: <c>
- define F_INTERRUPTS 15000 // interrupts per second
</c>
IRMP_SUPPORT_xxx_PROTOCOL
Hier lässt sich einstellen, welche Protokolle von IRMP unterstützt werden sollen. Die Standardprotokolle sind bereits aktiv. Möchte man weitere Protokolle einschalten bzw. einige aus Speicherplatzgründen deaktivieren, sind die entsprechenden Werte in irmpconfig.h anzupassen.
<c> // typical protocols, disable here! Enable Remarks F_INTERRUPTS Program Space
- define IRMP_SUPPORT_SIRCS_PROTOCOL 1 // Sony SIRCS >= 10000 ~150 bytes
- define IRMP_SUPPORT_NEC_PROTOCOL 1 // NEC + APPLE >= 10000 ~300 bytes
- define IRMP_SUPPORT_SAMSUNG_PROTOCOL 1 // Samsung + Samsung32 >= 10000 ~300 bytes
- define IRMP_SUPPORT_MATSUSHITA_PROTOCOL 1 // Matsushita >= 10000 ~50 bytes
- define IRMP_SUPPORT_KASEIKYO_PROTOCOL 1 // Kaseikyo >= 10000 ~250 bytes
- define IRMP_SUPPORT_DENON_PROTOCOL 1 // DENON, Sharp >= 10000 ~250 bytes
// more protocols, enable here! Enable Remarks F_INTERRUPTS Program Space
- define IRMP_SUPPORT_RC5_PROTOCOL 0 // RC5 >= 10000 ~250 bytes
- define IRMP_SUPPORT_RC6_PROTOCOL 0 // RC6 & RC6A >= 10000 ~250 bytes
- define IRMP_SUPPORT_JVC_PROTOCOL 0 // JVC >= 10000 ~150 bytes
- define IRMP_SUPPORT_NEC16_PROTOCOL 0 // NEC16 >= 10000 ~100 bytes
- define IRMP_SUPPORT_NEC42_PROTOCOL 0 // NEC42 >= 10000 ~300 bytes
- define IRMP_SUPPORT_IR60_PROTOCOL 0 // IR60 (SDA2008) >= 10000 ~300 bytes
- define IRMP_SUPPORT_GRUNDIG_PROTOCOL 0 // Grundig >= 10000 ~300 bytes
- define IRMP_SUPPORT_SIEMENS_PROTOCOL 0 // Siemens Gigaset >= 15000 ~550 bytes
- define IRMP_SUPPORT_NOKIA_PROTOCOL 0 // Nokia >= 10000 ~300 bytes
// exotic protocols, enable here! Enable Remarks F_INTERRUPTS Program Space
- define IRMP_SUPPORT_BOSE_PROTOCOL 0 // BOSE >= 10000 ~150 bytes
- define IRMP_SUPPORT_KATHREIN_PROTOCOL 0 // Kathrein >= 10000 ~200 bytes
- define IRMP_SUPPORT_NUBERT_PROTOCOL 0 // NUBERT >= 10000 ~50 bytes
- define IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL 0 // Bang & Olufsen >= 10000 ~200 bytes
- define IRMP_SUPPORT_RECS80_PROTOCOL 0 // RECS80 (SAA3004) >= 15000 ~50 bytes
- define IRMP_SUPPORT_RECS80EXT_PROTOCOL 0 // RECS80EXT (SAA3008) >= 15000 ~50 bytes
- define IRMP_SUPPORT_THOMSON_PROTOCOL 0 // Thomson >= 10000 ~250 bytes
- define IRMP_SUPPORT_NIKON_PROTOCOL 0 // NIKON camera >= 10000 ~250 bytes
- define IRMP_SUPPORT_NETBOX_PROTOCOL 0 // Netbox keyboard >= 10000 ~400 bytes (PROTOTYPE!)
- define IRMP_SUPPORT_FDC_PROTOCOL 0 // FDC3402 keyboard >= 10000 (better 15000) ~150 bytes (~400 in combination with RC5)
- define IRMP_SUPPORT_RCCAR_PROTOCOL 0 // RC Car >= 10000 (better 15000) ~150 bytes (~500 in combination with RC5)
- define IRMP_SUPPORT_RUWIDO_PROTOCOL 0 // RUWIDO, T-Home >= 15000 ~550 bytes
- define IRMP_SUPPORT_LEGO_PROTOCOL 0 // LEGO Power RC >= 20000 ~150 bytes
</c>
Jedes von IRMP unterstützte IR-Protokoll "verbrät" ungefähr den oben angegebenen Speicher an Code. Hier kann man Optimierungen vornehmen: Zum Beispiel ist die Modulationsfrequenz von 455kHz beim B&O-Protokoll weitab von den Frequenzen, die von den anderen Protokollen verwendet werden. Hier braucht man evtl. andere IR-Empfänger, anderenfalls kann man diese Protokolle einfach deaktiveren. Zum Beispiel kann man mit einem TSOP1738 kein B&O-Protokoll (455kHz) mehr empfangen.
Ausserdem werden die Protokolle SIEMENS/FDC/RCCAR erst ab einer Scan-Frequenz von ca. 15kHz zuverlässig erkannt. Bei RECS80/REC80EXT sind es sogar 20kHz. Wenn man also diese Protokolle nutzen will, muss man F_INTERRUPTS entsprechend anpassen, sonst erscheint beim Übersetzen eine entsprechende Warnung und die entsprechenden Protokolle werden dann automatisch abgeschaltet.
IRMP_PORT_LETTER + IRMP_BIT_NUMBER
Über diese Konstanten wird der Pin am µC beschrieben, an welchem der IR-Empfänger angeschlossen ist.
Standardwert ist PORT B6: <c> /*---------------------------------------------------------------------------
* Change hardware pin here for ATMEL AVR *--------------------------------------------------------------------------- */
- if defined (ATMEL_AVR) // use PB6 as IR input on AVR
- define IRMP_PORT_LETTER B
- define IRMP_BIT_NUMBER 6
</c>
Diese beiden Werte sind an den tatsächlichen Hardware-Pin des µCs anzupassen.
Dies gilt ebenso für die STM32-µCs:
<c> /*----------------------------------------------------------------------------
* Change hardware pin here for ARM STM32 *---------------------------------------------------------------------------- */
- elif defined (ARM_STM32) // use C13 as IR input on STM32
- define IRMP_PORT_LETTER C
- define IRMP_BIT_NUMBER 13
</c>
Bei den PIC-Prozessoren gibt es lediglich die anzupassende Konstante IRMP_PIN - je nach Compiler:
<c> /*----------------------------------------------------------------------------
* Change hardware pin here for PIC C18 compiler *---------------------------------------------------------------------------- */
- elif defined (PIC_C18) // use RB4 as IR input on PIC
- define IRMP_PIN PORTBbits.RB4
/*----------------------------------------------------------------------------
* Change hardware pin here for PIC CCS compiler *---------------------------------------------------------------------------- */
- elif defined (PIC_CCS) // use PB4 as IR input on PIC
- define IRMP_PIN PIN_B4
</c>
IRMP_USE_CALLBACK
Standardwert: <c>
- define IRMP_USE_CALLBACK 0 // flag: 0 = don't use callbacks, 1 = use callbacks, default is 0
</c>
Wenn man Callbacks einschaltet, wird bei jeder Pegeländerung des Eingangs eine Callback-Funktion aufgerufen. Dies kann zum Beispiel dafür verwendet werden, das eingehende IR-Signal sichtbar zu machen, also als Signal an einem weiteren Pin auszugeben.
Hier ein Beispiel:
<c>
- define LED_PORT PORTD // LED at PD6
- define LED_DDR DDRD
- define LED_PIN 6
/*-----------------------------------------------------------------------------------------------------------------------
* Called (back) from IRMP module * This example switches a LED (which is connected to GND) *----------------------------------------------------------------------------------------------------------------------- */
void led_callback (uint8_t on) {
if (on)
{
LED_PORT &= ~(1 << LED_PIN);
}
else
{
LED_PORT |= (1 << LED_PIN);
}
}
int main () {
... irmp_init ();
LED_DDR |= (1 << LED_PIN); // LED pin to output LED_PORT |= (1 << LED_PIN); // switch LED off (active low) irmp_set_callback_ptr (led_callback);
sei (); ...
} </c>
IRMP_LOGGING
Mit IRMP_LOGGING kann das Protokollieren von eingehenden IR-Frames eingeschaltet werden.
Standardwert: <c>
- define IRMP_LOGGING 0 // 1: log IR signal (scan), 0: do not. default is 0
</c>
Weitere Erläuterungen siehe IRMP#Scannen_von_unbekannten_Protokollen
Anwendung von IRMP
Die von IRMP unterstützten Protokolle weisen Bitlängen - teilweise variabel, teilweise fest - von 12 bis 48 Bit auf. Diese werden über Preprocessor-Defines beschrieben.
IRMP trennt diese IR-Telegramme prinzipiell in 3 Bereiche:
1. ID für verwendetes Protokoll 2. Adresse bzw. Herstellercode 3. Kommando
Mittels der Funktion
irmp_get_data (IRMP_DATA * irmp_data_p)
kann man ein decodiertes Telegramm abrufen. Der Return-Wert ist 1, wenn ein Telegramm eingelesen wurde, sonst 0. Im ersten Fall werden die Struct-Members
<c>
irmp_data_p->protocol irmp_data_p->address irmp_data_p->command irmp_data_p->flags
</c>
gefüllt.
Das heisst: am Ende bekommt man dann über irmp_get_data() einfach drei Werte (Protokoll, Adresse und Kommando-Code), die man über ein if oder switch checken kann, z. B. hier eine Routine, welche die Tasten 1-9 auf einer Fernbedienung auswertet:
<c>
IRMP_DATA irmp_data;
if (irmp_get_data (&irmp_data))
{
if (irmp_data.protocol == IRMP_NEC_PROTOCOL && // NEC-Protokoll
irmp_data.address == 0x1234) // Adresse 0x1234
{
switch (irmp_data.command)
{
case 0x0001: key1_pressed(); break; // Taste 1
case 0x0002: key2_pressed(); break; // Taste 2
...
case 0x0009: key9_pressed(); break; // Taste 9
}
}
}
</c>
Hier die möglichen Werte für irmp_data.protocol, siehe auch irmpprotocols.h:
<c>
- define IRMP_SIRCS_PROTOCOL 1 // Sony
- define IRMP_NEC_PROTOCOL 2 // NEC, Pioneer, JVC, Toshiba, NoName etc.
- define IRMP_SAMSUNG_PROTOCOL 3 // Samsung
- define IRMP_MATSUSHITA_PROTOCOL 4 // Matsushita
- define IRMP_KASEIKYO_PROTOCOL 5 // Kaseikyo (Panasonic etc)
- define IRMP_RECS80_PROTOCOL 6 // Philips, Thomson, Nordmende, Telefunken, Saba
- define IRMP_RC5_PROTOCOL 7 // Philips etc
- define IRMP_DENON_PROTOCOL 8 // Denon, Sharp
- define IRMP_RC6_PROTOCOL 9 // Philips etc
- define IRMP_SAMSUNG32_PROTOCOL 10 // Samsung32: no sync pulse at bit 16, length 32 instead of 37
- define IRMP_APPLE_PROTOCOL 11 // Apple, very similar to NEC
- define IRMP_RECS80EXT_PROTOCOL 12 // Philips, Technisat, Thomson, Nordmende, Telefunken, Saba
- define IRMP_NUBERT_PROTOCOL 13 // Nubert
- define IRMP_BANG_OLUFSEN_PROTOCOL 14 // Bang & Olufsen
- define IRMP_GRUNDIG_PROTOCOL 15 // Grundig
- define IRMP_NOKIA_PROTOCOL 16 // Nokia
- define IRMP_SIEMENS_PROTOCOL 17 // Siemens, e.g. Gigaset
- define IRMP_FDC_PROTOCOL 18 // FDC keyboard
- define IRMP_RCCAR_PROTOCOL 19 // RC Car
- define IRMP_JVC_PROTOCOL 20 // JVC (NEC with 16 bits)
- define IRMP_RC6A_PROTOCOL 21 // RC6A, e.g. Kathrein, XBOX
- define IRMP_NIKON_PROTOCOL 22 // Nikon
- define IRMP_RUWIDO_PROTOCOL 23 // Ruwido, e.g. T-Home Mediareceiver
- define IRMP_IR60_PROTOCOL 24 // IR60 (SDA2008)
- define IRMP_KATHREIN_PROTOCOL 25 // Kathrein
- define IRMP_NETBOX_PROTOCOL 26 // Netbox keyboard (bitserial)
- define IRMP_NEC16_PROTOCOL 27 // NEC with 16 bits (incl. sync)
- define IRMP_NEC42_PROTOCOL 28 // NEC with 42 bits
- define IRMP_LEGO_PROTOCOL 29 // LEGO Power Functions RC
- define IRMP_THOMSON_PROTOCOL 30 // Thomson
- define IRMP_BOSE_PROTOCOL 31 // BOSE
</c>
Die Werte für die Adresse und das Kommando muss man natürlich einmal für eine unbekannte Fernbedienung auslesen und dann über ein UART oder LC-Display ausgeben, um sie dann im Programm hart zu kodieren. Oder man hat eine kleine Anlernroutine, wo man einmal die gewünschten Tasten drücken muss, um sie anschließend im EEPROM abzuspeichern. Ein Beispiel dazu findet man im Artikel Lernfähige IR-Fernbedienung mit IRMP.
Eine weitere Beispiel-Main-Funktion ist im Zip-File enthalten, da sieht man dann auch die Initialisierung des Timers.
"Entprellen" von Tasten
Um zu unterscheiden, ob eine Taste lange gedrückt wurde oder lediglich einzeln, dient das Bit IRMP_FLAG_REPETITION. Dieses wird im Struct-Member flags gesetzt, wenn eine Taste auf der Fernbedienung längere Zeit gedrückt wurde und dadurch immer wieder dasselbe Kommando innerhalb kurzer Zeitabstände ausgesandt wird.
Beispiel:
<c>
if (irmp_data.flags & IRMP_FLAG_REPETITION)
{
// Benutzer hält die Taste länger runter
// entweder:
// ich ignoriere die (Wiederholungs-)Taste
// oder:
// ich benutze diese Info, um einen Repeat-Effekt zu nutzen
}
else
{
// Es handelt sich um eine neue Taste
}
</c>
Dies kann zum Beispiel dafür genutzt werden, um die Tasten 0-9 zu "entprellen", indem man Kommandos mit gesetztem Bit IRMP_FLAG_REPETITION ignoriert. Bei dem Drücken auf die Tasten VOLUME+ oder VOLUME- kann die wiederholte Auswertung ein und desselben Kommandos aber durchaus gewünscht sein - zum Beispiel, um LEDs zu faden.
Wenn man nur Einzeltasten auswerten will, kann man obigen IF-Block reduzieren auf:
<c>
if (! (irmp_data.flags & IRMP_FLAG_REPETITION))
{
// Es handelt sich um eine neue Taste
// ACTION!
}
</c>
Arbeitsweise
Das "Working Horse" von IRMP ist die Interrupt Service Routine irmp_ISR() welche 15.000 mal pro Sekunde aufgerufen werden sollte. Weicht dieser Wert ab, muss die Preprocessor-Konstante F_INTERRUPTS in irmpconfig.h angepasst werden. Der Wert kann zwischen 10kHz und 20kHz eingestellt werden.
irmp_ISR detektiert zunächst die Länge und die Form des/der Startbits und ermittelt daraus das verwendete Protokoll. Sobald das Protokoll erkannt wurde, werden die weiter einzulesenden Bits parametrisiert, um dann möglichst effektiv in den weiteren Aufrufen das komplette IR-Telegramm einzulesen.
Um direkt Kritikern den Wind aus den Segeln zu nehmen:
Ich weiss, die ISR ist ziemlich groß. Aber da sie sich wie eine State Machine verhält, ist der tatsächlich ausgeführte Code pro Durchlauf relativ gering. Solange es "dunkel" ist (und das ist es ja die meiste Zeit ;-)) ist die aufgewendete Zeit sogar verschwindend gering. Im WordClock-Projekt werden mit ein- und demselben Timer 8 ISRs aufgerufen, davon ist die irmp_ISR() nur eine unter vielen. Bei mindestens 8 MHz CPU-Takt traten bisher keine Timing-Probleme auf. Daher sehe ich bei der Länge von irmp_ISR überhaupt kein Problem.
Ein Quarz ist nicht unbedingt notwendig, es funktioniert auch mit dem internen Oszillator des AVRs, wenn man die Prescaler-Fuse entsprechend gesetzt hat, dass die CPU auch mit 8MHz rennt ... Die Fuse-Werte für einen ATMEGA88 findet man in main.c.
Scannen von unbekannten Protokollen
Stellt man in irmpconfig.h in der Zeile
<c>
#define IRMP_LOGGING 0 // 1: log IR signal (scan), 0: do not (default)
</c>
den Wert für IRMP_LOGGING auf 1, wird in IRMP eine Protokollierung eingeschaltet: Es werden dann die Hell- und Dunkelphase auf dem UART des Microntrollers mit 9600Bd ausgegeben: 1=Dunkel, 0=Hell. Eventuell müssen dann die Konstanten in den Funktionen uart_init() und uart_putc() angepasst werden; das kommt auf den verwendeten AVR-µC an.
Hinweis: Die IRMP-Logging-Funktion (insb. die Ausgabe über UART) ist nicht für PIC-Prozessoren angepasst. Wer immer dies tun möchte, kann sich gerne bei mir (Benutzer ukw) per PN melden.
Nimmt man diese Protokoll-Scans mit einem Terminal-Emulationsprogramm auf und speichert sie dann als normale Datei ab, kann man diese Scan-Dateien zur Analyse verwenden, um damit IRMP an das unbekannte Protokoll anzupassen - siehe nächstes Kapitel.
Wer eine Fernbedienung hat, die nicht von IRMP unterstützt wird, kann mir (ukw) gern die Scan-Dateien zuschicken. Ich schaue dann, ob das Protokoll in das IRMP-Konzept passt und passe gegebenenfalls den Source an.
IRMP unter Linux und Windows
irmp.c lässt sich auch unter Linux direkt kompilieren, um damit Infrarot-Scans, welche in Dateien gespeichert sind, direkt zu testen. Im Unterordner IR-Data finden sich solche Dateien, die man dem IRMP direkt zum "Fraß" vorwerfen kann.
Das Übersetzen von IRMP geht folgendermaßen:
make -f makefile.lnx
Dabei werden 3 IRMP-Versionen erzeugt:
- irmp: Version für 10kHz Scans
- irmp-15kHz: Version für 15kHz Scans
- irmp-20kHz: Version für 20kHz Scans
Der Aufruf geschieht dann über:
./irmp [-l|-p|-a|-v] < scan-file
Die angegebenen Optionen schließen sich aus, das heisst, es kann jeweils nur eine Option zu einer Zeit angegeben werden:
Option:
-l List gibt eine Liste der Pulse und Pausen aus -a analyze analysiert die Puls-/Pausen und schreibt ein "Spektrum" in ASCII-Form -v verbose ausführliche Ausgabe -p Print Timings gibt für alle Protokolle eine Timing-Tabelle aus
Beispiele:
Normale Ausgabe:
./irmp < IR-Data/orion_vcr_07660BM070.txt
<c>
------------------------------------------------------------------------- # Taste 1 00000001110111101000000001111111 p = 2, a = 0x7b80, c = 0x0001, f = 0x00 ------------------------------------------------------------------------- # Taste 2 00000001110111100100000010111111 p = 2, a = 0x7b80, c = 0x0002, f = 0x00 ------------------------------------------------------------------------- # Taste 3 00000001110111101100000000111111 p = 2, a = 0x7b80, c = 0x0003, f = 0x00 ------------------------------------------------------------------------- # Taste 4 00000001110111100010000011011111 p = 2, a = 0x7b80, c = 0x0004, f = 0x00 ------------------------------------------------------------------------- ...
</c>
Listen-Ausgabe:
./irmp -l < IR-Data/orion_vcr_07660BM070.txt
<c>
- Taste 1
pulse: 91 pause: 44 pulse: 6 pause: 5 pulse: 6 pause: 6 pulse: 6 pause: 5 pulse: 6 pause: 5 pulse: 6 pause: 5 pulse: 6 pause: 6 pulse: 6 pause: 5 pulse: 6 pause: 16 ... </c>
Analyse:
./irmp -a < IR-Data/orion_vcr_07660BM070.txt
<c>
START PULSES:
90 o 1 91 oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo 33 92 ooo 2
pulse avg: 91.0=9102.8 us, min: 90=9000.0 us, max: 92=9200.0 us, tol: 1.1%
START PAUSES:
43 oo 1 44 oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo 25 45 oooooooooooooooooooooooo 10
pause avg: 44.2=4425.0 us, min: 43=4300.0 us, max: 45=4500.0 us, tol: 2.8%
PULSES:
5 o 17 6 ooooooooooooooooooooooooooooooooooooooooooooooooooooooo 562 7 oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo 609
pulse avg: 6.5= 649.8 us, min: 5= 500.0 us, max: 7= 700.0 us, tol: 23.1%
PAUSES:
4 ooooooooooooooooooooooo 169 5 oooooooooooooooooooooooooooooooooooooooooooooooooooooooooo 412 6 oooo 31
pause avg: 4.8= 477.5 us, min: 4= 400.0 us, max: 6= 600.0 us, tol: 25.7%
15 oooooo 43 16 oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo 425 17 oooooooooo 72
pause avg: 16.1=1605.4 us, min: 15=1500.0 us, max: 17=1700.0 us, tol: 6.6%
</c>
Hier sieht man die gemessenen Zeiten aller Pulse und Pausen als (liegende) Glockenkurven, welche natürlich wegen der ASCII-Darstellung nicht gerade einer Idealkurve entsprechen. Je schmaler die gemessenen Kanäle, desto besser ist das Timing der Fernbedienung.
Aus obigem Output kann man herauslesen:
- Das Start-Bit hat eine Pulslänge zwischen 9000 und 9200 usec, im Mittel sind es 9102 usec. Die Abweichung von diesem Mittelwert liegt bei 1,1 Prozent.
- Das Start-Bit hat eine Pausenlänge zwischen 4300 usec und 4500 usec, der Mittelwert beträgt 4424 usec. Der Fehler liegt bei 2,8 Prozent.
- Die Pulslänge eines Datenbits liegt zwischen 500 usec und 700 usec, im Mittel sind es 650 usec, der Fehler liegt bei (stolzen) 23,1 Prozent!
Desweiteren gibt es noch 2 verschieden lange Pausen (für die Bits 0 und 1), das Ablesen der Werte überlasse ich dem geneigten Leser ;-)
Ausführliche Ausgabe:
./irmp -v < IR-Data/orion_vcr_07660BM070.txt
<c>
- Taste 1
26084 [starting pulse]
start-bit: pulse = 91, pause = 44 protocol = NEC, start bit timings: pulse: 53 - 127, pause: 26 - 64 pulse_1: 2 - 9 pause_1: 9 - 25 pulse_0: 2 - 9 pause_0: 2 - 9 command_offset: 16 command_len: 16 complete_len: 32 stop_bit: 1
26230 [bit 0: pulse = 6, pause = 5] 0 26242 [bit 1: pulse = 6, pause = 6] 0 26253 [bit 2: pulse = 6, pause = 5] 0 26264 [bit 3: pulse = 6, pause = 5] 0 ... 26749 [bit 31: pulse = 6, pause = 17] 1
stop bit detected code detected, length = 32 p = 2, a = 0x7b80, c = 0x0001, f = 0x00
</c>
Timing-Tabelle:
./irmp -p
<c> IRMP_TIMEOUT_LEN: 165 IRMP_KEY_REPETITION_LEN 1500
PROTOCOL S S-PULSE S-PAUSE PULSE-0 PAUSE-0 PULSE-1 PAUSE-1
========================================================================
SIRCS 1 21 - 27 4 - 7 4 - 8 4 - 8 10 - 14 4 - 8 NEC 1 53 - 127 26 - 64 2 - 9 2 - 9 2 - 9 9 - 25 NEC (rep) 1 53 - 127 13 - 32 2 - 9 2 - 9 2 - 9 9 - 25 SAMSUNG 1 40 - 51 40 - 51 3 - 8 2 - 7 3 - 8 9 - 20 MATSUSHITA 1 27 - 43 27 - 43 4 - 13 4 - 13 4 - 13 15 - 38 KASEIKYO 1 29 - 38 14 - 20 1 - 8 1 - 7 1 - 8 5 - 20 RECS80 1 1 - 3 66 - 83 0 - 3 43 - 55 0 - 3 66 - 83 RC5 1 7 - 11 7 - 11 7 - 11 DENON 1 1 - 4 1 - 4 6 - 10 1 - 4 16 - 22 RC6 1 23 - 30 7 - 11 3 - 6 RECS80EXT 1 1 - 3 34 - 39 0 - 3 43 - 55 0 - 3 66 - 83 NUBERT 1 10 - 17 2 - 5 3 - 7 9 - 17 10 - 17 2 - 5 BANG_OLUFSEN 1 1 - 3 27 - 35 BANG_OLUFSEN 2 1 - 3 27 - 35 BANG_OLUFSEN 3 1 - 3 140 - 165 BANG_OLUFSEN 4 1 - 3 27 - 35 BANG_OLUFSEN - 1 - 3 27 - 35 1 - 3 83 - 104 GRUNDIG/NOKIA 1 3 - 7 22 - 33 3 - 7 SIEMENS 1 2 - 4 2 - 4 2 - 4 FDC 1 18 - 24 8 - 12 1 - 5 1 - 3 1 - 5 5 - 10 RCCAR 1 17 - 23 17 - 23 4 - 8 5 - 13 4 - 8 2 - 7 </c>
Bei längeren Ausgaben sollte man das Programm "less" verwenden, um seitenweise zu blättern, z.B.:
./irmp -v < IR-Data/Samsung_DVD_Rec_00062C.txt | less
Diese Scan-Dateien halfen mir nicht nur bei der Entwicklung des IRMP, sondern können auch bei der Anpassung des Sources an neue IR-Protokolle sehr hilfreich sein.
Mittlerweile kann man IRMP auch unter Windows nutzen, nämlich folgendermaßen:
- Eingabeaufforderung starten
- In das Verzeichnis irmp wechseln
- Aufruf von:
irmp.exe < IR-Data\rc5x.txt
Da manche Ausgaben sehr lang werden, empfiehlt es sich auch hier, die Ausgabe in eine Datei zu lenken oder in den more weiterzuleiten, damit man seitenweise blättern kann:
irmp.exe < IR-Data\rc5x.txt | more
Auch hier gelten dieselben Optionen wie für die Linux-Version.
Zusatz:
Der Decoder für das RECS80- und RECS80-Extended-Protokoll ist ungetestet, wurde anhand von Dokumentationen im Internet erstellt und lediglich mittels künstlich erzeugten Scan-Dateien getestet... daher: keine Gewähr!
Fernbedienungen
| Protokoll | Bezeichnung | Gerät | Device Address |
|---|---|---|---|
| NEC | Toshiba CT-9859 | Fernseher | 24384 |
| Toshiba VT-728G | V-728G Videorekorder | 23364 | |
| Elta 8848 MP 4 | DVD-Player | 32512 | |
| AS-218 | Askey TV-View CHP03X (TV-Karte) | 15238 | |
| Cyberhome ??? | Cyberhome DVD Player | 28018 | |
| WD TV Life | Western Digital Multimediaplayer | 7984 | |
| NEC16 | Daewoo | Videorekorder | 21 |
| KASEIKYO | Technics EUR646497 | AV Receiver SA-AX 730 | 8194 |
| RC5 | Loewe Assist/RC3/RC4 | Fernseher (FB auf TV-Mode) | 0 |
| RC6 | Philips Television | Fernseher (FB auf TV-Mode) | 0 |
| SIRCS | Sony RM-816 | Fernseher (FB auf TV-Mode) | 0 (siehe Beschreibung) |
| DENON | DENON RC970 | AVR3805 (Verstärker) | 8 |
| DENON RC970 | DVD/CD-Player | 2 | |
| DENON RC970 | Tuner | 6 | |
| SAMSUNG32 | Samsung AA59-00484A | LE40D550 Fernseher | 1799 |
IR-Tastaturen
IRMP unterstützt ab Version 1.7.0 auch IR-Tastaturen, nämlich die Infrarot-Tastatur FDC-3402 - erhältlich bei Pollin (Art. 711 056) für weniger als 2 EUR.
Beim Erkennen einer Taste gibt IRMP folgende Daten zurück:
Protokoll-Nummer (irmp_data.protocol): 18 Addresse (irmp_data.address): 0x003F
Als Kommando (irmp_data.command) werden folgende Werte zurückgeliefert:
| Code | Taste | Code | Taste | Code | Taste | Code | Taste | Code | Taste | Code | Taste | Code | Taste | Code | Taste |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0x0000 | 0x0010 | TAB | 0x0020 | 's' | 0x0030 | 'c' | 0x0040 | 0x0050 | HOME | 0x0060 | 0x0070 | MENUE | |||
| 0x0001 | '^' | 0x0011 | 'q' | 0x0021 | 'd' | 0x0031 | 'v' | 0x0041 | 0x0051 | END | 0x0061 | 0x0071 | BACK | ||
| 0x0002 | '1' | 0x0012 | 'w' | 0x0022 | 'f' | 0x0032 | 'b' | 0x0042 | 0x0052 | 0x0062 | 0x0072 | FORWARD | |||
| 0x0003 | '2' | 0x0013 | 'e' | 0x0023 | 'g' | 0x0033 | 'n' | 0x0043 | 0x0053 | UP | 0x0063 | 0x0073 | ADDRESS | ||
| 0x0004 | '3' | 0x0014 | 'r' | 0x0024 | 'h' | 0x0034 | 'm' | 0x0044 | 0x0054 | DOWN | 0x0064 | 0x0074 | WINDOW | ||
| 0x0005 | '4' | 0x0015 | 't' | 0x0025 | 'j' | 0x0035 | ',' | 0x0045 | 0x0055 | PAGE_UP | 0x0065 | 0x0075 | 1ST_PAGE | ||
| 0x0006 | '5' | 0x0016 | 'z' | 0x0026 | 'k' | 0x0036 | '.' | 0x0046 | 0x0056 | PAGE_DOWN | 0x0066 | 0x0076 | STOP | ||
| 0x0007 | '6' | 0x0017 | 'u' | 0x0027 | 'l' | 0x0037 | '-' | 0x0047 | 0x0057 | 0x0067 | 0x0077 | ||||
| 0x0008 | '7' | 0x0018 | 'i' | 0x0028 | 'ö' | 0x0038 | 0x0048 | 0x0058 | 0x0068 | 0x0078 | FAVORITES | ||||
| 0x0009 | '8' | 0x0019 | 'o' | 0x0029 | 'ä' | 0x0039 | SHIFT_RIGHT | 0x0049 | 0x0059 | RIGHT | 0x0069 | 0x0079 | NEW_PAGE | ||
| 0x000A | '9' | 0x001A | 'p' | 0x002A | '#' | 0x003A | CTRL | 0x004A | 0x005A | 0x006A | 0x007A | SETUP | |||
| 0x000B | '0' | 0x001B | 'ü' | 0x002B | CR | 0x003B | 0x004B | INSERT | 0x005B | 0x006B | 0x007B | FONT | |||
| 0x000C | 'ß' | 0x001C | '+' | 0x002C | SHIFT_LEFT | 0x003C | ALT_LEFT | 0x004C | DELETE | 0x005C | 0x006C | 0x007C | |||
| 0x000D | '´' | 0x001D | 0x002D | '<' | 0x003D | SPACE | 0x004D | 0x005D | 0x006D | 0x007D | |||||
| 0x000E | 0x001E | CAPSLOCK | 0x002E | 'y' | 0x003E | ALT_RIGHT | 0x004E | 0x005E | 0x006E | ESCAPE | 0x007E | ON_OFF | |||
| 0x000F | BACKSPACE | 0x001F | 'a' | 0x002F | 'x' | 0x003F | 0x004F | LEFT | 0x005F | 0x006F | 0x007F |
Zusatztasten links:
| Code | Taste |
|---|---|
| 0x0400 | KEY_MOUSE_1 |
| 0x0800 | KEY_MOUSE_2 |
Dabei gelten die obigen Werte für das Drücken einer Taste. Wird die Taste wieder losgelassen, setzt IRMP zusätzlich das 8. Bit im Kommando.
Beispiel:
Taste 'a' drücken: 0x001F
Taste 'a' loslassen: 0x009F
Ausnahme ist die EIN/AUS-Taste: Diese sendet nur beim Drücken einen Code, nicht beim Loslassen.
Wird eine Taste länger gedrückt, wird das in irmp_data.flag angezeigt.
Beispiel:
command flag
Taste 'a' drücken: 0x001F 0x00
Taste 'a' drücken: 0x001F 0x01
Taste 'a' drücken: 0x001F 0x01
Taste 'a' drücken: 0x001F 0x01
....
Taste 'a' loslassen: 0x009F 0x00
Werden Tastenkombinationen (zum Beispiel für ein großes 'A') gedrückt, dann sind die Rückgabewerte von IRMP in folgendem Ablauf zu sehen:
Linke SHIFT-Taste drücken: 0x0002
Taste 'a' drücken: 0x001F
Taste 'a' loslassen: 0x009F
Linke SHIFT-Taste loslassen: 0x0082
In irmp.c findet man für die LINUX-Version eine Funktion get_fdc_key(), welche als Vorlage dienen mag, die Keycodes einer FDC-Tastatur in die entsprechenden ASCII-Codes umzuwandeln. Diese Funktion kann man entweder lokal auf dem µC nutzen, um die Keycodes zu decodieren, oder auf einem Hostsystem (z.B. PC), an welches die IRMP-Data-Struktur gesandt wird. Dafür sollte man die Funktion incl. der dazugehörenden Preprozessor-Konstanten in seinen Applikations-Quelltext kopieren.
Hier der entsprechende Auszug: <c>
- define STATE_LEFT_SHIFT 0x01
- define STATE_RIGHT_SHIFT 0x02
- define STATE_LEFT_CTRL 0x04
- define STATE_LEFT_ALT 0x08
- define STATE_RIGHT_ALT 0x10
- define KEY_ESCAPE 0x1B // keycode = 0x006e
- define KEY_MENUE 0x80 // keycode = 0x0070
- define KEY_BACK 0x81 // keycode = 0x0071
- define KEY_FORWARD 0x82 // keycode = 0x0072
- define KEY_ADDRESS 0x83 // keycode = 0x0073
- define KEY_WINDOW 0x84 // keycode = 0x0074
- define KEY_1ST_PAGE 0x85 // keycode = 0x0075
- define KEY_STOP 0x86 // keycode = 0x0076
- define KEY_MAIL 0x87 // keycode = 0x0077
- define KEY_FAVORITES 0x88 // keycode = 0x0078
- define KEY_NEW_PAGE 0x89 // keycode = 0x0079
- define KEY_SETUP 0x8A // keycode = 0x007a
- define KEY_FONT 0x8B // keycode = 0x007b
- define KEY_PRINT 0x8C // keycode = 0x007c
- define KEY_ON_OFF 0x8E // keycode = 0x007c
- define KEY_INSERT 0x90 // keycode = 0x004b
- define KEY_DELETE 0x91 // keycode = 0x004c
- define KEY_LEFT 0x92 // keycode = 0x004f
- define KEY_HOME 0x93 // keycode = 0x0050
- define KEY_END 0x94 // keycode = 0x0051
- define KEY_UP 0x95 // keycode = 0x0053
- define KEY_DOWN 0x96 // keycode = 0x0054
- define KEY_PAGE_UP 0x97 // keycode = 0x0055
- define KEY_PAGE_DOWN 0x98 // keycode = 0x0056
- define KEY_RIGHT 0x99 // keycode = 0x0059
- define KEY_MOUSE_1 0x9E // keycode = 0x0400
- define KEY_MOUSE_2 0x9F // keycode = 0x0800
static uint8_t get_fdc_key (uint16_t cmd) {
static uint8_t key_table[128] =
{
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0, '^', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'ß', '´', 0, '\b',
'\t','q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 'ü', '+', 0, 0, 'a',
's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ö', 'ä', '#', '\r', 0, '<', 'y', 'x',
'c', 'v', 'b', 'n', 'm', ',', '.', '-', 0, 0, 0, 0, 0, ' ', 0, 0,
0, '°', '!', '"', '§', '$', '%', '&', '/', '(', ')', '=', '?', '`', 0, '\b',
'\t','Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', 'Ü', '*', 0, 0, 'A',
'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Ö', 'Ä', '\,'\r', 0, '>', 'Y', 'X',
'C', 'V', 'B', 'N', 'M', ';', ':', '_', 0, 0, 0, 0, 0, ' ', 0, 0
};
static uint8_t state;
uint8_t key = 0;
switch (cmd)
{
case 0x002C: state |= STATE_LEFT_SHIFT; break; // pressed left shift
case 0x00AC: state &= ~STATE_LEFT_SHIFT; break; // released left shift
case 0x0039: state |= STATE_RIGHT_SHIFT; break; // pressed right shift
case 0x00B9: state &= ~STATE_RIGHT_SHIFT; break; // released right shift
case 0x003A: state |= STATE_LEFT_CTRL; break; // pressed left ctrl
case 0x00BA: state &= ~STATE_LEFT_CTRL; break; // released left ctrl
case 0x003C: state |= STATE_LEFT_ALT; break; // pressed left alt
case 0x00BC: state &= ~STATE_LEFT_ALT; break; // released left alt
case 0x003E: state |= STATE_RIGHT_ALT; break; // pressed left alt
case 0x00BE: state &= ~STATE_RIGHT_ALT; break; // released left alt
case 0x006e: key = KEY_ESCAPE; break;
case 0x004b: key = KEY_INSERT; break;
case 0x004c: key = KEY_DELETE; break;
case 0x004f: key = KEY_LEFT; break;
case 0x0050: key = KEY_HOME; break;
case 0x0051: key = KEY_END; break;
case 0x0053: key = KEY_UP; break;
case 0x0054: key = KEY_DOWN; break;
case 0x0055: key = KEY_PAGE_UP; break;
case 0x0056: key = KEY_PAGE_DOWN; break;
case 0x0059: key = KEY_RIGHT; break;
case 0x0400: key = KEY_MOUSE_1; break;
case 0x0800: key = KEY_MOUSE_2; break;
default:
{
if (!(cmd & 0x80)) // pressed key
{
if (cmd >= 0x70 && cmd <= 0x7F) // function keys
{
key = cmd + 0x10; // 7x -> 8x
}
else if (cmd < 64) // key listed in key_table
{
if (state & (STATE_LEFT_ALT | STATE_RIGHT_ALT))
{
switch (cmd)
{
case 0x0003: key = '²'; break;
case 0x0008: key = '{'; break;
case 0x0009: key = '['; break;
case 0x000A: key = ']'; break;
case 0x000B: key = '}'; break;
case 0x000C: key = '\\'; break;
case 0x001C: key = '~'; break;
case 0x002D: key = '|'; break;
case 0x0034: key = 'µ'; break;
}
}
else if (state & (STATE_LEFT_CTRL))
{
if (key_table[cmd] >= 'a' && key_table[cmd] <= 'z')
{
key = key_table[cmd] - 'a' + 1;
}
else
{
key = key_table[cmd];
}
}
else
{
int idx = cmd + ((state & (STATE_LEFT_SHIFT | STATE_RIGHT_SHIFT)) ? 64 : 0);
if (key_table[idx])
{
key = key_table[idx];
}
}
}
}
break;
}
}
return (key);
} </c>
Als letztes noch ein Beispiel einer Anwendung der Funktion get_fdc_key():
<c>
if (irmp_get_data (&irmp_data))
{
uint8_t key;
if (irmp_data.protocol == IRMP_FDC_PROTOCOL &&
(key = get_fdc_key (irmp_data.command)) != 0)
{
if ((key >= 0x20 && key < 0x7F) || key >= 0xA0) // show only printable characters
{
printf ("ascii-code = 0x%02x, character = '%c'\n", key, key);
}
else // it's a non-printable key
{
printf ("ascii-code = 0x%02x\n", key);
}
}
}
</c>
Alle nicht-druckbaren Zeichen werden dabei folgendermaßen codiert:
| Taste | Konstante | Wert |
|---|---|---|
| ESC | KEY_ESCAPE | 0x1B |
| Menü | KEY_MENUE | 0x80 |
| Zurück | KEY_BACK | 0x81 |
| Vorw. | KEY_FORWARD | 0x82 |
| Adresse | KEY_ADDRESS | 0x83 |
| Fenster | KEY_WINDOW | 0x84 |
| 1. Seite | KEY_1ST_PAGE | 0x85 |
| Stop | KEY_STOP | 0x86 |
| KEY_MAIL | 0x87 | |
| Fav. | KEY_FAVORITES | 0x88 |
| Neue Seite | KEY_NEW_PAGE | 0x89 |
| Setup | KEY_SETUP | 0x8A |
| Schrift | KEY_FONT | 0x8B |
| Druck | KEY_PRINT | 0x8C |
| Ein/Aus | KEY_ON_OFF | 0x8E |
| Backspace | '\b' | 0x08 |
| CR/ENTER | '\r' | 0x0C |
| TAB | '\t' | 0x09 |
| Einfg | KEY_INSERT | 0x90 |
| Entf | KEY_DELETE | 0x91 |
| Cursor links | KEY_LEFT | 0x92 |
| Pos1 | KEY_HOME | 0x93 |
| Ende | KEY_END | 0x94 |
| Cursor rechts | KEY_UP | 0x95 |
| Cursor runter | KEY_DOWN | 0x96 |
| Bild hoch | KEY_PAGE_UP | 0x97 |
| Bild runter | KEY_PAGE_DOWN | 0x98 |
| Cursor links | KEY_RIGHT | 0x99 |
| Linke Maustaste | KEY_MOUSE_1 | 0x9E |
| Rechte Maustaste | KEY_MOUSE_2 | 0x9F |
Die Funktion get_fdc_key berücksichtigt das Gedrückthalten der Shift-, Strg- und ALT-Tasten. Damit funktioniert nicht nur das Schreiben von Großbuchstaben, sondern auch das Auswählen der Sonderzeichen mit der Tastenkombination ALT + Taste, z.B. ALT + m = µ oder ALT + q = @. Ebenso kann man mit der Strg-Taste die Control-Zeichen CTRL-A bis CTRL-Z senden. Die CapsLock-Taste wird ignoriert, da ich sie sowieso für die überflüssigste Taste überhaupt halte ;-)
IRSND - Infrarot-Multiprotokoll-Encoder
Einleitung IRSND
IRSND ist das Gegenstück zu IRMP: es reproduziert aus den Daten, die mit IRMP empfangen wurden, wieder den Original Frame, der dann über eine Infrarot-Diode ausgegeben werden kann.
IRSND ist lauffähig auf folgenden AVR µCs:
- ATtiny87, ATtiny167
- ATtiny45, ATtiny85
- ATtiny84
- ATmega8, ATmega16, ATmega32
- ATmega162
- ATmega164, ATmega324, ATmega644, ATmega644P, ATmega1284
- ATmega88, ATmega88P, ATmega168, ATmega168P, ATmega328P
IRSND unterstützt die folgenden Protokolle:
- SIRCS
- NEC
- SAMSUNG
- SAMSUNG32
- MATSUSHITA
- RC5
- KASEIKYO
- DENON
- JVC
- APPLE
- NUBERT
- BANG_OLUFSEN
- GRUNDIG
- NOKIA
- SIEMENS (bei mind. ~15kHz)
- FDC (bei mind. ~15kHz)
- RCCAR (bei mind. ~15kHz)
- RECS80 (bei mind. ~20kHz)
- RECS80EXT (bei mind. ~20kHz)
- NIKON
- RC6
- RC6A
- THOMSON
- NEC16
- NEC42
- LEGO
- IR60 (NEU)
Download IRSND
Version 2.3.1, Stand vom 26.10.2012
Download Release-Version: Irsnd.zip
IRMP & IRSND sind nun auch über SVN abrufbar: IRMP im SVN
Achtung:
Die Version im SVN kann eine Zwischen- oder Test-Version sein, die nicht den hier dokumentierten Stand widerspiegelt! Im Zweifel verwendet man besser den obigen Download auf Irsnd.zip.
Die Software-Änderungen kann man sich hier anschauen: Software-Historie IRSND
Source-Code IRSND
Der Source-Code lässt sich einfach übersetzen, indem man unter Windows die Projekt-Datei irsnd.aps in das AVRStudio 4 lädt.
Auch für andere Entwicklungsumgebungen lässt sich leicht ein Projekt bzw. Makefile zusammenstellen. Zum IRSND-Source gehören folgende Dateien:
- irsnd.c - Der eigentliche IR-Encoder
- irmpprotocols.h - Sämtliche Definitionen zu den IR-Protokollen
- irmpsystem.h - Vom Zielsystem abhängige Definitionen für AVR/PIC/STM32
- irsnd.h - Include-Datei für die Applikation
- irsndconfig.h - Anzupassende Konfigurationsdatei
WICHTIG:
Im Applikations-Source sollte nur irsnd.h per include eingefügt werden, also lediglich:
<c>
- include "irsnd.h"
</c>
Alle anderen Include-Dateien werden automatisch über irsnd.h "eingefügt". Siehe dazu auch die Beispieldatei irsndmain.c.
IRSND encodiert sämtliche oben aufgelisteten Protokolle in einer ISR, siehe irsnd.c.
Einstellungen in irsndconfig.h
F_INTERRUPTS
Anzahl der Interrupts pro Sekunde. Der Wert kann zwischen 10000 und 20000 eingestellt werden.
Standardwert: <c>
- define F_INTERRUPTS 15000 // interrupts per second
</c>
IRSND_SUPPORT_xxx_PROTOCOL
Hier lässt sich einstellen, welche Protokolle von IRSND unterstützt werden sollen. Die Standardprotokolle sind bereits aktiv. Möchte man weitere Protokolle einschalten bzw. einige aus Speicherplatzgründen deaktivieren, sind die entsprechenden Werte in irsndconfig.h anzupassen.
<c> // typical protocols, disable here! Enable Remarks F_INTERRUPTS Program Space
- define IRSND_SUPPORT_SIRCS_PROTOCOL 1 // Sony SIRCS >= 10000 ~150 bytes
- define IRSND_SUPPORT_NEC_PROTOCOL 1 // NEC + APPLE >= 10000 ~100 bytes
- define IRSND_SUPPORT_SAMSUNG_PROTOCOL 1 // Samsung + Samsung32 >= 10000 ~300 bytes
- define IRSND_SUPPORT_MATSUSHITA_PROTOCOL 1 // Matsushita >= 10000 ~200 bytes
- define IRSND_SUPPORT_KASEIKYO_PROTOCOL 1 // Kaseikyo >= 10000 ~150 bytes
- define IRSND_SUPPORT_DENON_PROTOCOL 1 // DENON, Sharp >= 10000 ~200 bytes
// more protocols, enable here! Enable Remarks F_INTERRUPTS Program Space
- define IRSND_SUPPORT_RC5_PROTOCOL 0 // RC5 >= 10000 ~150 bytes
- define IRSND_SUPPORT_RC6_PROTOCOL 0 // RC6 >= 10000 ~250 bytes
- define IRSND_SUPPORT_RC6A_PROTOCOL 0 // RC6A >= 10000 ~250 bytes
- define IRSND_SUPPORT_JVC_PROTOCOL 0 // JVC >= 10000 ~150 bytes
- define IRSND_SUPPORT_NEC16_PROTOCOL 0 // NEC16 >= 10000 ~150 bytes
- define IRSND_SUPPORT_NEC42_PROTOCOL 0 // NEC42 >= 10000 ~150 bytes
- define IRSND_SUPPORT_IR60_PROTOCOL 0 // IR60 (SDA2008) >= 10000 DON'T CHANGE, NOT SUPPORTED YET!
- define IRSND_SUPPORT_GRUNDIG_PROTOCOL 0 // Grundig >= 10000 ~300 bytes
- define IRSND_SUPPORT_SIEMENS_PROTOCOL 0 // Siemens, Gigaset >= 15000 ~150 bytes
- define IRSND_SUPPORT_NOKIA_PROTOCOL 0 // Nokia >= 10000 ~400 bytes
// exotic protocols, enable here! Enable Remarks F_INTERRUPTS Program Space
- define IRSND_SUPPORT_KATHREIN_PROTOCOL 0 // Kathrein >= 10000 DON'T CHANGE, NOT SUPPORTED YET!
- define IRSND_SUPPORT_NUBERT_PROTOCOL 0 // NUBERT >= 10000 ~100 bytes
- define IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL 0 // Bang&Olufsen >= 10000 ~250 bytes
- define IRSND_SUPPORT_RECS80_PROTOCOL 0 // RECS80 >= 20000 ~100 bytes
- define IRSND_SUPPORT_RECS80EXT_PROTOCOL 0 // RECS80EXT >= 20000 ~100 bytes
- define IRSND_SUPPORT_THOMSON_PROTOCOL 0 // Thomson >= 10000 ~250 bytes
- define IRSND_SUPPORT_NIKON_PROTOCOL 0 // NIKON >= 10000 ~150 bytes
- define IRSND_SUPPORT_NETBOX_PROTOCOL 0 // Netbox keyboard >= 10000 DON'T CHANGE, NOT SUPPORTED YET!
- define IRSND_SUPPORT_FDC_PROTOCOL 0 // FDC IR keyboard >= 10000 (better 15000) ~150 bytes
- define IRSND_SUPPORT_RCCAR_PROTOCOL 0 // RC CAR >= 10000 (better 15000) ~150 bytes
- define IRSND_SUPPORT_RUWIDO_PROTOCOL 0 // RUWIDO, T-Home >= 15000 DON'T CHANGE, NOT SUPPORTED YET!
- define IRSND_SUPPORT_LEGO_PROTOCOL 0 // LEGO Power RC >= 20000 ~150 bytes
</c>
Mit Setzen auf 0 wird das Protokoll deaktiviert, mit Setzen auf 1 wird es aktiviert. Die deaktivierten Protokolle werden dann nicht mitübersetzt. Das spart Speicherplatz im Flash, siehe Angaben in obigen Kommentaren. Wenn man unbedingt Speicherplatz sparen muss, gelten natürlich hier dieselben Tipps wie für IRMP.
Um das APPLE-Protokoll zu unterstützen, ist IRSND_SUPPORT_NEC_PROTOCOL auf 1 zu setzen, da es sich hier lediglich um einen Spezialfall vom NEC-Protokoll handelt.
IRSND_OCx
Für das Senden der IR-Signale benötigt IRSND einen PWM-fähigen Output-Pin, da das Signal moduliert werden muss. Möglich sind eine der folgenden Einstellungen:
<c>
- define IRSND_OCx IRSND_OC2 // OC2 on ATmegas supporting OC2, e.g. ATmega8
- define IRSND_OCx IRSND_OC2A // OC2A on ATmegas supporting OC2A, e.g. ATmega88
- define IRSND_OCx IRSND_OC2B // OC2B on ATmegas supporting OC2B, e.g. ATmega88
- define IRSND_OCx IRSND_OC0 // OC0 on ATmegas supporting OC0, e.g. ATmega162
- define IRSND_OCx IRSND_OC0A // OC0A on ATmegas/ATtinys supporting OC0A, e.g. ATtiny84, ATtiny85
- define IRSND_OCx IRSND_OC0B // OC0B on ATmegas/ATtinys supporting OC0B, e.g. ATtiny84, ATtiny85
</c>
Standardwert: <c>
- define IRSND_OCx IRSND_OC2B
</c>
Für die PIC- und STM32-µCs sind entsprechende Werte anzupassen, siehe Kommentare in irsndconfig.h.
IRSND_USE_CALLBACK
Standardwert: <c>
- define IRSND_USE_CALLBACK 0 // flag: 0 = don't use callbacks, 1 = use callbacks, default is 0
</c>
Wenn man Callbacks einschaltet, wird bei jeder Änderung des Signals (IR-Modulation ein/aus) eine Callback-Funktion aufgerufen. Dies kann zum Beispiel dafür verwendet werden, ein unmoduliertes Signal an einem weiteren Pin auszugeben.
Hier ein Beispiel:
<c>
- define LED_PORT PORTD // LED at PD6
- define LED_DDR DDRD
- define LED_PIN 6
/*-----------------------------------------------------------------------------------------------------------------------
* Called (back) from IRSND module * This example switches a LED (which is connected to GND) *----------------------------------------------------------------------------------------------------------------------- */
void led_callback (uint8_t on) {
if (on)
{
LED_PORT &= ~(1 << LED_PIN);
}
else
{
LED_PORT |= (1 << LED_PIN);
}
}
int main () {
... LED_DDR |= (1 << LED_PIN); // LED pin to output LED_PORT |= (1 << LED_PIN); // switch LED off (active low) irsnd_init (); irsnd_set_callback_ptr (led_callback); sei (); ...
}
</c>
Anwendung von IRSND
IRSND baut den zu sendenden Frame "on-the-fly" aus der IRMP-Datenstruktur wieder zusammen. Dazu zählen:
1. ID für verwendetes Protokoll 2. Adresse bzw. Herstellercode 3. Kommando
Mittels der Funktion
irsnd_send_data (IRMP_DATA * irmp_data_p)
kann man ein zu encodierendes Telegramm versenden. Der Return-Wert ist 1, wenn das Telegramm versendet werden kann, sonst 0. Im ersten Fall werden die Struct-Members
<c>
irmp_data_p->protocol irmp_data_p->address irmp_data_p->command irmp_data_p->flags
</c>
ausgelesen und dann als Frame im jeweils gewünschten Protokoll gesendet.
NEU ab Version 1.5.0:
irmp_data_p->flags gibt die Anzahl der Wiederholungen an, z.B.
irmp_data_p->flags = 0: Verhalten wie bisher irmp_data_p->flags = 1: 1 Wiederholung irmp_data_p->flags = 2: 2 Wiederholungen usw.
Zu beachten: Da bisher irmp_data_p->flags von IRSND nicht ausgewertet wurde, ist unbedingt ab Version 1.5.0 darauf zu achten, dass irmp_data_p->flags vor dem Aufruf von irsnd_send_data() einen definierten Wert hat!
Hier ein Beispiel:
<c>
IRMP_DATA irmp_data;
irmp_data.protocol = IRMP_NEC_PROTOCOL; // sende im NEC-Protokoll irmp_data.address = 0x00FF; // verwende Adresse 0x00FF irmp_data.command = 0x0001; // sende Kommando 0001 irmp_data.flags = 0; // keine Wiederholung!
(void) irsnd_send_data (&irmp_data); // versende ohne Prüfung
</c>
Der Frame wird asynchron über die Interrupt-Routine irsnd_ISR() verschickt, so dass die Funktion irsnd_send_data() sofort zurückkommt.
Sind Wiederholungen angegeben, wird entweder der Frame nach einer Pause (protokollabhängig) neu ausgegeben oder ein protokollspezifischer Wiederholungsframe (z.B. für NEC) gesendet.
Wird erneut irsnd_send_data() aufgerufen, wartet diese, bis der vorhergenhende Frame vollständig verschickt wurde. Man kann aber auch selbst prüfen, ob IRSND gerade "busy" ist oder nicht:
<c>
while (irsnd_is_busy ())
{
; // selber warten oder was anderes tun...
}
(void) irsnd_send_data (&irmp_data); // versende ohne Prüfung
</c>
Im Beispiel-Source irsndmain.c findet man neben der Verwendung von irsnd_send_data() auch den Timer-Aufruf:
<c> ISR(TIMER1_COMPA_vect) {
irsnd_ISR()) // call irsnd ISR // call other timer interrupt routines...
} </c>
Paralleles Betreiben von IRMP und IRSND
Möchte man IRMP und IRSND parallel verwenden (also als Sender und Empfänger) schreibt man die ISR folgendermaßen:
<c> ISR(TIMER1_COMPA_vect) {
if (! irsnd_ISR()) // call irsnd ISR
{ // if not busy...
irmp_ISR(); // call irmp ISR
}
// call other timer interrupt routines...
} </c>
Das heisst: Nur wenn irsnd_ISR() nichts zu tun hat, dann rufe die ISR des Empfängers auf. Damit ist der Empfänger solange abgeschaltet, während irsnd_ISR() noch Daten sendet. Die Timer-Initialisierungsroutine ist für IRMP und IRSND dann natürlich dieselbe.
Eine gemeinsame main-Funktion könnte dann zum Beispiel folgendermaßen aussehen:
<c> int main (void) {
IRMP_DATA irmp_data;
irmp_init(); // initialize irmp irsnd_init(); // initialize irsnd timer_init(); // initialize timer sei (); // enable interrupts
for (;;)
{
if (irmp_get_data (&irmp_data))
{
irmp_data.flags = 0; // reset flags!
irsnd_send_data (&irmp_data);
}
}
} </c>
Die Funktion des obigen Sources ist offensichtlich: Ein empfangenes Telegramm wird nach vollständiger Decodierung wieder encodiert und dann wieder über die IR-Diode ausgesandt. Somit können dann zum Beispiel Signale "um die Ecke" oder streckenweise drahtgebunden übertragen werden.
Desweiteren könnte man auch Protokolle transformieren, zum Beispiel NEC-Telegramme in RC5 umwandeln, wenn man seine Original-RC5-FB zu seinem Philips-Gerät verlegt hat...
Der Rest bleibt der Phantasie des geneigten Lesers überlassen ;-)
Hier noch die möglichen Werte für irmp_data.protocol, siehe auch irmp.h:
<c>
- define IRMP_SIRCS_PROTOCOL 1 // Sony
- define IRMP_NEC_PROTOCOL 2 // NEC, Pioneer, JVC, Toshiba, NoName etc.
- define IRMP_SAMSUNG_PROTOCOL 3 // Samsung
- define IRMP_MATSUSHITA_PROTOCOL 4 // Matsushita
- define IRMP_KASEIKYO_PROTOCOL 5 // Kaseikyo (Panasonic etc)
- define IRMP_RECS80_PROTOCOL 6 // Philips, Thomson, Nordmende, Telefunken, Saba
- define IRMP_RC5_PROTOCOL 7 // Philips etc
- define IRMP_DENON_PROTOCOL 8 // Denon, Sharp
- define IRMP_RC6_PROTOCOL 9 // Philips etc
- define IRMP_SAMSUNG32_PROTOCOL 10 // Samsung32: no sync pulse at bit 16, length 32 instead of 37
- define IRMP_APPLE_PROTOCOL 11 // Apple, very similar to NEC
- define IRMP_RECS80EXT_PROTOCOL 12 // Philips, Technisat, Thomson, Nordmende, Telefunken, Saba
- define IRMP_NUBERT_PROTOCOL 13 // Nubert
- define IRMP_BANG_OLUFSEN_PROTOCOL 14 // Bang & Olufsen
- define IRMP_GRUNDIG_PROTOCOL 15 // Grundig
- define IRMP_NOKIA_PROTOCOL 16 // Nokia
- define IRMP_SIEMENS_PROTOCOL 17 // Siemens, e.g. Gigaset
- define IRMP_FDC_PROTOCOL 18 // FDC keyboard
- define IRMP_RCCAR_PROTOCOL 19 // RC Car
- define IRMP_JVC_PROTOCOL 20 // JVC (NEC with 16 bits)
- define IRMP_RC6A_PROTOCOL 21 // RC6A, e.g. Kathrein, XBOX
- define IRMP_NIKON_PROTOCOL 22 // Nikon
- define IRMP_RUWIDO_PROTOCOL 23 // Ruwido, e.g. T-Home Mediareceiver
- define IRMP_IR60_PROTOCOL 24 // IR60 (SDA2008)
- define IRMP_KATHREIN_PROTOCOL 25 // Kathrein
- define IRMP_NETBOX_PROTOCOL 26 // Netbox keyboard (bitserial)
- define IRMP_NEC16_PROTOCOL 27 // NEC with 16 bits (incl. sync)
- define IRMP_NEC42_PROTOCOL 28 // NEC with 42 bits
- define IRMP_LEGO_PROTOCOL 29 // LEGO Power Functions RC
- define IRMP_THOMSON_PROTOCOL 30 // Thomson
</c>
Die Daten für die Adresse und das Kommando ermittelt man am besten über IRMP, siehe weiter oben ;-)
IRSND unter Linux und Windows
irsnd.c lässt sich auch unter Linux direkt kompilieren, um damit Telegramme in Form von IRMP-Scan-Dateien zu erzeugen. Das geht folgendermaßen:
cc irsnd.c -o irsnd # IRSND compilieren
Der Aufruf geht dann folgendermaßen:
./irsnd protocol-number hex-address hex-command [repeat] > filename.txt
also zum Beispiel für das NEC-Protokoll, Adresse 0x00FF, Kommando 0x0001
./irsnd 2 00FF 0001 > nec.txt # irsnd ausführen
IRSND kann man auch unter Windows nutzen, nämlich folgendermaßen:
- Eingabeaufforderung starten
- In das Verzeichnis von irsnd wechseln
- Aufruf von:
irsnd.exe 2 00FF 0001 > nec.txt
Nun kann man direkt mit IRMP anschließend testen, ob das erzeugte Telegramm auch korrekt ist:
./irmp < nec.txt
bzw. unter Windows:
irmp.exe < nec.txt
Das Ganze geht auch ohne Zwischendatei, nämlich:
./irsnd 2 00FF 0001 | ./irmp
bzw. unter Windows:
irsnd.exe 2 00FF 0001 | irmp.exe
IRMP gibt dann als Ergebnis folgendes aus:
11111111000000001000000001111111 p = 2, a = 0x00ff, c = 0x0001, f = 0x00
IRMP konnte also aus dem von IRSND generierten Frame wieder das Protokoll 2, Adresse 0x00FF und Kommando 0x0001 decodieren.
Bitte beachten: Je nach benutztem Protokoll sind die Bit-Breiten der Adressen bzw. Kommandos verschieden, siehe obige Tabelle [1].
Man kann also nicht mit jedem IR-Protokoll komplett 16-Bit breite Adressen oder Kommandos transparent übertragen.
Anhang
Die IR-Protokolle im Detail
Pulse-Distance Protokolle
SIRCS
| SIRCS | Wert |
|---|---|
| Frequenz | 40 kHz |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bit + 12-20 Daten-Bits, kein Stop-Bit |
| Daten | 7 Kommando-Bits + 5 Adress-Bits + bis zu 8 zusätzliche Bits |
| Start-Bit | 2400µs Puls, 600µs Pause |
| 0-Bit | 600µs Puls, 600µs Pause |
| 1-Bit | 1200µs Puls, 600µs Pause |
| Wiederholung | zweimalig nach ca. 25ms, d.h. 2. und 3. Frame |
| Tasten-Wiederholung | ab dem 4. identischen Frame, Abstand ca. 25ms |
| Bit-Order | LSB first |
NEC + extended NEC
| NEC + extended NEC | Wert |
|---|---|
| Frequenz | 36 kHz / 38 kHz |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bit + 32 Daten-Bits + 1 Stop-Bit |
| Daten NEC | 8 Adress-Bits + 8 invertierte Adress-Bits + 8 Kommando-Bits + 8 invertierte Kommando-Bits |
| Daten ext. NEC | 16 Adress-Bits + 8 Kommando-Bits + 8 invertierte Kommando-Bits |
| Start-Bit | 9000µs Puls, 4500µs Pause |
| 0-Bit | 560µs Puls, 560µs Pause |
| 1-Bit | 560µs Puls, 1690µs Pause |
| Stop-Bit | 560µs Puls |
| Wiederholung | keine |
| Tasten-Wiederholung | 9000µs Puls, 2250µs Pause, 560µs Puls, ~100ms Pause |
| Bit-Order | LSB first |
JVC
| JVC | Wert |
|---|---|
| Frequenz | 38 kHz |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bit + 16 Daten-Bits + 1 Stop-Bit |
| Daten | 4 Adress-Bits + 12 Kommando-Bits |
| Start-Bit | 9000µs Puls, 4500µs Pause, 6000µs Pause bei Tasten-Wiederholung |
| 0-Bit | 560µs Puls, 560µs Pause |
| 1-Bit | 560µs Puls, 1690µs Pause |
| Stop-Bit | 560µs Puls |
| Wiederholung | keine |
| Tasten-Wiederholung | Wiederholung nach Pause von 25ms |
| Bit-Order | LSB first |
NEC16
| NEC16 | Wert |
|---|---|
| Frequenz | 38 kHz |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bit + 8 Adress-Bits + 1 Sync-Bit + 8 Daten-Bits + 1 Stop-Bit |
| Start-Bit | 9000µs Puls, 4500µs Pause |
| Sync-Bit | 560µs Puls, 4500µs Pause |
| 0-Bit | 560µs Puls, 560µs Pause |
| 1-Bit | 560µs Puls, 1690µs Pause |
| Stop-Bit | 560µs Puls |
| Wiederholung | keine/eine/zwei nach 25ms? |
| Tasten-Wiederholung | Wiederholung nach Pause von 25ms? |
| Bit-Order | LSB first |
NEC42
| NEC42 | Wert |
|---|---|
| Frequenz | 38 kHz? |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bit + 42 Daten-Bits + 1 Stop-Bit |
| Daten | 13 Adress-Bits + 13 invertierte Adress-Bits + 8 Kommando-Bits + 8 invertierte Kommando-Bits |
| Start-Bit | 9000µs Puls, 4500µs Pause |
| 0-Bit | 560µs Puls, 560µs Pause |
| 1-Bit | 560µs Puls, 1690µs Pause |
| Stop-Bit | 560µs Puls |
| Wiederholung | keine |
| Tasten-Wiederholung | (unbekannt) |
| Bit-Order | LSB first |
SAMSUNG
| SAMSUNG | Wert |
|---|---|
| Frequenz | ?? kHz |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bit + 16 Daten(1)-Bits + 1 Sync-Bit + 20 Daten(2)-Bits + 1 Stop-Bit |
| Daten(1) | 16 Adress-Bits |
| Daten(2) | 4 ID-Bits + 8 Kommando-Bits + 8 invertierte Kommando-Bits |
| Start-Bit | 4500µs Puls, 4500µs Pause |
| 0-Bit | 550µs Puls, 550µs Pause |
| 1-Bit | 550µs Puls, 1650µs Pause |
| Sync-Bit | 550µs Puls, 4500µs Pause |
| Stop-Bit | 550µs Puls |
| Wiederholung | keine |
| Tasten-Wiederholung | N-fache Wiederholung des Original-Frames innerhalb von 100ms |
| Bit-Order | LSB first |
SAMSUNG32
| SAMSUNG32 | Wert |
|---|---|
| Frequenz | 38 kHz |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bit + 32 Daten-Bits + 1 Stop-Bit |
| Daten | 16 Adress-Bits + 16 Kommando-Bits |
| Start-Bit | 4500µs Puls, 4500µs Pause |
| 0-Bit | 550µs Puls, 550µs Pause |
| 1-Bit | 550µs Puls, 1650µs Pause |
| Stop-Bit | 550µs Puls |
| Wiederholung | keine |
| Tasten-Wiederholung | dritter, fünfter, siebter usw. identischer Frame |
| Bit-Order | LSB first |
MATSUSHITA
| MATSUSHITA | Wert |
|---|---|
| Frequenz | 36 kHz |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bit + 24 Daten-Bits + 1 Stop-Bit |
| Daten | 6 Hersteller-Bits + 6 Kommando-Bits + 12 Adress-Bits |
| Start-Bit | 3488µs Puls, 3488µs Pause |
| 0-Bit | 872µs Puls, 872µs Pause |
| 1-Bit | 872µs Puls, 2616µs Pause |
| Stop-Bit | 872µs Puls |
| Wiederholung | keine |
| Tasten-Wiederholung | N-fache Wiederholung des Original-Frames innerhalb von 100ms |
| Bit-Order | LSB first? |
KASEIKYO
| KASEIKYO | Wert |
|---|---|
| Frequenz | 38 kHz |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bit + 48 Daten-Bits + 1 Stop-Bit |
| Daten | 16 Hersteller-Bits + 4 Parity-Bits + 4 Genre1-Bits + 4 Genre2-Bits + 10 Kommando-Bits + 2 ID-Bits + 8 Parity-Bits |
| Start-Bit | 3380µs Puls, 1690µs Pause |
| 0-Bit | 423µs Puls, 423µs Pause |
| 1-Bit | 423µs Puls, 1269µs Pause |
| Stop-Bit | 423µs Puls |
| Wiederholung | einmalig nach 74ms |
| Tasten-Wiederholung | N-fache Wiederholung des Original-Frames innerhalb von 74ms |
| Bit-Order | LSB first? |
RECS80
| RECS80 | Wert |
|---|---|
| Frequenz | 38 kHz |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bits + 10 Daten-Bits + 1 Stop-Bit |
| Daten | 1 Toggle-Bit + 3 Adress-Bits + 6 Kommando-Bits |
| Start-Bit | 158µs Puls, 7432µs Pause |
| 0-Bit | 158µs Puls, 4902µs Pause |
| 1-Bit | 158µs Puls, 7432µs Pause |
| Stop-Bit | 158µs Puls |
| Wiederholung | keine |
| Tasten-Wiederholung | N-fache Wiederholung des Original-Frames innerhalb von 100ms |
| Bit-Order | MSB first |
RECS80EXT
| RECS80EXT | Wert |
|---|---|
| Frequenz | 38 kHz |
| Kodierung | Pulse Distance |
| Frame | 2 Start-Bits + 11 Daten-Bits + 1 Stop-Bit |
| Daten | 1 Toggle-Bit + 4 Adress-Bits + 6 Kommando-Bits |
| Start-Bit | 158µs Puls, 3637µs Pause |
| 0-Bit | 158µs Puls, 4902µs Pause |
| 1-Bit | 158µs Puls, 7432µs Pause |
| Stop-Bit | 158µs Puls |
| Wiederholung | keine |
| Tasten-Wiederholung | N-fache Wiederholung des Original-Frames innerhalb von 100ms |
| Bit-Order | MSB first |
DENON
| DENON | Wert |
|---|---|
| Frequenz | 38 kHz (in der Praxis, lt. Dokumentation: 32 kHz) |
| Kodierung | Pulse Distance |
| Frame | 0 Start-Bits + 15 Daten-Bits + 1 Stop-Bit |
| Daten | 5 Address-Bits + 10 Kommando-Bits |
| Kommando | 6 Datenbits + 2 Extension Bits + 2 Data Construction Bits (normal: 00, invertiert: 11) |
| Start-Bit | kein Start-Bit |
| 0-Bit | 310µs Puls, 745µs Pause (in der Praxis, lt. Doku: 275µs Puls, 775µs Pause) |
| 1-Bit | 310µs Puls, 1780µs Pause (in der Praxis, lt. Doku: 275µs Puls, 1900µs Pause) |
| Stop-Bit | 310µs Puls (310µs Puls, 745µs Pause (in der Praxis, lt. Doku: 275µs Puls) |
| Wiederholung | Nach 65ms Wiederholung des Frames mit invertieren Kommando-Bits (Data Construction Bits = 11) |
| Tasten-Wiederholung | N-fache Wiederholung der beiden Original-Frames nach 65ms |
| Bit-Order | MSB first |
APPLE
| APPLE | Wert |
|---|---|
| Frequenz | 38 kHz? |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bit + 32 Daten-Bits + 1 Stop-Bit |
| Daten | 16 Adress-Bits + 11100000 + 8 Kommando-Bits |
| Start-Bit | siehe NEC |
| 0-Bit | siehe NEC |
| 1-Bit | siehe NEC |
| Stop-Bit | siehe NEC |
| Wiederholung | keine |
| Tasten-Wiederholung | N-fache Wiederholung des Original-Frames innerhalb von 100ms |
| Bit-Order | LSB first |
NUBERT
| NUBERT | Wert |
|---|---|
| Frequenz | 36 kHz? |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bit + 10 Daten-Bits + 1 Stop-Bit |
| Daten | 0 Adress-Bits + 10 Kommando-Bits ? |
| Start-Bit | 1340µs Puls, 340µs Pause |
| 0-Bit | 500µs Puls, 1300µs Pause |
| 1-Bit | 1340µs Puls, 340µs Pause |
| Stop-Bit | 500µs Puls |
| Wiederholung | einmalig nach 35ms |
| Tasten-Wiederholung | dritter, fünfter, siebter usw. identischer Frame |
| Bit-Order | MSB first? |
BOSE
| BOSE | Wert |
|---|---|
| Frequenz | 38 kHz? |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bit + 16 Daten-Bits + 1 Stop-Bit |
| Daten | 8 Kommando-Bits + 8 invertierte Kommando-Bits |
| Start-Bit | 1060µs Puls, 1425µs Pause |
| 0-Bit | 550µs Puls, 437µs Pause |
| 1-Bit | 550µs Puls, 1425µs Pause |
| Stop-Bit | 550µs Puls |
| Wiederholung | keine |
| Tasten-Wiederholung | noch ungeklärt |
| Bit-Order | LSB first |
B&O
| B&O | Wert |
|---|---|
| Frequenz | 455 kHz |
| Kodierung | Pulse Distance |
| Frame | 4 Start-Bits + 16 Daten-Bits + 1 Trailer-Bit + 1 Stop-Bit |
| Daten | 0 Adress-Bits + 16 Kommando-Bits |
| Start-Bit 1 | 200µs Puls, 2925µs Pause |
| Start-Bit 2 | 200µs Puls, 2925µs Pause |
| Start-Bit 3 | 200µs Puls, 15425µs Pause |
| Start-Bit 4 | 200µs Puls, 2925µs Pause |
| 0-Bit | 200µs Puls, 2925µs Pause |
| 1-Bit | 200µs Puls, 9175µs Pause |
| R-Bit | 200µs Puls, 6050µs Pause, wiederholt das letzte Bit (repetition) |
| Trailer-Bit | 200µs Puls, 12300µs Pause |
| Stop-Bit | 200µs Puls |
| Wiederholung | keine |
| Tasten-Wiederholung | N-fache Wiederholung des Original-Frames innerhalb von 100ms |
| Bit-Order | MSB first |
FDC
| FDC | Wert |
|---|---|
| Frequenz | 38 kHz |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bit + 40 Daten-Bits + 1 Stop-Bit |
| Daten | 8 Adress-Bits + 12 x 0-Bits + 4 Press/Release-Bits + 8 Kommando-Bits + 8 invertierte Kommando-Bits |
| Start-Bit | 2085µs Puls, 966µs Pause |
| 0-Bit | 300µs Puls, 220µs Pause |
| 1-Bit | 300µs Puls, 715µs Pause |
| Stop-Bit | 300µs Puls |
| Wiederholung | keine |
| Tasten-Drücken | Press/Release-Bits = 0000 |
| Tasten-Loslassen | Press/Release-Bits = 1111 |
| Tasten-Wiederholung | Wiederholung nach Pause von 60ms |
| Bit-Order | LSB first |
RCCAR
| RCCAR | Wert |
|---|---|
| Frequenz | 38 kHz? |
| Kodierung | Pulse Distance |
| Frame | 1 Start-Bit + 13 Daten-Bits + 1 Stop-Bit |
| Daten | C0 C1 A0 A1 D0 D1 D2 D3 D4 D5 D6 D7 V |
| Start-Bit | 2000µs Puls, 2000µs Pause |
| 0-Bit | 600µs Puls, 900µs Pause |
| 1-Bit | 600µs Puls, 450µs Pause |
| Stop-Bit | 600µs Puls |
| Wiederholung | keine |
| Tasten-Wiederholung | keine? |
| Bit-Order | LSB first |
Bi-Phase Protokolle
RC5 + RC5X
| RC5 + RC5X | Wert |
|---|---|
| Frequenz | 36 kHz |
| Kodierung | Bi-Phase (Manchester) |
| Frame RC5 | 2 Start-Bits + 12 Daten-Bits + 0 Stop-Bits |
| Daten RC5 | 1 Toggle-Bit + 5 Adress-Bits + 6 Kommando-Bits |
| Frame RC5X | 1 Start-Bit + 13 Daten-Bits + 0 Stop-Bit |
| Daten RC5X | 1 invertiertes Kommando-Bit + 1 Toggle-Bit + 5 Adress-Bits + 6 Kommando-Bits |
| Start-Bit | 889µs Pause, 889µs Puls |
| 0-Bit | 889µs Puls, 889µs Pause |
| 1-Bit | 889µs Pause, 889µs Puls |
| Stop-Bit | kein Stop-Bit |
| Wiederholung | keine |
| Tasten-Wiederholung | N-fache Wiederholung des Original-Frames innerhalb von 100ms |
| Bit-Order | MSB first |
RC6 + RC6A
| RC6 + RC6A | Wert |
|---|---|
| Frequenz | 36 kHz |
| Kodierung | Bi-Phase (Manchester) |
| Frame RC6 | 1 Start-Bit + 1 Bit "1" + 3 Mode-Bits (000) + 1 Toggle-Bit + 16 Daten-Bits + 2666µs pause |
| Frame RC6A | 1 Start-Bit + 1 Bit "1" + 3 Mode-Bits (110) + 1 Toggle-Bit + 31 Daten-Bits + 2666µs pause |
| Daten RC6 | 8 Adress-Bits + 8 Kommando Bits |
| Daten RC6A | "1" + 14 Hersteller-Bits + 8 System-Bits + 8 Kommando-Bits |
| Start-Bit | 2666µs Puls, 889µs Pause |
| Toggle 0-Bit | 889µs Pause, 889µs Puls |
| Toggle 1-Bit | 889µs Puls, 889µs Pause |
| 0-Bit | 444µs Pause, 444µs Puls |
| 1-Bit | 444µs Puls, 444µs Pause |
| Stop-Bit | kein Stop-Bit |
| Wiederholung | keine |
| Tasten-Wiederholung | N-fache Wiederholung des Original-Frames innerhalb von 100ms |
| Bit-Order | MSB first |
GRUNDIG + NOKIA
| GRUNDIG + NOKIA | Wert |
|---|---|
| Frequenz | 38 kHz (?) |
| Kodierung | Bi-Phase (Manchester) |
| Frame-Paket | 1 Start-Frame + 19,968ms Pause + N Info-Frames + 117,76ms Pause + 1 Stop-Frame |
| Start-Frame | 1 Pre-Bit + 1 Start-Bit + 9 Daten-Bits (alle 1) + 0 Stop-Bits |
| Info-Frame | 1 Pre-Bit + 1 Start-Bit + 9 Daten-Bits + 0 Stop-Bits |
| Stop-Frame | 1 Pre-Bit + 1 Start-Bit + 9 Daten-Bits (alle 1) + 0 Stop-Bits |
| Daten Grundig | 9 Kommando-Bits + 0 Adress-Bits |
| Daten Nokia | 8 Kommando-Bits + 8 Adress-Bits |
| Pre-Bit | 528µs Puls, 2639µs Pause |
| Start-Bit | 528µs Puls, 528µs Pause |
| 0-Bit | 528µs Pause, 528µs Puls |
| 1-Bit | 528µs Puls, 528µs Pause |
| Stop-Bit | kein Stop-Bit |
| Wiederholung | keine |
| Tasten-Wiederholung | N-fache Wiederholung des Info-Frames mit einem Pausenabstand von 117,76ms |
| Bit-Order | LSB first |
IR60 (SDA2008)
| IR60 (SDA2008) | Wert |
|---|---|
| Frequenz | 30 kHz |
| Kodierung | Bi-Phase (Manchester) |
| Start Frame | 1 Start-Bit + 101111 + 0 Stop-Bits + 22ms Pause |
| Daten Frame | 1 Start-Bit + 7 Daten-Bits + 0 Stop-Bits |
| Daten | 0 Adress-Bits + 7 Kommando-Bits |
| Start-Bit | 528µs Puls, 2639µs Pause |
| 0-Bit | 528µs Pause, 528µs Puls |
| 1-Bit | 528µs Puls, 528µs Pause |
| Stop-Bit | kein Stop-Bit |
| Wiederholung | keine |
| Tasten-Wiederholung | N-fache Wiederholung des Info-Frames mit einem Pausenabstand von 117,76ms |
| Bit-Order | LSB first |
SIEMENS + RUWIDO
| SIEMENS + RUWIDO | Wert |
|---|---|
| Frequenz | 36 kHz? (Merlin-Tastatur mit Ruwido-Protokoll: 56 kHz) |
| Kodierung | Bi-Phase (Manchester) |
| Frame Siemens | 1 Start-Bit + 22 Daten-Bits + 0 Stop-Bits |
| Frame Ruwido | 1 Start-Bit + 17 Daten-Bits + 0 Stop-Bits |
| Daten Siemens | 11 Adress-Bits + 10 Kommando-Bits + 1 invertiertes Bit (letztes Bit davor nochmal invertiert) |
| Daten Ruwido | 9 Adress-Bits + 7 Kommando-Bits + 1 invertiertes Bit (letztes Bit davor nochmal invertiert) |
| Start-Bit | 275µs Puls, 275µs Pause |
| 0-Bit | 275µs Pause, 275µs Puls |
| 1-Bit | 275µs Puls, 275µs Pause |
| Stop-Bit | kein Stop-Bit |
| Wiederholung | 1-malige Wiederholung mit gesetztem Repeat-Bit (?) |
| Tasten-Wiederholung | N-fache Wiederholung des Original-Frames innerhalb von 100ms (?) |
| Bit-Order | MSB first |
Serial Protokolle
NETBOX
| NETBOX | Wert |
|---|---|
| Frequenz | 38 kHz? |
| Kodierung | Serial |
| Frame | 1 Start-Bit + 16 Daten-Bits, kein Stop-Bit |
| Daten | 3 Adress-Bits + 13 Kommando-Bits |
| Start-Bit | 2400µs Puls, 800µs Pause |
| Bitlänge | 800µs |
| Wiederholung | keine |
| Tasten-Wiederholung | Abstand ca. 35ms? |
| Bit-Order | LSB first |
Software-Historie IRMP
Änderungen IRMP:
Version 2.3.3 (nur im SVN):
- 19.11.2012: Portierung auf Stellaris LM4F120 Launchpad von TI (ARM Cortex M4)
Version 2.3.2 (nur im SVN):
- 06.11.2012: Korrektur Denon-Frame-Erkennung
Version 2.3.1:
- 26.10.2012: Einige Timer-Korrekturen, Anpassungen an Arduino
Version 2.2.4:
- 11.07.2012: Neues Protokoll: BOSE
Version 2.2.3:
- 18.06.2012: Unterstützung für ATtiny87/167 hinzugefügt
Version 2.2.2:
- 05.06.2012: Kleinere Korrekturen Portierung auf ARM STM32
- 05.06.2012: Include-Korrektur in irmpextlog.c
- 05.06.2012: Bugfix, wenn nur NEC und NEC42 aktiviert
Version 2.2.0:
- 23.05.2012: Portierung auf ARM STM32
- 23.05.2012: Bugfix Frame-Erkennung beim Denon-Protokoll
Ältere Versionen:
- 27.02.2012: Bug in IR60-Decoder behoben
- 27.02.2012: Bug in CRC-Berechnung von Kaseikyo-Frames behoben
- 27.02.2012: Portierung auf C18 Compiler für PIC-Mikroprozessoren
- 13.02.2012: Bugfix: oberstes Bit in Adresse falsch bei NEC-Protokoll, wenn auch NEC42-Protokoll eingeschaltet ist.
- 13.02.2012: Timing von SAMSUNG- und SAMSUNG32-Protokoll korrigiert
- 13.02.2012: Genre2-Bits werden nun im oberen Nibble von flags gespeichert.
- 20.09.2011: Neues Protokoll: KATHREIN
- 20.09.2011: Neues Protokoll: RUWIDO
- 20.09.2011: Neues Protokoll: THOMSON
- 20.09.2011: Neues Protokoll: IR60
- 20.09.2011: Neues Protokoll: LEGO
- 20.09.2011: Neues Protokoll: NEC16
- 20.09.2011: Neues Protokoll: NEC42
- 20.09.2011: Neues Protokoll: NETBOX
- 20.09.2011: Portierung auf ATtiny84 und ATtiny85
- 20.09.2011: Verbesserung von Tastenwiederholungen bei RC5
- 20.09.2011: Verbessertes Decodieren von Bi-Phase-Protokollen
- 20.09.2011: Korrekturen am RECS80-Decoder
- 20.09.2011: Korrekturen beim Erkennen von zusätzlichen Bits im SIRCS-Protocol
- 18.01.2011: Korrekturen für Siemens-Protokoll
- 18.01.2011: Neues Protokoll: NIKON
- 18.01.2011: Speichern der zusätzlichen Bits (>12) im SIRCS-Protokoll in der Adresse
- 18.01.2011: Timing-Korrekturen für Denon-Protokoll
- 04.09.2010: Bugfix für F_INTERRUPTS >= 16000
- 02.09.2010: Neues Protokoll: RC6A
- 29.08.2010: Neues Protokoll: JVC
- 29.08.2010: Kaseikyo-Protokoll: Berücksichtigung der Genre-Bits. ACHTUNG: dadurch neue Command-Codes!
- 29.08.2010: Kaseikyo-Protokoll: Verbesserte Behandlung von Wiederholungs-Frames
- 29.08.2010: Verbesserte Unterstützung des APPLE-Protokolls. ACHTUNG: dadurch neue Adress-Codes!
- 01.07.2010: Bugfix: Einführen eines Timeouts für NEC-Repetition-Frames, um "Geisterkommandos" zu verhindern.
- 26.06.2010: Bugfix: Deaktivieren von RECS80, RECS80EXT & SIEMENS bei geringer Interrupt-Rate
- 25.06.2010: Neues Protokoll: RCCAR
- 25.06.2010: Tastenerkennung für FDC-Protokoll (IR-keyboard) erweitert
- 25.06.2010: Interrupt-Frequenz nun bis zu 20kHz möglich
- 09.06.2010: Neues Protokoll: FDC (IR-keyboard)
- 09.06.2010: Timing für DENON-Protokoll korrigiert
- 02.06.2010: Neues Protokoll: Siemens (Gigaset)
- 26.05.2010: Neues Protokoll: Nokia
- 26.05.2010: Bugfix Auswertung von langen Tastendrücken bei Grundig-Protokoll
- 17.05.2010: Bugfix SAMSUNG32-Protokoll: Kommando-Bit-Maske korrigiert
- 16.05.2010: Neues Protokoll: Grundig
- 16.05.2010: Behandlung von automatischen Frame-Wiederholungen beim SIRCS-, SAMSUNG32- und NUBERT-Protokoll verbessert.
- 28.04.2010: Nur einige kosmetische Code-Optimierungen
- 16.04.2010: Sämtliche Timing-Toleranzen angepasst/optimiert
- 12.04.2010: Neues Protokoll: Bang & Olufsen
- 29.03.2010: Bugfix beim Erkennen von mehrfachen NEC-Repetition-Frames
- 29.03.2010: Konfiguration in irmpconfig.h ausgelagert
- 29.03.2010: Einführung einer Programmversion in README.txt: Version 1.0
- 17.03.2010: Neues Protokoll: Nubert
- 16.03.2010: Korrektur der RECS80-Startbit-Timings
- 16.03.2010: Neues Protokoll: RECS80 Extended
- 15.03.2010: Codeoptimierung
- 14.03.2010: Portierung auf PIC
- 11.03.2010: Anpassungen an verschiedene ATMega-Typen durchgeführt
- 07.03.2010: Bugfix: Zurücksetzen der Statemachine nach einem unvollständigen RC5-Frame
- 05.03.2010: Neues Protokoll: Apple
- 05.03.2010: Die Daten irmp_data.addr + irmp_data.command werden nun in der jeweiligen Bit-Order des verwendeten Protokolls gespeichert
- 04.03.2010: Neues Protokoll: SAMSUNG32 (Mix aus SAMSUNG & NEC-Protokoll)
- 04.03.2010: Änderung der SIRCS- und Kaseikyo-Toleranzen
- 02.03.2010: SIRCS: Korrekte Erkennung und Unterdrückung von automatischen Frame-Wiederholungen
- 02.03.2010: SIRCS: Device-ID-Bits werden nun in irmp_data.command und nicht mehr in irmp_data.address gespeichert
- 02.03.2010: Vergrößerung des Scan Buffers (zwecks Protokollierung)
- 24.02.2010: Neue Variable flags in IRMP_DATA zur Erkennung von langen Tastendrücken
- 20.02.2010: Bugfix Denon-Protokoll: Wiederholungsframe grundsätzlich invertiert
- 19.02.2010: Erkennung von NEC-Protokoll-Varianten, z. B. Apple-Fernbedienung
- 19.02.2010: Erkennung von RC6- und Denon-Protokoll
- 19.02.2010: Verbesserung des RC5-Decoders (Bugfixes)
- 13.02.2010: Bugfix: Puls/Pausen-Counter um 1 zu niedrig, nun bessere Erkennung bei Protokollen mit sehr kurzen Pulszeiten
- 13.02.2010: Erkennung der NEC-Wiederholungssequenz
- 12.02.2010: RC5-Protokoll-Decoder hinzugefügt
- 05.02.2010: Konflikt zwischen Samsung- und Matsushita-Protokoll beseitigt
- 07.01.2010: Erste Version
Software-Historie IRSND
Änderungen IRSND:
Version 2.3.1:
- 26.10.2012: Einige Timer-Korrekturen, Anpassungen an Arduino
Version 2.2.3:
- 18.06.2012: Unterstützung für ATtiny87/167 hinzugefügt
Version 2.2.2:
- 05.06.2012: Korrekturen Portierung auf ARM STM32 - nun getestet
Version 2.2.0:
- 23.05.2012: Portierung auf ARM STM32 (ungetestet!)
- 23.05.2012: Bugfix Timing für 2. Frame beim Denon-Protokoll
Ältere Versionen:
- 27.02.2012: Neues Protokoll: IR60
- 27.02.2012: Bug beim Senden von Bi-Phase-Frames (Manchester) behoben
- 27.02.2012: Portierung auf C18 Compiler für PIC-Mikroprozessoren
- 15.02.2012: Bugfix: Nur der 1. Frame wurde gesendet
- 13.02.2012: Timing von SAMSUNG- und SAMSUNG32-Protokoll korrigiert
- 13.02.2012: Genre2-Bits werden nun im oberen Nibble von flags gespeichert.
- 13.02.2012: Zusätzliche Pause nach dem Senden des letzten Frames
- 20.09.2011: Neues Protokoll: THOMSON
- 20.09.2011: Neues Protokoll: LEGO
- 20.09.2011: Neues Protokoll: NEC16
- 20.09.2011: Neues Protokoll: NEC42
- 20.09.2011: Portierung auf ATtiny84 und ATtiny85
- 20.09.2011: Korrektur von Pausenlängen
- 20.09.2011: Korrekturen von irsnd_stop()
- 20.09.2011: Korrektur des SIEMENS-Timings
- 20.09.2011: Umstellung auf 36kHz Modulationsfrequenz für DENON-Protokoll
- 20.09.2011: Korrektur Behandlung zusätzlicher Bits im SIRCS Protokoll
- 18.01.2011: Neues Protokoll: RC6A
- 18.01.2011: Neues Protokoll: RC6
- 18.01.2011: Neues Protokoll: NIKON
- 18.01.2011: Beachten der zusätzlichen Bits (>12) im SIRCS-Protokoll
- 18.01.2011: Korrektur der Pausenlängen
- 18.01.2011: Timing-Korrekturen für Denon-Protokoll
- 02.09.2010: Neues Protokoll: JVC
- 02.09.2010: Anpassung des APPLE-Encoders an IRMP-Version 1.7.3.
- 29.08.2010: Neues Protokoll: Kaseikyo (Panasonic u.a.)
- 01.07.2010: Bugfix: Deaktivieren von RECS80, RECS80EXT & SIEMENS bei geringer Interrupt-Rate
- 25.06.2010: Neues Protokoll: RCCAR
- 09.06.2010: Neues Protokoll: FDC (IR-keyboard)
- 09.06.2010: Timing für DENON-Protokoll korrigiert
- 02.06.2010: Neues Protokoll: Siemens (Gigaset)
- 02.06.2010: Simulation von langen Tastendrücken
- 26.05.2010: Neues Protokoll: Nokia
- 17.05.2010: Neues Protokoll: Grundig
- 17.05.2010: Behandlung von Frame-Wiederholungen für SIRCS, SAMSUNG32 und NUBERT korrigiert
- 28.04.2010: Unterstützung des APPLE-Protokolls
- 28.04.2010: Konfiguration über irmpconfig.h
- 16.04.2010: Sämtliche Timing-Toleranzen angepasst/optimiert
- 14.04.2010: Neues Protokoll: Bang & Olufsen
- 17.03.2010: Neues Protokoll: Nubert
- 17.03.2010: Korrektur der Pausen zwischen Frame-Wiederholungen
- 16.03.2010: Korrektur des Timer-Registers TCCR2
- 16.03.2010: Korrektur der RECS80-Startbit-Timings
- 16.03.2010: Neues Protokoll: RECS80 Extended
- 11.03.2010: Anpassungen an verschiedene ATMega-Typen durchgeführt
- 07.03.2010: Alpha-Version
Literatur
IR-Übersicht :
- http://www.sbprojects.com/knowledge/ir/index.php
- http://www.epanorama.net/links/irremote.html
- http://www.elektor.de/jahrgang/2008/juni/cc2-avr-projekt-%283%29-unsichtbare-kommandos.497184.lynkx?tab=4 (IR Übersicht & RC5)
SIRCS-Protokoll:
- http://www.sbprojects.com/knowledge/ir/sirc.php
- http://www.ustr.net/infrared/sony.shtml
- http://users.telenet.be/davshomepage/sony.htm
- http://picprojects.org.uk/projects/sirc/
NEC-Protokoll:
- http://www.sbprojects.com/knowledge/ir/nec.php
- http://www.ustr.net/infrared/nec.shtml
- http://www.celadon.com/infrared_protocol/infrared_protocols_samples.pdf
NEC16-Protokoll (JVC):
SAMSUNG-Protokoll:
(wurde aus diversen Protokollen (Daewoo u.ä.) zusammengereimt, daher kein direkter Link auf irgendwelche SAMSUNG-Dokumentation verfügbar)
Hier ein Link zum Daewoo-Protokoll, welches dasselbe Prinzip des Sync-Bits in der Mitte eines Frames nutzt, jedoch mit anderen Timing-Werten arbeitet:
MATSUHITA-Protokoll:
KASEIKYO-Protokoll (auch "Japan-Protokoll"):
- http://www.mikrocontroller.net/attachment/4246/IR-Protokolle_Diplomarbeit.pdf
- http://www.roboternetz.de/phpBB2/files/entwicklung_und_realisierung_einer_universalinfrarotfernbedienung_mit_timerfunktionen.pdf
RECS80- und RECS80-Extended-Protokoll:
RC5- und RC5x-Protokoll:
Denon-Protokoll:
- http://www.mikrocontroller.com/de/IR-Protokolle.php#DENON
- http://www.manualowl.com/m/Denon/AVR-3803/Manual/170243
RC6 und RC6A-Protokoll:
- http://www.sbprojects.com/knowledge/ir/rc6.php
- http://slycontrol.ru/scr/kb/rc6.htm
- http://www.picbasic.nl/info_rc6_uk.htm
Bang & Olufsen:
Grundig
Nokia
IR60 (SDA2008 bzw. MC14497P)
- http://www.datasheetarchive.com/dl/Datasheets-24/DSA-478524.pdf
- http://www.datasheetcatalog.org/datasheet/motorola/MC14497P.pdf
Diverse Protokolle:
- http://www.mikrocontroller.net/attachment/4246/IR-Protokolle_Diplomarbeit.pdf
- http://www.celadon.com/infrared_protocol/infrared_protocols_samples.pdf
- http://www.opendcc.de/info/rc5/rc5.html
- http://www.roboternetz.de/phpBB2/files/entwicklung_und_realisierung_einer_universalinfrarotfernbedienung_mit_timerfunktionen.pdf
Hardware / IRMP-Projekte
Eine Implementierung auf Basis IRMP und IRSND als Multiprotokoll Dekoder mit LCD von Klaus Leidinger:
Ähnliche Implementierung wie von Klaus Leidinger für Pollin AVR-NET-IO mit Pollin ADD-ON Board:
USB IR Remote Receiver von Hugo Portisch:
Servo-gesteuerter IR Sender mit Anlernfunktion von Stefan Pendsa:
- http://forum.mikrokopter.de/topic-21060.html
- (SVN) http://svn.mikrokopter.de/listing.php?repname=Projects&path=%2FServo-Controlled+IR-Transmitter%2F&#Ad2417800d6aa14bf08c571a896e9def7
Lernfähige IR-Fernbedienung von Robert und Frank M.
Danksagung
Ganz herzlich bedanken möchte ich mich bei Vlad Tepesch, Klaus Leidinger und Peter K., die mich mit Scan-Dateien ihrer Infrarot-Fernbedienungen versorgt haben. Dank auch an Klaus für seine nächtelangen Tests von IRMP & IRSND.
Ebenso bedanken möchte ich mich bei Christian F. für seine Tipps zur PIC-Portierung. Vielen Dank auch an gera für die Portierung auf den PIC-C18 Compiler. Für die Portierung auf ARM STM32 bedanke ich mich herzlich bei kichi (Michael K.). Vielen Dank auch an Markus Schuster für die Portierung auf Stellaris LM4F120 Launchpad von TI (ARM Cortex M4).
Diskussion
Meinungen, Verbesserungsvorschläge, harsche Kritik und ähnliches kann im Beitrag: Infrared Multi Protocol Decoder geäussert werden.
Viel Spaß mit IRMP!