Browse Source

- HOLD-Mode bei RC5/RC6: anstatt repeats zu senden (eigene Keyboard Tastendrücke) wird bei Tasten, die auf "HOLD" konfiguriert sind die Taste nicht sofort (virtuall) losgelassen. Wird die Taste der Fernbedienung weiter gehalten so bleibt die virtuelle Keyboardtaste gedrückt, bis die FB-Taste losgelassen wurde (mit timeout).
- HOLD-Mode auch für OK/ENTER und BACK: ermöglicht in Kodi das Kontextmenü bzw. das Shutdown-Menü per langem Tastendruck zu erreichen

FloKra 2 years ago
parent
commit
6614155553

+ 7 - 0
CHANGELOG.md

@@ -1,3 +1,10 @@
+- 2022-01-07
+
+  - HOLD-Mode bei RC5/RC6: anstatt repeats zu senden (eigene Keyboard Tastendrücke) wird bei Tasten, die auf "HOLD" konfiguriert sind die Taste nicht sofort (virtuall) losgelassen. Wird die Taste der Fernbedienung weiter gehalten so bleibt die virtuelle Keyboardtaste gedrückt, bis die FB-Taste losgelassen wurde (mit timeout). 
+    - HOLD-Mode auch für OK/ENTER und BACK: ermöglicht in Kodi das Kontextmenü bzw. das Shutdown-Menü per langem Tastendruck zu erreichen
+  
+  
+  
 - 2022-01-04
 
   - Weiterentwicklung, um verschiedene Fernsteuerungen zu unterstützen, z.B. Pioneer und NEC

+ 16 - 3
README.md

@@ -12,11 +12,24 @@ Daher habe ich mich dann entschieden, die Sondertasten einfach Tastenkombination
 
 Der Code ist simpel gestrickt und die Tastencodes meiner Fernsteuerung sind hard coded. Also eher ein prove-of-concept. 
 
-Update 01/2022:
 
-Unterstützung für RC5/RC6-Fernbedienungen verbessert, Power-Button Handling verbessert, TaskSwitch-Handling neu (ALT+TAB), bessere Unterstützung für verschiedene IR-Codes gleichzeitig, z.B. Pioneer und NEC. 
 
-Mehrfachauslösung wird nun in mehreren Stufen schneller, bei guter Response des einzelnen Tastendrucks (zumindest bei RC5/RC6 Remotes).
+Update 05.01.2022:
+
+- Unterstützung für RC5/RC6-Fernbedienungen verbessert, Power-Button Handling verbessert, TaskSwitch-Handling neu (ALT+TAB), bessere Unterstützung für verschiedene IR-Codes gleichzeitig, z.B. Pioneer und NEC. 
+
+- Mehrfachauslösung wird nun in mehreren Stufen schneller, bei guter Response des einzelnen Tastendrucks (zumindest bei RC5/RC6 Remotes).
+
+
+
+Update 07.01.2022:
+
+- HOLD-Mode bei RC5/RC6: anstatt repeats zu senden (eigene Keyboard Tastendrücke) wird bei Tasten, die auf "HOLD" konfiguriert sind die Taste nicht sofort (virtuall) losgelassen. Wird die Taste der Fernbedienung weiter gehalten so bleibt die virtuelle Keyboardtaste gedrückt, bis die FB-Taste losgelassen wurde (mit timeout). 
+- HOLD-Mode auch für OK/ENTER und BACK: ermöglicht in Kodi das Kontextmenü bzw. das Shutdown-Menü per langem Tastendruck zu erreichen
+
+
+
+
 
 [CHANGELOG](CHANGELOG.md)
 

+ 108 - 76
src/IR-PC-HID-Remote/IR-PC-HID-Remote.ino

@@ -12,6 +12,10 @@ bool debug = false;
 bool debug2 = false;
 bool useSerial = false;
 
+// global conf vars
+unsigned int holdButton_releaseTimeout = 120;
+
+
 #define BTN_1 1
 #define BTN_2 2
 #define BTN_3 3
@@ -68,9 +72,19 @@ bool useSerial = false;
 #define BTN_DUMMY 255
 
 
+// Button Modes
+#define BUTTONMODE_ONCE 0
+#define BUTTONMODE_REPEAT 1
+#define BUTTONMODE_HOLD 2
 
+// Remote Types
+#define REMOTETYPE_RC5 0
+#define REMOTETYPE_RC6 1
+
+// global vars
 unsigned long lastNECcode;
 unsigned long lastReceivedMillis;
+unsigned long holdButton_lastTriggeredMillis = 0;
 
 
 //------------------------------------------------------------------------------
