handleButton.ino 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // Button handling for IR remotes using Pioneer, NEC, Sony... code
  2. // - These DO NOT send a toggle bit on every new button press, so it is difficult to differ hold and re-pressing
  3. // - On re-pressing this function will send the button again as fast as possible. It uses timers to filter out unintended multi triggering,
  4. // so this can be a little bit delayed (RC5 and RC6 remotes are better in this case)
  5. // - If a button is held down, the remote will go on sending the same code every 100ms or so.
  6. // This function will then, after some ignored codes, start with some slow repeats, and then switch to fast repeat rate (with the rate of the incoming codes).
  7. // special case Pioneer Protocol:
  8. // Pioneer Protocol transmits 2 different NEC 32bit codes on each keypress at once
  9. // and always with one repetition, so a short keypress sends 4 NEC codes
  10. // i.E.:
  11. // NEC, 0xD52A34CB, 32
  12. // NEC, 0xF50AF708, 32
  13. // NEC, 0xD52A34CB, 32
  14. // NEC, 0xF50AF708, 32
  15. // Each pair takes about 184ms -> 368ms for one button press.
  16. // On button hold the same codes are transmitted continuously.
  17. // So the shortest repeat time possible is about every 183ms - but ONLY when the button is held.
  18. // If the button is quickly short pressed it looks just like the same on receiver side.
  19. // As there is always at least 1 repetition, it is mandatory to filter these out, or a single
  20. // button press would always result in 2 events.
  21. uint8_t handleButton_lastSentKey;
  22. unsigned long handleButton_lastSentKey_begin;
  23. unsigned long handleButton_repeatedReceivedMillis;
  24. unsigned long handleButton_repeatMillis;
  25. #define HANDLEBUTTON_FIRST_REPEAT_INTERVAL 500 // minimum ms for the first repeat(s) to trigger an event. the actual value will be slightly more, as it will be only triggert on the next receive from the RC
  26. // so basically it must be a multiple of the time a transmit takes the RC
  27. #define HANDLEBUTTON_SLOW_REPEATS 2 // how many slow repeats should occur before fast repeats are engaged
  28. #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
  29. #define HANDLEBUTTON_MAX_REPEATED_RECEIVE_MS_0 200 // slightly more than one transmit, used to detect repetitions
  30. #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
  31. #define HANDLEBUTTON_HOLD_TIMEOUT_0 150
  32. #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
  33. #define HANDLEBUTTON_MAX_REPEATED_RECEIVE_MS_1 120 // slightly more than one transmit, used to detect repetitions
  34. #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
  35. #define HANDLEBUTTON_HOLD_TIMEOUT_1 150
  36. #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
  37. #define HANDLEBUTTON_MAX_REPEATED_RECEIVE_MS_2 110 // slightly more than one transmit, used to detect repetitions
  38. #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
  39. #define HANDLEBUTTON_HOLD_TIMEOUT_2 150
  40. unsigned int handleButton_lastKey_countRepeats = 0;
  41. void handleButton(uint8_t _key) {
  42. handleButton(_key, false, 0);
  43. }
  44. void handleButton(uint8_t _key, bool _repeat) {
  45. handleButton(_key, _repeat, 0);
  46. }
  47. void handleButton(uint8_t _key, bool _repeat, uint8_t _rcType) {
  48. // _repeat: enable/disable repeat for this button - if false, holding the button will not trigger repeated events
  49. // _rcType: 0 = RC code types without toggle bit as in RC5/RC6, therefore a higher delay is required to avoid repeated events at single button presses
  50. // 1 = other (slower?) remote
  51. // 2 = ...
  52. unsigned int _minRepeatInterval = 0;
  53. if (debug2) {
  54. Serial.print(F(" loopTime="));
  55. Serial.print((millis() - lastReceivedMillis));
  56. Serial.println("ms");
  57. }
  58. lastReceivedMillis = millis();
  59. unsigned int _handleButton_repeat_Timeout, _handleButton_maxRepeatedReceiveMs, _handleButton_avoidRepeatDelay;
  60. if (_rcType == 1) {
  61. _handleButton_repeat_Timeout = HANDLEBUTTON_REPEAT_TIMEOUT_1;
  62. _handleButton_maxRepeatedReceiveMs = HANDLEBUTTON_MAX_REPEATED_RECEIVE_MS_1;
  63. _handleButton_avoidRepeatDelay = HANDLEBUTTON_AVOID_REPEAT_DELAY_1;
  64. }
  65. else if (_rcType == 2) {
  66. _handleButton_repeat_Timeout = HANDLEBUTTON_REPEAT_TIMEOUT_2;
  67. _handleButton_maxRepeatedReceiveMs = HANDLEBUTTON_MAX_REPEATED_RECEIVE_MS_2;
  68. _handleButton_avoidRepeatDelay = HANDLEBUTTON_AVOID_REPEAT_DELAY_2;
  69. }
  70. else { // PIONEER o.A.
  71. _handleButton_repeat_Timeout = HANDLEBUTTON_REPEAT_TIMEOUT_0;
  72. _handleButton_maxRepeatedReceiveMs = HANDLEBUTTON_MAX_REPEATED_RECEIVE_MS_0;
  73. _handleButton_avoidRepeatDelay = HANDLEBUTTON_AVOID_REPEAT_DELAY_0;
  74. }
  75. if (_repeat) _minRepeatInterval = 1;
  76. // if this is the POWER button, always use repeat, regardless of function call variable
  77. if (_key == BTN_POWER) _minRepeatInterval = 1;
  78. if (_minRepeatInterval > 0) {
  79. if (handleButton_lastSentKey == _key && (millis() - handleButton_repeatMillis) < _handleButton_repeat_Timeout && (millis() - handleButton_repeatedReceivedMillis) < _handleButton_maxRepeatedReceiveMs) {
  80. if (debug) {
  81. Serial.print(F(" R="));
  82. Serial.print(handleButton_lastKey_countRepeats + 1);
  83. Serial.print(F(", handleButton_lastSentKey_begin="));
  84. Serial.print(millis() - handleButton_lastSentKey_begin);
  85. Serial.print(F("ms, handleButton_repeatMillis="));
  86. Serial.print(millis() - handleButton_repeatMillis);
  87. Serial.print(F("ms, handleButton_repeatedReceivedMillis="));
  88. Serial.print(millis() - handleButton_repeatedReceivedMillis);
  89. Serial.println(F("ms"));
  90. }
  91. if ( (millis() - handleButton_repeatMillis) >= HANDLEBUTTON_FIRST_REPEAT_INTERVAL) {
  92. // slow repeats
  93. sendKey(_key, false);
  94. if (debug2) {
  95. Serial.print(F(" SLOW REPEAT "));
  96. }
  97. handleButton_repeatMillis = millis();
  98. handleButton_lastKey_countRepeats++;
  99. }
  100. else if ( handleButton_lastKey_countRepeats >= HANDLEBUTTON_SLOW_REPEATS && (millis() - handleButton_repeatMillis) >= _minRepeatInterval) {
  101. // fast repeats
  102. sendKey(_key, false);
  103. if (debug2) {
  104. Serial.print(F(" FAST REPEAT "));
  105. }
  106. handleButton_repeatMillis = millis();
  107. handleButton_lastKey_countRepeats++;
  108. }
  109. else {
  110. // waiting to reach HANDLEBUTTON_FIRST_REPEAT_INTERVAL
  111. //handleButton_repeatMillis = millis();
  112. if (debug2) {
  113. Serial.println(F(" REPEAT WAITING "));
  114. }
  115. }
  116. }
  117. else {
  118. // this is the initial button press
  119. handleButton_lastSentKey_begin = millis();
  120. handleButton_repeatMillis = millis();
  121. handleButton_lastSentKey = _key;
  122. handleButton_lastKey_countRepeats = 0;
  123. sendKey(_key, false);
  124. if (debug2) {
  125. Serial.print(F(" INITIAL "));
  126. }
  127. if (debug) {
  128. Serial.print(F(" R="));
  129. Serial.println(handleButton_lastKey_countRepeats);
  130. }
  131. }
  132. if (handleButton_lastSentKey == _key) {
  133. handleButton_repeatedReceivedMillis = millis();
  134. if (debug2) {
  135. Serial.println(F(" REPRECV "));
  136. }
  137. }
  138. }
  139. else if (!_repeat) {
  140. // only send once
  141. if ( handleButton_lastSentKey != _key || (handleButton_lastSentKey == _key && (millis() - handleButton_lastSentKey_begin) > _handleButton_avoidRepeatDelay)) {
  142. sendKey(_key, false);
  143. if (debug2) Serial.println(F(" ONCE"));
  144. //handleButton_lastSentKey_begin = millis();
  145. handleButton_lastSentKey = _key;
  146. }
  147. if (handleButton_lastSentKey == _key) {
  148. handleButton_lastSentKey_begin = millis();
  149. }
  150. }
  151. }