123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- // Button handling for IR remotes using Pioneer, NEC, Sony... code
- // - These DO NOT send a toggle bit on every new button press, so it is difficult to differ hold and re-pressing
- // - On re-pressing this function will send the button again as fast as possible. It uses timers to filter out unintended multi triggering,
- // so this can be a little bit delayed (RC5 and RC6 remotes are better in this case)
- // - If a button is held down, the remote will go on sending the same code every 100ms or so.
- // 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).
- // special case Pioneer Protocol:
- // Pioneer Protocol transmits 2 different NEC 32bit codes on each keypress at once
- // and always with one repetition, so a short keypress sends 4 NEC codes
- // i.E.:
- // NEC, 0xD52A34CB, 32
- // NEC, 0xF50AF708, 32
- // NEC, 0xD52A34CB, 32
- // NEC, 0xF50AF708, 32
- // Each pair takes about 184ms -> 368ms for one button press.
- // On button hold the same codes are transmitted continuously.
- // So the shortest repeat time possible is about every 183ms - but ONLY when the button is held.
- // If the button is quickly short pressed it looks just like the same on receiver side.
- // As there is always at least 1 repetition, it is mandatory to filter these out, or a single
- // button press would always result in 2 events.
- uint8_t handleButton_lastSentKey;
- unsigned long handleButton_lastSentKey_begin;
- unsigned long handleButton_repeatedReceivedMillis;
- unsigned long handleButton_repeatMillis;
- #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
- // so basically it must be a multiple of the time a transmit takes the RC
- #define HANDLEBUTTON_SLOW_REPEATS 2 // how many slow repeats should occur before fast repeats are engaged
- #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;
- void handleButton(uint8_t _key) {
- handleButton(_key, false, 0);
- }
- void handleButton(uint8_t _key, bool _repeat) {
- handleButton(_key, _repeat, 0);
- }
- void handleButton(uint8_t _key, bool _repeat, uint8_t _rcType) {
- // _repeat: enable/disable repeat for this button - if false, holding the button will not trigger repeated events
- // _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
- // 1 = other (slower?) remote
- // 2 = ...
- unsigned int _minRepeatInterval = 0;
- if (debug2) {
- Serial.print(F(" loopTime="));
- Serial.print((millis() - lastReceivedMillis));
- Serial.println("ms");
- }
- lastReceivedMillis = millis();
- unsigned int _handleButton_repeat_Timeout, _handleButton_maxRepeatedReceiveMs, _handleButton_avoidRepeatDelay;
- if (_rcType == 1) {
- _handleButton_repeat_Timeout = HANDLEBUTTON_REPEAT_TIMEOUT_1;
- _handleButton_maxRepeatedReceiveMs = HANDLEBUTTON_MAX_REPEATED_RECEIVE_MS_1;
- _handleButton_avoidRepeatDelay = HANDLEBUTTON_AVOID_REPEAT_DELAY_1;
- }
- else if (_rcType == 2) {
- _handleButton_repeat_Timeout = HANDLEBUTTON_REPEAT_TIMEOUT_2;
- _handleButton_maxRepeatedReceiveMs = HANDLEBUTTON_MAX_REPEATED_RECEIVE_MS_2;
- _handleButton_avoidRepeatDelay = HANDLEBUTTON_AVOID_REPEAT_DELAY_2;
- }
- else { // PIONEER o.A.
- _handleButton_repeat_Timeout = HANDLEBUTTON_REPEAT_TIMEOUT_0;
- _handleButton_maxRepeatedReceiveMs = HANDLEBUTTON_MAX_REPEATED_RECEIVE_MS_0;
- _handleButton_avoidRepeatDelay = HANDLEBUTTON_AVOID_REPEAT_DELAY_0;
- }
- if (_repeat) _minRepeatInterval = 1;
- // if this is the POWER button, always use repeat, regardless of function call variable
- if (_key == BTN_POWER) _minRepeatInterval = 1;
- if (_minRepeatInterval > 0) {
- if (handleButton_lastSentKey == _key && (millis() - handleButton_repeatMillis) < _handleButton_repeat_Timeout && (millis() - handleButton_repeatedReceivedMillis) < _handleButton_maxRepeatedReceiveMs) {
- if (debug) {
- Serial.print(F(" R="));
- Serial.print(handleButton_lastKey_countRepeats + 1);
- Serial.print(F(", handleButton_lastSentKey_begin="));
- Serial.print(millis() - handleButton_lastSentKey_begin);
- Serial.print(F("ms, handleButton_repeatMillis="));
- Serial.print(millis() - handleButton_repeatMillis);
- Serial.print(F("ms, handleButton_repeatedReceivedMillis="));
- Serial.print(millis() - handleButton_repeatedReceivedMillis);
- Serial.println(F("ms"));
- }
- if ( (millis() - handleButton_repeatMillis) >= HANDLEBUTTON_FIRST_REPEAT_INTERVAL) {
- // slow repeats
- sendKey(_key, false);
- if (debug2) {
- Serial.print(F(" SLOW REPEAT "));
- }
-
- handleButton_repeatMillis = millis();
- handleButton_lastKey_countRepeats++;
- }
- else if ( handleButton_lastKey_countRepeats >= HANDLEBUTTON_SLOW_REPEATS && (millis() - handleButton_repeatMillis) >= _minRepeatInterval) {
- // fast repeats
- sendKey(_key, false);
- if (debug2) {
- Serial.print(F(" FAST REPEAT "));
- }
-
- handleButton_repeatMillis = millis();
- handleButton_lastKey_countRepeats++;
- }
- else {
- // waiting to reach HANDLEBUTTON_FIRST_REPEAT_INTERVAL
- //handleButton_repeatMillis = millis();
- if (debug2) {
- Serial.println(F(" REPEAT WAITING "));
- }
- }
- }
- else {
- // this is the initial button press
- handleButton_lastSentKey_begin = millis();
- handleButton_repeatMillis = millis();
- handleButton_lastSentKey = _key;
- handleButton_lastKey_countRepeats = 0;
- sendKey(_key, false);
- if (debug2) {
- Serial.print(F(" INITIAL "));
- }
- if (debug) {
- Serial.print(F(" R="));
- Serial.println(handleButton_lastKey_countRepeats);
- }
- }
- if (handleButton_lastSentKey == _key) {
- handleButton_repeatedReceivedMillis = millis();
- if (debug2) {
- Serial.println(F(" REPRECV "));
- }
- }
- }
- else if (!_repeat) {
- // only send once
- if ( handleButton_lastSentKey != _key || (handleButton_lastSentKey == _key && (millis() - handleButton_lastSentKey_begin) > _handleButton_avoidRepeatDelay)) {
- sendKey(_key, false);
- if (debug2) Serial.println(F(" ONCE"));
- //handleButton_lastSentKey_begin = millis();
- handleButton_lastSentKey = _key;
- }
- if (handleButton_lastSentKey == _key) {
- handleButton_lastSentKey_begin = millis();
- }
- }
- }
|