Browse Source

init checkin

FloKra 2 years ago
commit
f2d09d57fd
6 changed files with 1156 additions and 0 deletions
  1. 50 0
      AutoHotkey/IRRemote.ahk
  2. 48 0
      AutoHotkey/switchToApp.ahk
  3. 175 0
      README.md
  4. BIN
      ir-fb.jpg
  5. BIN
      lib/HID-2.8.2.zip
  6. 883 0
      src/IR-PC-HID-Remote/IR-PC-HID-Remote.ino

+ 50 - 0
AutoHotkey/IRRemote.ahk

@@ -0,0 +1,50 @@
+; Hotkeys für IR Remote
+
+; * beliebige weitere taste
+; ^ CTRL
+; ! ALT
+; # windows key
+; + SHIFT
+; 
+
+; #^!F1::
+; 	;MsgBox You pressed Win+Strg+Alt+F1
+; Return
+; 
+; #^!F2::
+; 	;MsgBox You pressed Win+Strg+Alt+F2
+; Return
+; 	
+; #^!F3::
+; 	;MsgBox You pressed Win+Strg+Alt+F3
+; Return
+; 	
+; #^!F4::
+; 	;MsgBox You pressed Win+Strg+Alt+F4
+; Return
+; 
+; #^!F5::
+; 	;MsgBox You pressed Win+Strg+Alt+F5
+; Return
+; 
+; #^!F6::
+; 	;MsgBox You pressed Win+Strg+Alt+F6
+; Return
+; 
+; #^!F7::
+; 	;MsgBox You pressed Win+Strg+Alt+F7
+; Return
+
+#^!F8::
+	;MsgBox You pressed Win+Strg+Alt+F8
+	Run, switchToApp.ahk SPOTIFY
+Return
+
+; #^!F9::
+; 	MsgBox You pressed Win+Strg+Alt+F9
+; Return
+
+#^!F10::
+	;MsgBox You pressed Win+Strg+Alt+F10
+	Run, switchToApp.ahk KODI
+Return

+ 48 - 0
AutoHotkey/switchToApp.ahk

@@ -0,0 +1,48 @@
+
+NumberOfParameters = %0%
+Loop, %NumberOfParameters%
+{
+   Parameter := %A_Index%
+   
+   if ( !IsLabel( Parameter ) )
+   {
+      ;MsgBox, Parameter "%Parameter%" Not Recognized.
+      Return
+   }
+   
+   GoSub, %Parameter%
+}
+return
+
+
+KODI:
+   ;MsgBox,Kodi
+   Process, Close, spotify.exe
+   Process, Close, vlc.exe
+   Process, Close, MediaMonkey.exe
+   Run "C:\Program Files\Kodi\kodi.exe"
+return
+
+SPOTIFY:
+   ;MsgBox,Spotify
+   Process, Close, kodi.exe
+   Process, Close, MediaMonkey.exe
+   Process, Close, vlc.exe
+   Run "C:\Users\Flo\AppData\Roaming\Spotify\Spotify.exe"
+return
+
+MEDIAMONKEY:
+   ;MsgBox,Spotify
+   Process, Close, kodi.exe
+   Process, Close, spotify.exe
+   Process, Close, vlc.exe
+   Run "C:\Program Files (x86)\MediaMonkey\MediaMonkey.exe"
+return
+
+VLC:
+   ;MsgBox,Spotify
+   Process, Close, kodi.exe
+   Process, Close, spotify.exe
+   Process, Close, MediaMonkey.exe
+   Run "C:\Program Files\VideoLAN\VLC\vlc.exe"
+return

+ 175 - 0
README.md

