Currently only the first press of an IR-Remote key is reported to the application. If you hold the key nothing happens. As this is most often the expected behaviour (i. e. for a preset change), there are situations were you would want the radio to recognise longpress events. Namely if pressing Vol+ or Vol- buttons. This can be achieved by the proposed change.
Application details (how to use the proposed change)
The current approach of handling IR-Events is not altered, but extended. On first press of a key with the code XXXX the preferences are looked up for the existence of the preference setting _irXXXX and the associated command is executed.
If the key is hold, the preferences are searched for the setting _irXXXXr and if found, the associated command will be executed.
Consider the example from defaultprefs.h. There you find the setting ir_40BF = upvolume = 2. To have the radio to react on longpress of that key, you should add to the preferences ir_40BFr = upvolume = 1. That will result in a smooth increase of the volume as long as the key is pressed.
The timing distance of repeat events averages around 100ms (could be more or less depending on application load (and the effects of the Nyquist Shannon signal sampling theorem of course and some implementation details of the NEC IR protocol)).
If DEBUG is on, you can observe the Serial output. You will notice that a repeat counter is increased for lonpressed keys. Here an arbitrary example for a key that has no associated entries in the preferences:
21:11:06.848 -> D: IR code 02FD received, but not found in preferences! Timing 558/1681
21:11:06.881 -> D: Longpress IR code 02FD received, repeat count is: 1
21:11:07.014 -> D: Longpress IR code 02FD received, repeat count is: 2
21:11:07.080 -> D: Longpress IR code 02FD received, repeat count is: 3
21:11:07.213 -> D: Longpress IR code 02FD received, repeat count is: 4
21:11:07.312 -> D: Longpress IR code 02FD received, repeat count is: 5
You can hook to a specific repeat of a keypress in the preferences by setting a preference with the pattern _irXXXXrY, where
XXXX is the hexadecimal code of the key
Y is the decimal representation of the repeat count (w/o any leading '0')
So, in the example above a preference setting of _ir02FDr2 = reset would result in:
21:30:35.676 -> D: IR code 02FD received, but not found in preferences! Timing 560/1680
21:30:35.709 -> D: Longpress IR code 02FD received, repeat count is: 1
21:30:35.809 -> D: Longpress IR code 02FD received, repeat count is: 2
21:30:35.809 -> D: IR code ir_02FDr2 received. Will execute reset
21:30:35.809 -> D: Command: reset with parameter 0
The following holds true for every sequence for a keypress of key XXXX on the IR remote:
the first event generated is always _irXXXX. That is effectively the known behaviour. Nothing will change if only that type of keys are defined in the preferences.
the repeat events will only be generated, if the previous first event has been "seen" by the application. It is not possible that any _irXXXXr event is executed before the leading _irXXXX event has been handled.
_irXXXXr events can be defined without any _irXXXX event, though.
the sequence is always guaranteed: first event will always be _irXXXX, then _irXXXXr1, _irXXXXr2, _irXXXXr3 and so on.
the timing between this events is not guaranteed, though it will average around 100ms
an _irXXXXrY will fire, if the repeat count equals Y (decimal representation, no leading '0'). If that happens it will shadow an existing preference for _irXXXXr (so that will NOT fire).
there is no such event as _irXXXXr0. That means the event _irXXXX for the first press of the key can not be overridden
Implementation details
The global variable _irvalue is now _uint32t. It is still produced by _isrIR() and consumed by scanIR(). _isrIR() will set _irvalue to something not Zero if meaningful input has been detected, and scanIR() will reset _irvalue to Zero if the input has been consumed. Major change: the upper half word of _irvalue contains the repeat count. So the sequence for a key press XXXX will be: 0x0000XXXX for the first press followed by 0x0001XXXX, 0x0002XXXX, 0x0003XXXX and so on.
Repeat shots in the NEC IR protocol are coded as frames that start with a 9ms burst (as any dataframe), followed by a 2.25ms space (half of the 4.5ms of a full frame) followed by a 560µs burst. If that pattern is encountered (in _isrIR()) it is checked if there has been a valid key press detected within the last 120ms (could be either an initial press or a repeated press). If so, that key press is reported with an increased repeat counter.
General Idea
Currently only the first press of an IR-Remote key is reported to the application. If you hold the key nothing happens. As this is most often the expected behaviour (i. e. for a preset change), there are situations were you would want the radio to recognise longpress events. Namely if pressing Vol+ or Vol- buttons. This can be achieved by the proposed change.
Application details (how to use the proposed change)
The current approach of handling IR-Events is not altered, but extended. On first press of a key with the code XXXX the preferences are looked up for the existence of the preference setting _irXXXX and the associated command is executed. If the key is hold, the preferences are searched for the setting _irXXXXr and if found, the associated command will be executed.
Consider the example from defaultprefs.h. There you find the setting
ir_40BF = upvolume = 2
. To have the radio to react on longpress of that key, you should add to the preferencesir_40BFr = upvolume = 1
. That will result in a smooth increase of the volume as long as the key is pressed.The timing distance of repeat events averages around 100ms (could be more or less depending on application load (and the effects of the Nyquist Shannon signal sampling theorem of course and some implementation details of the NEC IR protocol)).
If DEBUG is on, you can observe the Serial output. You will notice that a repeat counter is increased for lonpressed keys. Here an arbitrary example for a key that has no associated entries in the preferences:
21:11:06.848 -> D: IR code 02FD received, but not found in preferences! Timing 558/1681
21:11:06.881 -> D: Longpress IR code 02FD received, repeat count is: 1
21:11:07.014 -> D: Longpress IR code 02FD received, repeat count is: 2
21:11:07.080 -> D: Longpress IR code 02FD received, repeat count is: 3
21:11:07.213 -> D: Longpress IR code 02FD received, repeat count is: 4
21:11:07.312 -> D: Longpress IR code 02FD received, repeat count is: 5
You can hook to a specific repeat of a keypress in the preferences by setting a preference with the pattern _irXXXXrY, where
So, in the example above a preference setting of _ir02FDr2 = reset would result in:
21:30:35.676 -> D: IR code 02FD received, but not found in preferences! Timing 560/1680
21:30:35.709 -> D: Longpress IR code 02FD received, repeat count is: 1
21:30:35.809 -> D: Longpress IR code 02FD received, repeat count is: 2
21:30:35.809 -> D: IR code ir_02FDr2 received. Will execute reset
21:30:35.809 -> D: Command: reset with parameter 0
21:30:35.809 -> D: Command accepted
21:30:36.835 -> ets Jul 29 2019 12:21:46
21:30:36.835 ->
21:30:36.835 -> rst:0xc (SW_CPU_RESET),boot:0x1f (SPI_FAST_FLASH_BOOT)
The following holds true for every sequence for a keypress of key XXXX on the IR remote:
Implementation details
The global variable _irvalue is now _uint32t. It is still produced by _isrIR() and consumed by scanIR(). _isrIR() will set _irvalue to something not Zero if meaningful input has been detected, and scanIR() will reset _irvalue to Zero if the input has been consumed. Major change: the upper half word of _irvalue contains the repeat count. So the sequence for a key press XXXX will be: 0x0000XXXX for the first press followed by 0x0001XXXX, 0x0002XXXX, 0x0003XXXX and so on.
Repeat shots in the NEC IR protocol are coded as frames that start with a 9ms burst (as any dataframe), followed by a 2.25ms space (half of the 4.5ms of a full frame) followed by a 560µs burst. If that pattern is encountered (in _isrIR()) it is checked if there has been a valid key press detected within the last 120ms (could be either an initial press or a repeated press). If so, that key press is reported with an increased repeat counter.
Further more, refer to the comments in the code.