@@ -138,141 +152,153 @@ void  dumpInfo (decode_results *results)
 
     // Hauppauge Remote
     if (_currRC5Code == 0xBD) { // POWER
-      //handleButton_RCx(BTN_POWER, true, _currRC5Pref);
+      //handleButton_RCx(BTN_POWER, BUTTONMODE_REPEAT, _currRC5Pref, REMOTETYPE_RC5);
       handlePowerButton();
     }
     else if (_currRC5Code == 0x90) { // VOL+
-      handleButton_RCx(BTN_VOL_UP, true, _currRC5Pref);
+      //handleButton_RCx(BTN_VOL_UP, BUTTONMODE_REPEAT, _currRC5Pref, REMOTETYPE_RC5);
+      handleButton_RCx(BTN_VOL_UP, BUTTONMODE_HOLD, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x91) { // VOL-
-      handleButton_RCx(BTN_VOL_DOWN, true, _currRC5Pref);
+      //handleButton_RCx(BTN_VOL_DOWN, BUTTONMODE_REPEAT, _currRC5Pref, REMOTETYPE_RC5);
+      handleButton_RCx(BTN_VOL_DOWN, BUTTONMODE_HOLD, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0xB2) { // REWIND
-      handleButton_RCx(BTN_REWD, true, _currRC5Pref);
+      //handleButton_RCx(BTN_REWD, BUTTONMODE_REPEAT, _currRC5Pref, REMOTETYPE_RC5);
+      //handleButton_RCx(BTN_REWD, BUTTONMODE_HOLD, _currRC5Pref, REMOTETYPE_RC5);
+      handleButton_RCx(BTN_REWD, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0xB4) { // FAST_FORWARD
-      handleButton_RCx(BTN_FFWD, true, _currRC5Pref);
+      //handleButton_RCx(BTN_FFWD, BUTTONMODE_REPEAT, _currRC5Pref, REMOTETYPE_RC5);
+      //handleButton_RCx(BTN_FFWD, BUTTONMODE_HOLD, _currRC5Pref, REMOTETYPE_RC5);
+      handleButton_RCx(BTN_FFWD, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0xA1) { // CH- used as page down
-      handleButton_RCx(BTN_CH_DOWN, false, _currRC5Pref);
+      handleButton_RCx(BTN_CH_DOWN, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0xA0) { // CH+ used as page up
-      handleButton_RCx(BTN_CH_UP, false, _currRC5Pref);
+      handleButton_RCx(BTN_CH_UP, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x94) { // ARROW UP
-      handleButton_RCx(BTN_UP, true, _currRC5Pref);
+      //handleButton_RCx(BTN_UP, BUTTONMODE_REPEAT, _currRC5Pref, REMOTETYPE_RC5);
+      handleButton_RCx(BTN_UP, BUTTONMODE_HOLD, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x95) { // ARROW DOWN
-      handleButton_RCx(BTN_DOWN, true, _currRC5Pref);
+      //handleButton_RCx(BTN_DOWN, BUTTONMODE_REPEAT, _currRC5Pref, REMOTETYPE_RC5);
+      handleButton_RCx(BTN_DOWN, BUTTONMODE_HOLD, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x96) { // ARROW LEFT
-      handleButton_RCx(BTN_LEFT, true, _currRC5Pref);
+      //handleButton_RCx(BTN_LEFT, BUTTONMODE_REPEAT, _currRC5Pref, REMOTETYPE_RC5);
+      handleButton_RCx(BTN_LEFT, BUTTONMODE_HOLD, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x97) { // ARROW RIGHT
-      handleButton_RCx(BTN_RIGHT, true, _currRC5Pref);
+      //handleButton_RCx(BTN_RIGHT, BUTTONMODE_REPEAT, _currRC5Pref, REMOTETYPE_RC5);
+      handleButton_RCx(BTN_RIGHT, BUTTONMODE_HOLD, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0xA5) { // OK
-      handleButton_RCx(BTN_OK_ENTER, false, _currRC5Pref);
+      //handleButton_RCx(BTN_OK_ENTER, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
+      handleButton_RCx(BTN_OK_ENTER, BUTTONMODE_HOLD, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x9F) { // BACK/EXIT
-      handleButton_RCx(BTN_BACK, false, _currRC5Pref);
+      //handleButton_RCx(BTN_BACK, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
+      handleButton_RCx(BTN_BACK, BUTTONMODE_HOLD, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x8D) { // i/MENU
-      handleButton_RCx(BTN_MENU, false, _currRC5Pref);
+      handleButton_RCx(BTN_MENU, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x92) { // PREV.CH
-      handleButton_RCx(BTN_CONTEXT, false, _currRC5Pref);
+      handleButton_RCx(BTN_CONTEXT, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x8F) { // MUTE
-      handleButton_RCx(BTN_MUTE, false, _currRC5Pref);
+      handleButton_RCx(BTN_MUTE, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0xBB) { // HOME/GO
-      //handleButton_RCx(BTN_HOME, false, _currRC5Pref);
+      //handleButton_RCx(BTN_HOME, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
       handleTaskSwitchButton();
     }
     else if (_currRC5Code == 0x9C) { // TV
-      handleButton_RCx(BTN_TV, false, _currRC5Pref);
+      handleButton_RCx(BTN_TV, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x98) { // VIDEOS
-      handleButton_RCx(BTN_VIDEOS, false, _currRC5Pref);
+      handleButton_RCx(BTN_VIDEOS, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x99) { // MUSIC
-      handleButton_RCx(BTN_MUSIC, false, _currRC5Pref);
+      handleButton_RCx(BTN_MUSIC, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x9A) { // PICTURES
-      handleButton_RCx(BTN_PICTURES, false, _currRC5Pref);
+      handleButton_RCx(BTN_PICTURES, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x9B) { // GUIDE
-      handleButton_RCx(BTN_GUIDE, false, _currRC5Pref);
+      handleButton_RCx(BTN_GUIDE, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x8C) { // RADIO
-      handleButton_RCx(BTN_RADIO, false, _currRC5Pref);
+      handleButton_RCx(BTN_RADIO, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0xB7) { // REC
-      handleButton_RCx(BTN_REC, false, _currRC5Pref);
+      handleButton_RCx(BTN_REC, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0xB6) { // STOP
-      handleButton_RCx(BTN_STOP, false, _currRC5Pref);
+      handleButton_RCx(BTN_STOP, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0xB5) { // PLAY
-      handleButton_RCx(BTN_PLAY, false, _currRC5Pref);
+      handleButton_RCx(BTN_PLAY, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0xB0) { // PAUSE
-      handleButton_RCx(BTN_PAUSE, false, _currRC5Pref);
+      handleButton_RCx(BTN_PAUSE, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0xA4) { // PREV
-      handleButton_RCx(BTN_PREV, false, _currRC5Pref);
+      handleButton_RCx(BTN_PREV, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x9E) { // NEXT
-      handleButton_RCx(BTN_NEXT, false, _currRC5Pref);
+      handleButton_RCx(BTN_NEXT, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x81) { // 1
-      handleButton_RCx(BTN_1, false, _currRC5Pref);
+      handleButton_RCx(BTN_1, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x82) { // 2
-      handleButton_RCx(BTN_2, false, _currRC5Pref);
+      handleButton_RCx(BTN_2, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x83) { // 3
-      handleButton_RCx(BTN_3, false, _currRC5Pref);
+      handleButton_RCx(BTN_3, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x84) { // 4
-      handleButton_RCx(BTN_4, false, _currRC5Pref);
+      handleButton_RCx(BTN_4, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x85) { // 5
-      handleButton_RCx(BTN_5, false, _currRC5Pref);
+      handleButton_RCx(BTN_5, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x86) { // 6
-      handleButton_RCx(BTN_6, false, _currRC5Pref);
+      handleButton_RCx(BTN_6, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x87) { // 7
-      handleButton_RCx(BTN_7, false, _currRC5Pref);
+      handleButton_RCx(BTN_7, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x88) { // 8
-      handleButton_RCx(BTN_8, false, _currRC5Pref);
+      handleButton_RCx(BTN_8, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x89) { // 9
-      handleButton_RCx(BTN_9, false, _currRC5Pref);
+      handleButton_RCx(BTN_9, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x80) { // 0
-      handleButton_RCx(BTN_0, false, _currRC5Pref);
+      handleButton_RCx(BTN_0, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x8A) { // *
-      handleButton_RCx(BTN_STAR, false, _currRC5Pref);
+      handleButton_RCx(BTN_STAR, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x8E) { // #
-      handleButton_RCx(BTN_HASH, false, _currRC5Pref);
+      handleButton_RCx(BTN_HASH, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0x8B) { // RED
-      handleButton_RCx(BTN_RED, false, _currRC5Pref);
+      handleButton_RCx(BTN_RED, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0xAE) { // GREEN
-      handleButton_RCx(BTN_GREEN, false, _currRC5Pref);
+      handleButton_RCx(BTN_GREEN, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0xB8) { // YELLOW
-      handleButton_RCx(BTN_YELLOW, false, _currRC5Pref);
+      handleButton_RCx(BTN_YELLOW, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
     else if (_currRC5Code == 0xA9) { // BLUE
-      handleButton_RCx(BTN_BLUE, false, _currRC5Pref);
+      handleButton_RCx(BTN_BLUE, BUTTONMODE_ONCE, _currRC5Pref, REMOTETYPE_RC5);
     }
 
   } // END RC5 CODES
@@ -327,88 +353,94 @@ void  dumpInfo (decode_results *results)
     // Missing buttons configured using learning function, which does not work well with RCx format due to the toggle bit,
     // so i used an old unused IR remote with NEC code for these, which will be OK for non-repeating buttons.
     if (_currRC6Code == 0x270C) { // POWER (of SOURCE)
-      //handleButton_RCx(BTN_POWER, true, _currRC6Pref);
+      //handleButton_RCx(BTN_POWER, BUTTONMODE_REPEAT, _currRC6Pref, REMOTETYPE_RC6);
       handlePowerButton();
     }
     else if (_currRC6Code == 0x275C) { // OK/ENTER
-      handleButton_RCx(BTN_OK_ENTER, false, _currRC6Pref);
+      //handleButton_RCx(BTN_OK_ENTER, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
+      handleButton_RCx(BTN_OK_ENTER, BUTTONMODE_HOLD, _currRC6Pref, REMOTETYPE_RC6);
+    }
+    else if (_currRC6Code == 0x2783) { // RETURN/BACK - bottom right at control pad
+      //handleButton_RCx(BTN_BACK, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
+      handleButton_RCx(BTN_BACK, BUTTONMODE_HOLD, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x275A) { // LEFT
-      handleButton_RCx(BTN_LEFT, true, _currRC6Pref);
+      //handleButton_RCx(BTN_LEFT, BUTTONMODE_REPEAT, _currRC6Pref, REMOTETYPE_RC6);
+      handleButton_RCx(BTN_LEFT, BUTTONMODE_HOLD, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x275B) { // RIGHT
-      handleButton_RCx(BTN_RIGHT, true, _currRC6Pref);
+      //handleButton_RCx(BTN_RIGHT, BUTTONMODE_REPEAT, _currRC6Pref, REMOTETYPE_RC6);
+      handleButton_RCx(BTN_RIGHT, BUTTONMODE_HOLD, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2758) { // UP
-      handleButton_RCx(BTN_UP, true, _currRC6Pref);
+      //handleButton_RCx(BTN_UP, BUTTONMODE_REPEAT, _currRC6Pref, REMOTETYPE_RC6);
+      handleButton_RCx(BTN_UP, BUTTONMODE_HOLD, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2759) { // DOWN
-      handleButton_RCx(BTN_DOWN, true, _currRC6Pref);
+      //handleButton_RCx(BTN_DOWN, BUTTONMODE_REPEAT, _currRC6Pref, REMOTETYPE_RC6);
+      handleButton_RCx(BTN_DOWN, BUTTONMODE_HOLD, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x27CC) { // HOME MENU - bottom left at control pad
-      handleButton_RCx(BTN_MENU, false, _currRC6Pref);
-    }
-    else if (_currRC6Code == 0x2783) { // RETURN/BACK - bottom right at control pad
-      handleButton_RCx(BTN_BACK, false, _currRC6Pref);
+      handleButton_RCx(BTN_MENU, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2743) { // X - AUDIO PARAMETER - top left at control pad
-      //handleButton_RCx(BTN_HOME, false, _currRC6Pref);
+      //handleButton_RCx(BTN_HOME, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
       handleTaskSwitchButton();
     }
     else if (_currRC6Code == 0x2754) { // VIDEO PARAMETER - top right at control pad
-      //handleButton_RCx(BTN_MENU, false, _currRC6Pref);
-      handleButton_RCx(BTN_CONTEXT, false, _currRC6Pref);
+      //handleButton_RCx(BTN_MENU, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
+      handleButton_RCx(BTN_CONTEXT, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2771) { // PLAY
-      handleButton_RCx(BTN_PLAY, false, _currRC6Pref);
+      handleButton_RCx(BTN_PLAY, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x276F) { // PAUSE
-      handleButton_RCx(BTN_PAUSE, false, _currRC6Pref);
+      handleButton_RCx(BTN_PAUSE, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x276E) { // STOP
-      handleButton_RCx(BTN_STOP, false, _currRC6Pref);
+      handleButton_RCx(BTN_STOP, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x276D) { // PREVIOUS
-      handleButton_RCx(BTN_PREV, false, _currRC6Pref);
+      handleButton_RCx(BTN_PREV, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2770) { // NEXT
-      handleButton_RCx(BTN_NEXT, false, _currRC6Pref);
+      handleButton_RCx(BTN_NEXT, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2701) { // 1
-      handleButton_RCx(BTN_1, false, _currRC6Pref);
+      handleButton_RCx(BTN_1, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2702) { // 2
-      handleButton_RCx(BTN_2, false, _currRC6Pref);
+      handleButton_RCx(BTN_2, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2703) { // 3
-      handleButton_RCx(BTN_3, false, _currRC6Pref);
+      handleButton_RCx(BTN_3, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2704) { // 4
-      handleButton_RCx(BTN_4, false, _currRC6Pref);
+      handleButton_RCx(BTN_4, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2705) { // 5
-      handleButton_RCx(BTN_5, false, _currRC6Pref);
+      handleButton_RCx(BTN_5, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2706) { // 6
-      handleButton_RCx(BTN_6, false, _currRC6Pref);
+      handleButton_RCx(BTN_6, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2707) { // 7
-      handleButton_RCx(BTN_7, false, _currRC6Pref);
+      handleButton_RCx(BTN_7, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2708) { // 8
-      handleButton_RCx(BTN_8, false, _currRC6Pref);
+      handleButton_RCx(BTN_8, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2709) { // 9
-      handleButton_RCx(BTN_9, false, _currRC6Pref);
+      handleButton_RCx(BTN_9, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2700) { // 0
-      handleButton_RCx(BTN_0, false, _currRC6Pref);
+      handleButton_RCx(BTN_0, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2720) { // CH+
-      handleButton_RCx(BTN_CH_UP, false, _currRC6Pref);
+      handleButton_RCx(BTN_CH_UP, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
     else if (_currRC6Code == 0x2721) { // CH-
-      handleButton_RCx(BTN_CH_DOWN, false, _currRC6Pref);
+      handleButton_RCx(BTN_CH_DOWN, BUTTONMODE_ONCE, _currRC6Pref, REMOTETYPE_RC6);
     }
 
     // Buttons in NEC CODE due to limitations of this RC:
@@ -602,5 +634,5 @@ void  loop ( )
 
   handlePowerButton_loop();
   handleTaskSwitchButton_loop();
-
+  handleHoldButtons_loop(); // release all keys after timeout
 }

+ 7 - 6
src/IR-PC-HID-Remote/handleButton.ino

@@ -37,16 +37,17 @@ unsigned long handleButton_repeatMillis;
 #define HANDLEBUTTON_REPEAT_TIMEOUT_0 560         // should be slightly more than 3 transmits of the slowest RC used, so min. 560 for the Pioneer RC
 #define HANDLEBUTTON_MAX_REPEATED_RECEIVE_MS_0 200  // slightly more than one transmit, used to detect repetitions
 #define HANDLEBUTTON_AVOID_REPEAT_DELAY_0 200     // must be more than one transmits time or repeats could occur also on buttons configured as repeat=false
-
+#define HANDLEBUTTON_HOLD_TIMEOUT_0 150
 
 #define HANDLEBUTTON_REPEAT_TIMEOUT_1 130         // should be slightly more than 3 transmits of the slowest RC used, so min. 560 for the Pioneer RC
 #define HANDLEBUTTON_MAX_REPEATED_RECEIVE_MS_1 120  // slightly more than one transmit, used to detect repetitions
 #define HANDLEBUTTON_AVOID_REPEAT_DELAY_1 100     // must be more than one transmits time or repeats could occur also on buttons configured as repeat=false
-
+#define HANDLEBUTTON_HOLD_TIMEOUT_1 150
 
 #define HANDLEBUTTON_REPEAT_TIMEOUT_2 120         // should be slightly more than 3 transmits of the slowest RC used, so min. 560 for the Pioneer RC
 #define HANDLEBUTTON_MAX_REPEATED_RECEIVE_MS_2 110  // slightly more than one transmit, used to detect repetitions
 #define HANDLEBUTTON_AVOID_REPEAT_DELAY_2 100     // must be more than one transmits time or repeats could occur also on buttons configured as repeat=false
+#define HANDLEBUTTON_HOLD_TIMEOUT_2 150
 
 unsigned int handleButton_lastKey_countRepeats = 0;
 
@@ -113,7 +114,7 @@ void handleButton(uint8_t _key, bool _repeat, uint8_t _rcType) {
 
       if ( (millis() - handleButton_repeatMillis) >= HANDLEBUTTON_FIRST_REPEAT_INTERVAL) {
         // slow repeats
-        sendKey(_key);
+        sendKey(_key, false);
         if (debug2) {
           Serial.print(F("    SLOW REPEAT  "));
         }
@@ -123,7 +124,7 @@ void handleButton(uint8_t _key, bool _repeat, uint8_t _rcType) {
       }
       else if ( handleButton_lastKey_countRepeats >= HANDLEBUTTON_SLOW_REPEATS && (millis() - handleButton_repeatMillis) >= _minRepeatInterval) {
         // fast repeats
-        sendKey(_key);
+        sendKey(_key, false);
         if (debug2) {
           Serial.print(F("    FAST REPEAT  "));
         }
@@ -146,7 +147,7 @@ void handleButton(uint8_t _key, bool _repeat, uint8_t _rcType) {
       handleButton_lastSentKey = _key;
       handleButton_lastKey_countRepeats = 0;
 
-      sendKey(_key);
+      sendKey(_key, false);
       if (debug2) {
         Serial.print(F("    INITIAL  "));
       }
@@ -166,7 +167,7 @@ void handleButton(uint8_t _key, bool _repeat, uint8_t _rcType) {
   else if (!_repeat) {
     // only send once
     if ( handleButton_lastSentKey != _key || (handleButton_lastSentKey == _key && (millis() - handleButton_lastSentKey_begin) > _handleButton_avoidRepeatDelay)) {
-      sendKey(_key);
+      sendKey(_key, false);
       if (debug2) Serial.println(F("    ONCE"));
       //handleButton_lastSentKey_begin = millis();
       handleButton_lastSentKey = _key;

+ 34 - 7
src/IR-PC-HID-Remote/handleButton_RCx.ino

@@ -11,6 +11,8 @@ uint8_t handleButton_RCx_slowRepeats = 4;                 // amount of slow repe
 uint8_t handleButton_RCx_slowRepeatsNumFastRepeats = 4;   // how many fast repeats (=sending rate of the RC remote) represent one slow repeat?
 uint8_t handleButton_RCx_mediumRepeats = 5;               // amount of medium repeats to send
 uint8_t handleButton_RCx_mediumRepeatsNumFastRepeats = 2; // how many fast repeats (=sending rate of the RC remote) represent one slow repeat?
+uint8_t handleButton_RC5_holdButton_releaseTimeout = 146; // release keys after a button was held (_btnMode=BUTTON_HOLD) after this ms if triggered by handleButton_RCx function
+uint8_t handleButton_RC6_holdButton_releaseTimeout = 100; // release keys after a button was held (_btnMode=BUTTON_HOLD) after this ms if triggered by handleButton_RCx function
 
 // global variables for RCx button handling
 unsigned int handleButton_RCx_btnRepeatsCounter;
@@ -19,18 +21,39 @@ uint8_t handleButton_RCx_btnSlowRepeatsCounter, handleButton_RCx_btnSlowRepeatsC
 uint8_t handleButton_RCx_btnMediumRepeatsCounter, handleButton_RCx_btnMediumRepeatsCounter2;
 
 // the function
-void handleButton_RCx(uint8_t _btn, bool _repeat, uint8_t _currPrefix) {
+//void handleButton_RCx(uint8_t _btn, uint8_t _btnMode, uint8_t _currPrefix) {
+//  handleButton_RCx(_btn, _btnMode, _currPrefix, REMOTETYPE_RC6);
+//}
+
+void handleButton_RCx(uint8_t _btn, uint8_t _btnMode, uint8_t _currPrefix, uint8_t _remoteType) {
+  bool _repeatMode = false;
+  bool _holdMode = false;
+  if (_btnMode == 1) _repeatMode = true;
+  else if (_btnMode == 2) _holdMode = true;
+
   if (_btn != handleButton_RCx_lastButton || (_btn == handleButton_RCx_lastButton) && (_currPrefix != handleButton_RCx_lastPrefix)) {
     if (debug2) {
       Serial.println(F("RCx BUTTON INITIAL"));
     }
+    
+    if (_holdMode) {
+      releaseAllKeys();
+      sendKey(_btn, true);
+
+      if(_remoteType == REMOTETYPE_RC6) holdButton_releaseTimeout = handleButton_RC6_holdButton_releaseTimeout;
+      else if(_remoteType == REMOTETYPE_RC5) holdButton_releaseTimeout = handleButton_RC5_holdButton_releaseTimeout;
+      
+      holdButton_lastTriggeredMillis = millis();
+    }
+    else sendKey(_btn, false);
 
-    sendKey(_btn);
     handleButton_RCx_btnRepeatsCounter = 0;
     handleButton_RCx_btnSlowRepeatsCounter = 0;
     handleButton_RCx_btnMediumRepeatsCounter = 0;
   }
-  else if ((_btn == handleButton_RCx_lastButton) && (_currPrefix == handleButton_RCx_lastPrefix) && _repeat) {
+
+  // REPEAT BUTTON
+  else if ((_btn == handleButton_RCx_lastButton) && (_currPrefix == handleButton_RCx_lastPrefix) && _repeatMode) {
     if (handleButton_RCx_btnRepeatsCounter >= handleButton_RCx_ignoreFirstRepeats) {
       if (handleButton_RCx_btnSlowRepeatsCounter == 0) {
         handleButton_RCx_btnSlowRepeatsCounter++;
@@ -39,7 +62,7 @@ void handleButton_RCx(uint8_t _btn, bool _repeat, uint8_t _currPrefix) {
           Serial.print(F("RCx BUTTON REPEAT SLOW #"));
           Serial.println(handleButton_RCx_btnSlowRepeatsCounter);
         }
-        sendKey(_btn);
+        sendKey(_btn, false);
       }
       else if (handleButton_RCx_btnSlowRepeatsCounter < handleButton_RCx_slowRepeats) {
         if (handleButton_RCx_btnSlowRepeatsCounter2 < handleButton_RCx_slowRepeatsNumFastRepeats) {
@@ -52,7 +75,7 @@ void handleButton_RCx(uint8_t _btn, bool _repeat, uint8_t _currPrefix) {
             Serial.print(F("RCx BUTTON REPEAT SLOW #"));
             Serial.println(handleButton_RCx_btnSlowRepeatsCounter);
           }
-          sendKey(_btn);
+          sendKey(_btn, false);
         }
       }
       else if (handleButton_RCx_btnMediumRepeatsCounter <= handleButton_RCx_mediumRepeats) {
@@ -67,18 +90,22 @@ void handleButton_RCx(uint8_t _btn, bool _repeat, uint8_t _currPrefix) {
             Serial.println(handleButton_RCx_btnMediumRepeatsCounter);
           }
 
-          sendKey(_btn);
+          sendKey(_btn, false);
         }
       }
       else {
         if (debug2) {
           Serial.println(F("RCx BUTTON REPEAT FAST"));
         }
-        sendKey(_btn);
+        sendKey(_btn, false);
       }
     }
     handleButton_RCx_btnRepeatsCounter++;
+  }
 
+  // HOLD BUTTON
+  else if ((_btn == handleButton_RCx_lastButton) && (_currPrefix == handleButton_RCx_lastPrefix) && _holdMode) {
+    holdButton_lastTriggeredMillis = millis();
   }
   handleButton_RCx_lastPrefix = _currPrefix;
   handleButton_RCx_lastButton = _btn;

+ 15 - 0
src/IR-PC-HID-Remote/handleHoldButtons.ino

@@ -0,0 +1,15 @@
+void handleHoldButtons_loop() {
+  if (holdButton_lastTriggeredMillis > 0) {
+    if ((millis() - holdButton_lastTriggeredMillis) > holdButton_releaseTimeout) {
+      releaseAllKeys();
+      holdButton_lastTriggeredMillis = 0;
+      if (useSerial) {
+        Serial.println(F("KEY RELEASED"));
+      }
+    }
+  }
+}
+
+void releaseAllKeys() {
+  BootKeyboard.releaseAll();
+}

+ 61 - 49
src/IR-PC-HID-Remote/sendKeys.ino

@@ -15,12 +15,12 @@ void printArrow() {
 }
 
 
+//void sendKey(uint8_t _key) {
+//  sendKey(_key, false);
+//}
 
-
-
-
-void sendKey(uint8_t _key) {
-  if(debug) Serial.println(F("SENDING KEY"));
+void sendKey(uint8_t _key, bool _hold) {
+  if (debug) Serial.println(F("SENDING KEY"));
   switch (_key) {
     //    case BTN_POWER:
     //      //handlePowerButton();
@@ -30,14 +30,31 @@ void sendKey(uint8_t _key) {
     //      }
     //      break;
     case BTN_OK_ENTER:
-      if (sendHID) BootKeyboard.write(KEY_ENTER);
+      if (sendHID) {
+        if(_hold) BootKeyboard.press(KEY_ENTER);
+        else BootKeyboard.write(KEY_ENTER);
+      }
+      holdButton_lastTriggeredMillis = millis();
       if (useSerial) {
         printKey();
         Serial.println(F("OK_ENTER"));
       }
       break;
+    case BTN_BACK:
+      if (sendHID) {
+        if(_hold) BootKeyboard.press(KEY_BACKSPACE);
+        else BootKeyboard.write(KEY_BACKSPACE);
+      }
+      if (useSerial) {
+        printKey();
+        Serial.println(F("BACK"));
+      }
+      break;
     case BTN_UP:
-      if (sendHID) BootKeyboard.write(KEY_UP_ARROW);
+      if (sendHID) {
+        if(_hold) BootKeyboard.press(KEY_UP_ARROW);
+        else BootKeyboard.write(KEY_UP_ARROW);
+      }
       if (useSerial) {
         printKey();
         Serial.println(F("UP"));
@@ -45,7 +62,10 @@ void sendKey(uint8_t _key) {
       handleTaskSwitchButton_extendAltTabTimeout();
       break;
     case BTN_DOWN:
-      if (sendHID) BootKeyboard.write(KEY_DOWN_ARROW);
+      if (sendHID) {
+        if(_hold) BootKeyboard.press(KEY_DOWN_ARROW);
+        else BootKeyboard.write(KEY_DOWN_ARROW);
+      }
       if (useSerial) {
         printKey();
         Serial.println(F("DOWN"));
@@ -53,7 +73,10 @@ void sendKey(uint8_t _key) {
       handleTaskSwitchButton_extendAltTabTimeout();
       break;
     case BTN_RIGHT:
-      if (sendHID) BootKeyboard.write(KEY_RIGHT_ARROW);
+      if (sendHID) {
+        if(_hold) BootKeyboard.press(KEY_RIGHT_ARROW);
+        else BootKeyboard.write(KEY_RIGHT_ARROW);
+      }
       if (useSerial) {
         printKey();
         Serial.println(F("RIGHT"));
@@ -61,7 +84,10 @@ void sendKey(uint8_t _key) {
       handleTaskSwitchButton_extendAltTabTimeout();
       break;
     case BTN_LEFT:
-      if (sendHID) BootKeyboard.write(KEY_LEFT_ARROW);
+      if (sendHID) {
+        if(_hold) BootKeyboard.press(KEY_LEFT_ARROW);
+        else BootKeyboard.write(KEY_LEFT_ARROW);
+      }
       if (useSerial) {
         printKey();
         Serial.println(F("LEFT"));
@@ -130,13 +156,6 @@ void sendKey(uint8_t _key) {
         Serial.println(F("NEXT"));
       }
       break;
-    case BTN_BACK:
-      if (sendHID) BootKeyboard.write(KEY_BACKSPACE);
-      if (useSerial) {
-        printKey();
-        Serial.println(F("BACK"));
-      }
-      break;
     case BTN_MENU:
       if (sendHID) BootKeyboard.write(KEY_ESC);
       if (useSerial) {
@@ -153,12 +172,14 @@ void sendKey(uint8_t _key) {
       break;
     case BTN_RED:
       if (sendHID) {
+
         BootKeyboard.press(KEY_LEFT_CTRL);
         BootKeyboard.press(KEY_LEFT_ALT);
         BootKeyboard.press(KEY_LEFT_WINDOWS);
         BootKeyboard.press(KEY_F7);
-        delay(50);
-        BootKeyboard.releaseAll();
+        holdButton_lastTriggeredMillis = millis();
+        //delay(50);
+        //BootKeyboard.releaseAll();
       }
       if (useSerial) {
         printKey();
@@ -172,8 +193,9 @@ void sendKey(uint8_t _key) {
         BootKeyboard.press(KEY_LEFT_ALT);
         BootKeyboard.press(KEY_LEFT_WINDOWS);
         BootKeyboard.press(KEY_F8);
-        delay(50);
-        BootKeyboard.releaseAll();
+        holdButton_lastTriggeredMillis = millis();
+        //delay(50);
+        //BootKeyboard.releaseAll();
       }
       if (useSerial) {
         printKey();
@@ -187,8 +209,9 @@ void sendKey(uint8_t _key) {
         BootKeyboard.press(KEY_LEFT_ALT);
         BootKeyboard.press(KEY_LEFT_WINDOWS);
         BootKeyboard.press(KEY_F9);
-        delay(50);
-        BootKeyboard.releaseAll();
+        holdButton_lastTriggeredMillis = millis();
+        //delay(50);
+        //BootKeyboard.releaseAll();
       }
       if (useSerial) {
         printKey();
@@ -202,8 +225,9 @@ void sendKey(uint8_t _key) {
         BootKeyboard.press(KEY_LEFT_ALT);
         BootKeyboard.press(KEY_LEFT_WINDOWS);
         BootKeyboard.press(KEY_F10);
-        delay(50);
-        BootKeyboard.releaseAll();
+        holdButton_lastTriggeredMillis = millis();
+        //delay(50);
+        //BootKeyboard.releaseAll();
       }
       if (useSerial) {
         printKey();
@@ -232,14 +256,12 @@ void sendKey(uint8_t _key) {
     case BTN_GUIDE:
       if (sendHID) {
         BootKeyboard.press(KEY_LEFT_CTRL);
-        delay(2);
         BootKeyboard.press(KEY_LEFT_ALT);
-        delay(2);
         BootKeyboard.press(KEY_LEFT_WINDOWS);
-        delay(2);
         BootKeyboard.press(KEY_F5);
-        delay(20);
-        BootKeyboard.releaseAll();
+        holdButton_lastTriggeredMillis = millis();
+        //delay(20);
+        //BootKeyboard.releaseAll();
       }
       if (useSerial) {
         printKey();
@@ -250,14 +272,12 @@ void sendKey(uint8_t _key) {
     case BTN_RADIO:
       if (sendHID) {
         BootKeyboard.press(KEY_LEFT_CTRL);
-        delay(2);
         BootKeyboard.press(KEY_LEFT_ALT);
-        delay(2);
         BootKeyboard.press(KEY_LEFT_WINDOWS);
-        delay(2);
         BootKeyboard.press(KEY_F6);
-        delay(20);
-        BootKeyboard.releaseAll();
+        holdButton_lastTriggeredMillis = millis();
+        //delay(20);
+        //BootKeyboard.releaseAll();
       }
       if (useSerial) {
         printKey();
@@ -288,7 +308,6 @@ void sendKey(uint8_t _key) {
     case BTN_CH_DOWN:
       if (sendHID) {
         BootKeyboard.write(KEY_PAGE_DOWN);
-        //BootKeyboard.releaseAll();
       }
       if (useSerial) {
         printKey();
@@ -298,7 +317,6 @@ void sendKey(uint8_t _key) {
     case BTN_CH_UP:
       if (sendHID) {
         BootKeyboard.write(KEY_PAGE_UP);
-        //BootKeyboard.releaseAll();
       }
       if (useSerial) {
         printKey();
@@ -308,7 +326,6 @@ void sendKey(uint8_t _key) {
     case BTN_PAGE_DOWN:
       if (sendHID) {
         BootKeyboard.write(KEY_PAGE_DOWN);
-        //BootKeyboard.releaseAll();
       }
       if (useSerial) {
         printKey();
@@ -318,7 +335,6 @@ void sendKey(uint8_t _key) {
     case BTN_PAGE_UP:
       if (sendHID) {
         BootKeyboard.write(KEY_PAGE_UP);
-        //BootKeyboard.releaseAll();
       }
       if (useSerial) {
         printKey();
@@ -388,14 +404,12 @@ void sendKey(uint8_t _key) {
     case BTN_MUSIC:
       if (sendHID) {
         BootKeyboard.press(KEY_LEFT_CTRL);
-        delay(2);
         BootKeyboard.press(KEY_LEFT_ALT);
-        delay(2);
         BootKeyboard.press(KEY_LEFT_WINDOWS);
-        delay(2);
         BootKeyboard.press(KEY_F3);
-        delay(20);
-        BootKeyboard.releaseAll();
+        holdButton_lastTriggeredMillis = millis();
+        //delay(20);
+        //BootKeyboard.releaseAll();
       }
       if (useSerial) {
         printKey();
@@ -406,14 +420,12 @@ void sendKey(uint8_t _key) {
     case BTN_PICTURES:
       if (sendHID) {
         BootKeyboard.press(KEY_LEFT_CTRL);
-        delay(2);
         BootKeyboard.press(KEY_LEFT_WINDOWS);
-        delay(2);
         BootKeyboard.press(KEY_LEFT_ALT);
-        delay(2);
         BootKeyboard.press(KEY_F4);
-        delay(20);
-        BootKeyboard.releaseAll();
+        holdButton_lastTriggeredMillis = millis();
+        //delay(20);
+        //BootKeyboard.releaseAll();
       }
       if (useSerial) {
         printKey();