@@ -0,0 +1,175 @@
+# IR-PC-HID-Remote
+
+Arduino ProMicro/Leonardo (ATmega32U4) basierter IR Empfänger als USB HID Gerät. 
+Sendet alle Tasten direkt als Tastaturkommandos an den PC. 
+
+In habe das an einem Nachmittag/Abend entwickelt um eine vorhandene alte Fernsteuerung einer alten Hauppauge TV-Karte mit meinem mit Windows 10 und KODI betriebenen Media Center PC benutzen zu können. 
+Ursprünglich wollte ich nur einen einfachen Arduino-basierten Empfänger (das Code Example IRrecvDumpV2) aufbauen, der die empfangenen Codes seriell an den PC überträgt, welche dann dort von einem Agent-Programm in Tastencodes umgesetzt werden. 
+
+Tests haben gezeigt, dass das aus verschiedenen Gründen weniger zuverlässig ist, vor allem timingkritische Vorgänge sind auf der MCU besser aufgehoben. Daraus ist dann dieser Arduino-Sketch mit direkter USB-HID-Unterstützung geworden, da ich zufällig noch einen ATmega 32U4 basierten "ProMicro" clone herumliegen hatte. 
+
+Der Code ist simpel gestrickt und die Tastencodes meiner Fernsteuerung sind hard coded. Also eher ein prove-of-concept. 
+
+![](ir-fb.jpg)
+
+
+
+## Hardware
+
+Simpler Aufbau aus einem IR Receiver wie z.B. TSOP38238 und einem Arduino-kompatiblen "ProMicro" MCU Board. Wichtig ist die ATmega 32U4 MCU - nur diese unterstützt den notwendigen USB Modus. 
+
+Anschluss IR-Receiver => MCU-Modul: 
+Output => GPIO-2
+Vcc => 5V
+GND => GND
+
+
+
+## Software
+
+Aufbauend auf das Arduino IRrecvDumpV2 code example. 
+
+### Libraries
+
+- Arduino v1.8.13, Arduino AVR Boards v1.8.3
+- HID-Project v2.8.2
+  Für die USB-HID Kommunikation, da die in Arduino (Stand Arduino IDE v1.8.13 mit Arduino AVR Boards v1.8.3) enthaltenen HID-Funktionen keine Media Keys wie Play/Pause, Stop, etc. unterstützen. 
+- IRRemote v2.0.1
+
+
+
+## Features
+
+- IR codes empfangen, in Tastaturcodes umsetzen und via USB-HID an den angeschlossenen PC senden
+  - Media Keys wie Play/Pause, Stop, Fast-Forward, Rewind... als entsprechende "Media Keyboard" Tastendrücke
+  - Sleep/Herunterfahren durch kurz/lang drücken der Power-Taste
+  - Steuerkreuz auf Pfeiltasten zur Menünavigation
+- die wichtigsten Tasten der Fernbedienung senden die naheliegenden Befehle, 
+- Sondertasten willkürlich festgelegte Tastenkombinationen, z.B. um mit AutoHotkey ein Programm zu starten, wenn die blaue Taste der Fernbedienung gedrückt wurde
+- Mehrfachauslösung bei gehaltener Taste unterdrücken (außer bei bestimmten Tasten)
+
+
+
+## Fernbedienung Hauppauge
+
+Diese Fernbedienung sendet RC5 12-bit Codes. 
+
+RC5-Fernbedienungen wechseln bei jedem Tastendruck ein Togglebit, so dass der "Adressteil" des Codes 2 abwechselnde Werte hat, d.h. dies wechselt bei jedem Tastendruck. Hält man eine Taste gedrückt, wird sie fortlaufend mit dem selben Togglebit erneut gesendet, so dass ein Wechsel eindeutig aussagt, dass die Taste dazwischen losgelassen wurde. 
+
+Die IRremote library erzeugt daraus 3-stellige HEX codes, deren erste Stelle (in meinem Code als Prefix bezeichnet) je nach Status des Togglebit immer 7 oder F ist. 
+
+IR-Code demzufolge: 0x7** oder 0xF** - ** siehe Tabelle
+
+| Fernbedienung                | IR-Code | Tastencode                           |
+| ---------------------------- | ------- | ------------------------------------ |
+| Home/Go                      | BB      | WINDOWS-Taste                        |
+| Power                        | BD      | System Sleep (kurz), Shutdown (lang) |
+| TV                           | 9C      | CTRL+ALT+WIN+F1                      |
+| Videos                       | 98      | CTRL+ALT+WIN+F2                      |
+| Music                        | 99      | CTRL+ALT+WIN+F3                      |
+| Pictures                     | 9A      | CTRL+ALT+WIN+F4                      |
+| Guide                        | 9B      | CTRL+ALT+WIN+F5                      |
+| Radio                        | 8C      | CTRL+ALT+WIN+F6                      |
+| Pfeil nach links ←      | 96      | ←                               |
+| Pfeil nach oben ↑       | 94      | ↑                               |
+| Pfeil nach rechts →     | 97      | →                               |
+| Pfeil nach unten ↓      | 95      | ↓                               |
+| OK                           | A5      | RETURN                               |
+| Back/Exit                    | 9F      | BACKSPACE                            |
+| i/MENU                       | 8D      | ESC                                  |
+| Prev.Ch                      | A4      |                                      |
+| Volume +                     | 90      | MEDIA VOLUME UP  (repeat aktiv)      |
+| Volume -                     | 91      | MEDIA VOLUME DOWN  (repeat aktiv)    |
+| Volume Mute                  | 8F      | MEDIA VOLUME MUTE                    |
+| CH +                         | A0      | PAGE UP                              |
+| CH -                         | A1      | PAGE DOWN                            |
+| ◉  REC                 | B7      |                                      |
+| ◼  STOP                | B6      | MEDIA STOP                           |
+| ►  PLAY                | B5      | MEDIA PLAY/PAUSE                     |
+| ❚❚  PAUSE      | B0      | MEDIA PLAY/PAUSE                     |
+| ◄◄  REWIND       | B2      | MEDIA REWIND  (repeat aktiv)         |
+| ►►  FAST FORWARD | B4      | MEDIA FAST FORWARD  (repeat aktiv)   |
+| ❚◄  PREVIOUS    | A4      | MEDIA PREVIOUS TRACK                 |
+| ►❚  NEXT        | 9E      | MEDIA NEXT TRACK                     |
+| 1                            | 81      | 1                                    |
+| 2                            | 82      | 2                                    |
+| 3                            | 83      | 3                                    |
+| 4                            | 84      | 4                                    |
+| 5                            | 85      | 5                                    |
+| 6                            | 86      | 6                                    |
+| 7                            | 87      | 7                                    |
+| 8                            | 88      | 8                                    |
+| 9                            | 89      | 9                                    |
+| 0                            | 80      | 0                                    |
+| *                            | 8A      |                                      |
+| #                            | 8E      |                                      |
+| RED                          | 8B      | CTRL+ALT+WIN+F7                      |
+| GREEN                        | AE      | CTRL+ALT+WIN+F8                      |
+| YELLOW                       | B8      | CTRL+ALT+WIN+F9                      |
+| BLUE                         | A9      | CTRL+ALT+WIN+F10                     |
+
+
+
+## AutoHotkey
+
+Um Aktionen auf die Tastenkombinationen der Sondertasten auszuführen verwende ich ein simples AHK-Script. 
+
+
+Beispiel: 
+
+```AHK
+
+; * beliebige weitere taste
+; ^ CTRL
+; ! ALT
+; # windows key
+; + SHIFT
+; 
+
+; #^!F1::
+; 	;MsgBox You pressed Win+Strg+Alt+F1
+; Return
+; 
+; #^!F2::
+; 	;MsgBox You pressed Win+Strg+Alt+F2
+; Return
+; 	
+; #^!F3::
+; 	;MsgBox You pressed Win+Strg+Alt+F3
+; Return
+; 	
+; #^!F4::
+; 	;MsgBox You pressed Win+Strg+Alt+F4
+; Return
+; 
+; #^!F5::
+; 	;MsgBox You pressed Win+Strg+Alt+F5
+; Return
+; 
+; #^!F6::
+; 	;MsgBox You pressed Win+Strg+Alt+F6
+; Return
+; 
+; #^!F7::
+; 	;MsgBox You pressed Win+Strg+Alt+F7
+; Return
+
+#^!F8::
+	;MsgBox You pressed Win+Strg+Alt+F8
+	Run, switchToApp.ahk SPOTIFY
+Return
+
+; #^!F9::
+; 	MsgBox You pressed Win+Strg+Alt+F9
+; Return
+
+#^!F10::
+	;MsgBox You pressed Win+Strg+Alt+F10
+	Run, switchToApp.ahk KODI
+Return
+
+
+```
+
+
+

BIN
ir-fb.jpg


BIN
lib/HID-2.8.2.zip


+ 883 - 0
src/IR-PC-HID-Remote/IR-PC-HID-Remote.ino

@@ -0,0 +1,883 @@
+//------------------------------------------------------------------------------
+// Include the IRremote library header
+//
+#include <IRremote.h>
+#include <HID-Project.h>  // HID-Project 2.8.2
+
+
+bool debug = false;
+bool useSerial = false;
+
+#define KEY_1 1
+#define KEY_2 2
+#define KEY_3 3
+#define KEY_4 4
+#define KEY_5 5
+#define KEY_6 6
+#define KEY_7 7
+#define KEY_8 8
+#define KEY_9 9
+#define KEY_0 10
+#define KEY_PLAY 11
+#define KEY_PAUSE 12
+#define KEY_STOP 13
+#define KEY_REC 14
+#define KEY_REWD 15
+#define KEY_FFWD 16
+#define KEY_PREV 17
+#define KEY_NEXT 18
+#define KEY_LEFT 20
+#define KEY_RIGHT 21
+#define KEY_UP 22
+#define KEY_DOWN 23
+#define KEY_OK 24
+#define KEY_BACK 25
+#define KEY_MENU 26
+#define KEY_HOME 26
+#define KEY_RED 30
+#define KEY_GREEN 31
+#define KEY_YELLOW 32
+#define KEY_BLUE 33
+#define KEY_STATUS 34
+#define KEY_RETURN 35
+#define KEY_SETUP 36
+#define KEY_GUIDE 37
+#define KEY_RADIO 38
+#define KEY_PREVCH 39
+#define KEY_CH_DOWN 40
+#define KEY_CH_UP 41
+#define KEY_VOL_DOWN 42
+#define KEY_VOL_UP 43
+#define KEY_MUTE 44
+#define KEY_POWER 45
+#define KEY_TV 46
+#define KEY_VIDEOS 47
+#define KEY_MUSIC 48
+#define KEY_PICTURES 49
+#define KEY_STAR 50
+#define KEY_HASH 51
+#define KEY_RED 52
+#define KEY_YELLOW 53
+#define KEY_GREEN 54
+#define KEY_BLUE 55
+
+#define KEY_DUMMY 255
+
+
+uint8_t lastRC5Pref;
+bool RC5RepeatLastKey = false;
+int repeatInterval = 150;
+unsigned long lastKeypressMillis = 0;;
+
+unsigned long ignoreMillis = 0;
+
+unsigned long powerButton_lastPressedMillis = 0;;
+int powerButton_countRepeats = 0;
+int powerButton_execAfter = 500;
+int ignoreTimeout = 300;
+
+//------------------------------------------------------------------------------
+// Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838)
+//
+int recvPin = 2;
+IRrecv irrecv(recvPin);
+
+//+=============================================================================
+// Configure the Arduino
+//
+void  setup ( )
+{
+  if (useSerial) Serial.begin(115200);
+  Keyboard.begin();
+  Consumer.begin();
+  System.begin();
+  irrecv.enableIRIn();  // Start the receiver
+}
+
+//+=============================================================================
+// Display IR code
+//
+void  ircode (decode_results *results)
+{
+  if (useSerial) {
+    // Panasonic has an Address
+    if (results->decode_type == PANASONIC) {
+      Serial.print(results->address, HEX);
+      Serial.print(":");
+    }
+
+    // Print Code
+    Serial.print(results->value, HEX);
+  }
+}
+
+//+=============================================================================
+// Display encoding type
+//
+void  encoding (decode_results *results)
+{
+  if (useSerial) {
+    switch (results->decode_type) {
+      default:
+      case UNKNOWN:      Serial.print("UNKNOWN");       break ;
+      case NEC:          Serial.print("NEC");           break ;
+      case SONY:         Serial.print("SONY");          break ;
+      case RC5:          Serial.print("RC5");           break ;
+      case RC6:          Serial.print("RC6");           break ;
+      case DISH:         Serial.print("DISH");          break ;
+      case SHARP:        Serial.print("SHARP");         break ;
+      case JVC:          Serial.print("JVC");           break ;
+      case SANYO:        Serial.print("SANYO");         break ;
+      case MITSUBISHI:   Serial.print("MITSUBISHI");    break ;
+      case SAMSUNG:      Serial.print("SAMSUNG");       break ;
+      case LG:           Serial.print("LG");            break ;
+      case WHYNTER:      Serial.print("WHYNTER");       break ;
+      case AIWA_RC_T501: Serial.print("AIWA_RC_T501");  break ;
+      case PANASONIC:    Serial.print("PANASONIC");     break ;
+      case DENON:        Serial.print("DENON");         break ;
+    }
+  }
+}
+
+void printKey() {
+  if (useSerial) {
+    Serial.print(F("KEY_"));
+  }
+}
+void printMedia() {
+  if (useSerial) {
+    Serial.print(F("MEDIA_"));
+  }
+}
+void printArrow() {
+  if (useSerial) {
+    Serial.print(F("ARROW_"));
+  }
+}
+
+
+//+=============================================================================
+// Dump out the decode_results structure.
+//
+void  dumpInfo (decode_results *results)
+{
+  // Check if the buffer overflowed
+  //  if (results->overflow) {
+  //    Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWLEN");
+  //    return;
+  //  }
+
+
+  int resKey = 0;
+
+  // Hauppauge Remote
+  if (results->decode_type == RC5 && results->bits == 12) {
+    // RC5 code
+    // 3 bytes, start byte for this device is 0xF or 0x7 depending on toggle bit
+
+    uint8_t currRC5Code = results->value ^ 0xF00;
+    uint8_t currRC5Pref = ( currRC5Code ^ results->value )  >> 8;
+    uint8_t RC5keyNum;
+
+    //    Serial.print("0x");
+    //    Serial.print(currRC5Pref, HEX);
+    //    Serial.print(" ");
+    //    Serial.print(currRC5Code, HEX);
+    //    Serial.println();
+
+    if (lastRC5Pref != currRC5Pref || RC5RepeatLastKey) {
+      lastRC5Pref = currRC5Pref;
+
+
+      if (currRC5Code == 0xBD) { // POWER
+        bool doit = false;
+        if ((millis() - powerButton_lastPressedMillis) > repeatInterval) {
+          powerButton_lastPressedMillis = millis();
+          doit = true;
+        }
+        if (doit) {
+          RC5RepeatLastKey = true;
+          powerButton_countRepeats++;
+
+          if (useSerial) {
+            printKey();
+            Serial.println(F("POWER"));
+            Serial.print(F("REPEATS:"));
+            Serial.println(powerButton_countRepeats);
+          }
+
+          //System.write(SYSTEM_WAKE_UP);
+
+          if ( powerButton_countRepeats > 10) {
+
+            if (useSerial) {
+              Serial.println(F("POWER_LONG_PRESSED"));
+              Serial.println("sending SYSTEM_POWER_DOWN");
+            }
+            RC5RepeatLastKey = false;
+            powerButton_countRepeats = 0;
+            System.write(SYSTEM_POWER_DOWN);
+          }
+
+          //System.write(SYSTEM_SLEEP);
+
+          //Keyboard.press(KEY_LEFT_ALT);
+          //Keyboard.press(KEY_F4);
+          //delay(50);
+          //Keyboard.releaseAll();
+
+          resKey = KEY_POWER;
+          //powerButton_lastPressedMillis
+          //powerButton_countRepeats
+        }
+      }
+      else if (currRC5Code == 0x90) { // VOL+
+        bool doit = false;
+        if ((millis() - lastKeypressMillis) > repeatInterval) {
+          lastKeypressMillis = millis();
+          doit = true;
+        }
+        if (doit) {
+          RC5RepeatLastKey = true;
+          if (useSerial) {
+            printKey();
+            printMedia();
+            Serial.println(F("VOLUME_UP"));
+          }
+          Consumer.write(MEDIA_VOLUME_UP);
+          resKey = KEY_VOL_UP;
+        }
+      }
+      else if (currRC5Code == 0x91) { // VOL-
+        bool doit = false;
+        if ((millis() - lastKeypressMillis) > repeatInterval) {
+          lastKeypressMillis = millis();
+          doit = true;
+        }
+        if (doit) {
+          RC5RepeatLastKey = true;
+          if (useSerial) {
+            printKey();
+            printMedia();
+            Serial.println(F("VOLUME_DOWN"));
+          }
+          Consumer.write(MEDIA_VOLUME_DOWN);
+          resKey = KEY_VOL_DOWN;
+        }
+      }
+      else if (currRC5Code == 0xB2) { // REWIND
+        bool doit = false;
+        if ((millis() - lastKeypressMillis) > repeatInterval) {
+          lastKeypressMillis = millis();
+          doit = true;
+        }
+        if (doit) {
+          RC5RepeatLastKey = true;
+          if (useSerial) {
+            printKey();
+            printMedia();
+            Serial.println(F("REWIND"));
+          }
+          Consumer.write(MEDIA_REWIND);
+          resKey = KEY_REWD;
+        }
+      }
+      else if (currRC5Code == 0xB4) { // FAST_FORWARD
+        bool doit = false;
+        if ((millis() - lastKeypressMillis) > repeatInterval) {
+          lastKeypressMillis = millis();
+          doit = true;
+        }
+        if (doit) {
+          RC5RepeatLastKey = true;
+          if (useSerial) {
+            printKey();
+            printMedia();
+            Serial.println(F("FAST_FORWARD"));
+          }
+          Consumer.write(MEDIA_FAST_FORWARD);
+          resKey = KEY_FFWD;
+        }
+      }
+
+
+      else if (currRC5Code == 0xA1) { // CH- used as page down
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("CH_DOWN"));
+        }
+        Keyboard.write(KEY_PAGE_DOWN);
+        resKey = KEY_CH_DOWN;
+      }
+      else if (currRC5Code == 0xA0) { // CH+ used as page up
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("CH_UP"));
+        }
+        Keyboard.write(KEY_PAGE_UP);
+        resKey = KEY_CH_UP;
+      }
+      else if (currRC5Code == 0x94) { // ARROW UP
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          printArrow();
+          Serial.println(F("UP"));
+        }
+        Keyboard.write(KEY_UP_ARROW);
+        resKey = KEY_UP;
+      }
+      else if (currRC5Code == 0x95) { // ARROW DOWN
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          printArrow();
+          Serial.println(F("DOWN"));
+        }
+        Keyboard.write(KEY_DOWN_ARROW);
+        resKey = KEY_DOWN;
+      }
+      else if (currRC5Code == 0x96) { // ARROW LEFT
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          printArrow();
+          Serial.println(F("LEFT"));
+        }
+        Keyboard.write(KEY_LEFT_ARROW);
+        resKey = KEY_LEFT;
+      }
+      else if (currRC5Code == 0x97) { // ARROW RIGHT
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          printArrow();
+          Serial.println(F("RIGHT"));
+        }
+        Keyboard.write(KEY_RIGHT_ARROW);
+        resKey = KEY_RIGHT;
+      }
+      else if (currRC5Code == 0xA5) { // OK
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("OK_ENTER"));
+        }
+        Keyboard.write(KEY_ENTER);
+        resKey = KEY_OK;
+      }
+      else if (currRC5Code == 0x9F) { // BACK/EXIT
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("BACK_EXIT"));
+        }
+        Keyboard.write(KEY_BACKSPACE);
+        resKey = KEY_BACK;
+      }
+      else if (currRC5Code == 0x8D) { // i/MENU
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("MENU"));
+        }
+        Keyboard.write(KEY_ESC);
+        resKey = KEY_MENU;
+      }
+      else if (currRC5Code == 0x92) { // PREV.CH
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("PREV_CH"));
+        }
+        resKey = KEY_PREVCH;
+      }
+      else if (currRC5Code == 0x8F) { // MUTE
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          printMedia();
+          Serial.println(F("VOLUME_MUTE"));
+        }
+        Consumer.write(MEDIA_VOLUME_MUTE);
+        resKey = KEY_MUTE;
+      }
+      else if (currRC5Code == 0xBB) { // HOME/GO
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("HOME"));
+        }
+        Keyboard.write(KEY_LEFT_WINDOWS);
+
+        resKey = KEY_HOME;
+      }
+      else if (currRC5Code == 0x9C) { // TV
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("TV"));
+          Serial.println(F("sending CTRL+ALT+WIN+F1"));
+        }
+        Keyboard.press(KEY_LEFT_CTRL);
+        delay(2);
+        Keyboard.press(KEY_LEFT_WINDOWS);
+        delay(2);
+        Keyboard.press(KEY_LEFT_ALT);
+        delay(2);
+        Keyboard.press(KEY_F1);
+        delay(20);
+        Keyboard.releaseAll();
+        resKey = KEY_TV;
+      }
+      else if (currRC5Code == 0x98) { // VIDEOS
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("VIDEOS"));
+          Serial.println(F("sending CTRL+ALT+WIN+F2"));
+        }
+        Keyboard.press(KEY_LEFT_CTRL);
+        delay(2);
+        Keyboard.press(KEY_LEFT_ALT);
+        delay(2);
+        Keyboard.press(KEY_LEFT_WINDOWS);
+        delay(2);
+        Keyboard.press(KEY_F2);
+        delay(20);
+        Keyboard.releaseAll();
+        resKey = KEY_VIDEOS;
+      }
+      else if (currRC5Code == 0x99) { // MUSIC
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("MUSIC"));
+          Serial.println(F("sending CTRL+ALT+WIN+F3"));
+        }
+        Keyboard.press(KEY_LEFT_CTRL);
+        delay(2);
+        Keyboard.press(KEY_LEFT_ALT);
+        delay(2);
+        Keyboard.press(KEY_LEFT_WINDOWS);
+        delay(2);
+        Keyboard.press(KEY_F3);
+        delay(20);
+        Keyboard.releaseAll();
+        resKey = KEY_MUSIC;
+      }
+      else if (currRC5Code == 0x9A) { // PICTURES
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("PICTURES"));
+          Serial.println(F("sending CTRL+ALT+WIN+F4"));
+        }
+        Keyboard.press(KEY_LEFT_CTRL);
+        delay(2);
+        Keyboard.press(KEY_LEFT_WINDOWS);
+        delay(2);
+        Keyboard.press(KEY_LEFT_ALT);
+        delay(2);
+        Keyboard.press(KEY_F4);
+        delay(20);
+        Keyboard.releaseAll();
+        resKey = KEY_PICTURES;
+      }
+      else if (currRC5Code == 0x9B) { // GUIDE
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("GUIDE"));
+          Serial.println(F("sending CTRL+ALT+WIN+F5"));
+        }
+        Keyboard.press(KEY_LEFT_CTRL);
+        delay(2);
+        Keyboard.press(KEY_LEFT_ALT);
+        delay(2);
+        Keyboard.press(KEY_LEFT_WINDOWS);
+        delay(2);
+        Keyboard.press(KEY_F5);
+        delay(20);
+        Keyboard.releaseAll();
+        resKey = KEY_GUIDE;
+      }
+      else if (currRC5Code == 0x8C) { // RADIO
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("RADIO"));
+          Serial.println(F("sending CTRL+ALT+WIN+F6"));
+        }
+        Keyboard.press(KEY_LEFT_CTRL);
+        delay(2);
+        Keyboard.press(KEY_LEFT_ALT);
+        delay(2);
+        Keyboard.press(KEY_LEFT_WINDOWS);
+        delay(2);
+        Keyboard.press(KEY_F6);
+        delay(20);
+        Keyboard.releaseAll();
+        resKey = KEY_RADIO;
+      }
+      else if (currRC5Code == 0xB7) { // REC
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          printMedia();
+          Serial.println(F("RECORD"));
+        }
+        resKey = KEY_REC;
+        //Consumer.write(MEDIA_STOP);
+      }
+      else if (currRC5Code == 0xB6) { // STOP
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          printMedia();
+          Serial.println(F("STOP"));
+        }
+        resKey = KEY_STOP;
+        Consumer.write(MEDIA_STOP);
+      }
+      else if (currRC5Code == 0xB5) { // PLAY
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          printMedia();
+          Serial.println(F("PLAY"));
+        }
+        resKey = KEY_PLAY;
+        Consumer.write(MEDIA_PLAY_PAUSE);
+      }
+      else if (currRC5Code == 0xB0) { // PAUSE
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          printMedia();
+          Serial.println(F("PAUSE"));
+        }
+        resKey = KEY_PAUSE;
+        Consumer.write(MEDIA_PLAY_PAUSE);
+      }
+      else if (currRC5Code == 0xA4) { // PREV
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          printMedia();
+          Serial.println(F("PREVIOUS"));
+        }
+        Consumer.write(MEDIA_PREVIOUS);
+        resKey = KEY_PREV;
+      }
+      else if (currRC5Code == 0x9E) { // NEXT
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          printMedia();
+          Serial.println(F("NEXT"));
+        }
+        Consumer.write(MEDIA_NEXT);
+        resKey = KEY_NEXT;
+      }
+      else if (currRC5Code == 0x81) { // 1
+        RC5RepeatLastKey = false;
+        Keyboard.write('1');
+        if (useSerial) {
+          printKey();
+          Serial.println("1");
+        }
+        resKey = KEY_1;
+      }
+      else if (currRC5Code == 0x82) { // 2
+        RC5RepeatLastKey = false;
+        Keyboard.write('2');
+        if (useSerial) {
+          printKey();
+          Serial.println("2");
+        }
+        resKey = KEY_2;
+      }
+      else if (currRC5Code == 0x83) { // 3
+        RC5RepeatLastKey = false;
+        Keyboard.write('3');
+        if (useSerial) {
+          printKey();
+          Serial.println("3");
+        }
+        resKey = KEY_3;
+      }
+      else if (currRC5Code == 0x84) { // 4
+        RC5RepeatLastKey = false;
+        Keyboard.write('4');
+        if (useSerial) {
+          printKey();
+          Serial.println("4");
+        }
+        resKey = KEY_4;
+      }
+      else if (currRC5Code == 0x85) { // 5
+        RC5RepeatLastKey = false;
+        Keyboard.write('5');
+        if (useSerial) {
+          printKey();
+          Serial.println("5");
+        }
+        resKey = KEY_5;
+      }
+      else if (currRC5Code == 0x86) { // 6
+        RC5RepeatLastKey = false;
+        Keyboard.write('6');
+        if (useSerial) {
+          printKey();
+          Serial.println("6");
+        }
+        resKey = KEY_6;
+      }
+      else if (currRC5Code == 0x87) { // 7
+        RC5RepeatLastKey = false;
+        Keyboard.write('7');
+        if (useSerial) {
+          printKey();
+          Serial.println("7");
+        }
+        resKey = KEY_7;
+      }
+      else if (currRC5Code == 0x88) { // 8
+        RC5RepeatLastKey = false;
+        Keyboard.write('8');
+        if (useSerial) {
+          printKey();
+          Serial.println("8");
+        }
+        resKey = KEY_8;
+      }
+      else if (currRC5Code == 0x89) { // 9
+        RC5RepeatLastKey = false;
+        Keyboard.write('9');
+        if (useSerial) {
+          printKey();
+          Serial.println("9");
+        }
+        resKey = KEY_9;
+      }
+      else if (currRC5Code == 0x80) { // 0
+        RC5RepeatLastKey = false;
+        Keyboard.write('0');
+        if (useSerial) {
+          printKey();
+          Serial.println("0");
+        }
+        resKey = KEY_0;
+      }
+      else if (currRC5Code == 0x8A) { // *
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("STAR"));
+        }
+        resKey = KEY_STAR;
+      }
+      else if (currRC5Code == 0x8E) { // #
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("HASH"));
+        }
+        resKey = KEY_HASH;
+      }
+      else if (currRC5Code == 0x8B) { // RED
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("RED"));
+          Serial.println("sending CTRL+ALT+WIN+F7");
+        }
+        Keyboard.press(KEY_LEFT_CTRL);
+        Keyboard.press(KEY_LEFT_ALT);
+        Keyboard.press(KEY_LEFT_WINDOWS);
+        Keyboard.press(KEY_F7);
+        delay(50);
+        Keyboard.releaseAll();
+
+        resKey = KEY_RED;
+      }
+      else if (currRC5Code == 0xAE) { // GREEN
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("GREEN"));
+          Serial.println(F("sending CTRL+ALT+WIN+F8"));
+        }
+        Keyboard.press(KEY_LEFT_CTRL);
+        Keyboard.press(KEY_LEFT_ALT);
+        Keyboard.press(KEY_LEFT_WINDOWS);
+        Keyboard.press(KEY_F8);
+        delay(50);
+        Keyboard.releaseAll();
+
+        resKey = KEY_GREEN;
+      }
+      else if (currRC5Code == 0xB8) { // YELLOW
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("YELLOW"));
+          Serial.println(F("sending CTRL+ALT+WIN+F9"));
+        }
+        Keyboard.press(KEY_LEFT_CTRL);
+        Keyboard.press(KEY_LEFT_ALT);
+        Keyboard.press(KEY_LEFT_WINDOWS);
+        Keyboard.press(KEY_F9);
+        delay(50);
+        Keyboard.releaseAll();
+
+        resKey = KEY_YELLOW;
+      }
+      else if (currRC5Code == 0xA9) { // BLUE
+        //0xFA9 0x7A9
+        RC5RepeatLastKey = false;
+        if (useSerial) {
+          printKey();
+          Serial.println(F("BLUE"));
+          Serial.println("sending CTRL+ALT+WIN+F10");
+        }
+        Keyboard.press(KEY_LEFT_CTRL);
+        Keyboard.press(KEY_LEFT_ALT);
+        Keyboard.press(KEY_LEFT_WINDOWS);
+        Keyboard.press(KEY_F10);
+        delay(50);
+        Keyboard.releaseAll();
+
+        resKey = KEY_BLUE;
+      }
+
+    }
+  }
+
+
+  // DENON RC-1014 REMOTE, Mode AUDIO/CD, MEDIA KEYS (set to SONY CD Player)
+  else if (results->decode_type == SONY && results->bits == 12) {
+    if (results->value == 0x9D1) { // PAUSE
+      if (useSerial) {
+        printKey();
+        printMedia();
+        Serial.println(F("PAUSE"));
+      }
+      resKey = KEY_PAUSE;
+      Consumer.write(MEDIA_PLAY_PAUSE);
+      ignoreMillis = millis(); // set to ignore input for a moment to avoid repetations
+    }
+    else if (results->value == 0xCD1) { // REWD
+      if (useSerial) {
+        printKey();
+        printMedia();
+        Serial.println(F("REWIND"));
+      }
+      Consumer.write(MEDIA_REWIND);
+      resKey = KEY_REWD;
+      ignoreMillis = millis(); // set to ignore input for a moment to avoid repetations
+    }
+    else if (results->value == 0x2D1) { // FFWD
+      if (useSerial) {
+        printKey();
+        printMedia();
+        Serial.println(F("FAST_FORWARD"));
+      }
+      Consumer.write(MEDIA_FAST_FORWARD);
+      resKey = KEY_FFWD;
+      ignoreMillis = millis(); // set to ignore input for a moment to avoid repetations
+    }
+    else if (results->value == 0xD1) { // PREV
+      if (useSerial) {
+        printKey();
+        printMedia();
+        Serial.println(F("PREVIOUS"));
+      }
+      Consumer.write(MEDIA_PREVIOUS);
+      ignoreMillis = millis(); // set to ignore input for a moment to avoid repetations
+    }
+    else if (results->value == 0x8D1) { // NEXT
+      if (useSerial) {
+        printKey();
+        printMedia();
+        Serial.println(F("NEXT"));
+      }
+      Consumer.write(MEDIA_NEXT);
+      resKey = KEY_NEXT;
+      ignoreMillis = millis(); // set to ignore input for a moment to avoid repetations
+    }
+    else if (results->value == 0x4D1) { // PLAY
+      if (useSerial) {
+        printKey();
+        printMedia();
+        Serial.println(F("PLAY"));
+      }
+      resKey = KEY_PLAY;
+      Consumer.write(MEDIA_PLAY_PAUSE);
+      ignoreMillis = millis(); // set to ignore input for a moment to avoid repetations
+    }
+    else if (results->value == 0x1D1) { // STOP
+      if (useSerial) {
+        printKey();
+        printMedia();
+        Serial.println(F("STOP"));
+      }
+      resKey = KEY_STOP;
+      Consumer.write(MEDIA_STOP);
+      ignoreMillis = millis(); // set to ignore input for a moment to avoid repetations
+    }
+  }
+
+
+  //if (resKey == 0 && results->decode_type != UNKNOWN) {
+  if ((resKey == 0 && results->decode_type != UNKNOWN && results->bits > 0) && debug) {
+    if (useSerial) {
+      encoding(results);
+      Serial.print(";0x");
+      ircode(results);
+      Serial.print(";");
+      Serial.print(results->bits, DEC);
+      Serial.println();
+      Serial.println();
+    }
+  }
+
+}
+
+
+//+=============================================================================
+// The repeating section of the code
+//
+void  loop ( )
+{
+  decode_results  results;        // Somewhere to store the results
+
+  if (irrecv.decode(&results)) {  // Grab an IR code
+    if ((millis() - ignoreMillis) > ignoreTimeout) dumpInfo(&results);          // Output the results (if not in ignore time window)
+    irrecv.resume();              // Prepare for the next value
+  }
+
+  // handle Power Button short press
+  if (powerButton_countRepeats > 0 && (millis() - powerButton_lastPressedMillis) > powerButton_execAfter) {
+    if (powerButton_countRepeats > 2) {
+      if (useSerial) {
+        Serial.println("POWER_SHORT_PRESSED");
+        Serial.println("sending SYSTEM_SLEEP");
+      }
+      System.write(SYSTEM_SLEEP);
+    }
+    //    else {
+    //      Serial.println("POWER_VERY_SHORT_PRESSED");
+    //      Serial.println("sending ALT+F4");
+    //      Keyboard.press(KEY_LEFT_ALT);
+    //      Keyboard.press(KEY_F4);
+    //      delay(50);
+    //      Keyboard.releaseAll();
+    //    }
+    RC5RepeatLastKey = false;
+    powerButton_countRepeats = 0;
+  }
+}