Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recognise Longpress on IR-Remotes #430

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

Conversation

EFWob
Copy link

@EFWob EFWob commented Jan 22, 2021

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 ir_XXXX and the associated command is executed.
If the key is hold, the preferences are searched for the setting ir_XXXXr 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 ir_XXXXrY, 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 ir_02FDr2 = 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:

  • the first event generated is always ir_XXXX. 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 ir_XXXXr event is executed before the leading ir_XXXX event has been handled.
  • ir_XXXXr events can be defined without any ir_XXXX event, though.
  • the sequence is always guaranteed: first event will always be ir_XXXX, then ir_XXXXr1, ir_XXXXr2, ir_XXXXr3 and so on.
  • the timing between this events is not guaranteed, though it will average around 100ms
  • an ir_XXXXrY will fire, if the repeat count equals Y (decimal representation, no leading '0'). If that happens it will shadow an existing preference for ir_XXXXr (so that will NOT fire).
  • there is no such event as ir_XXXXr0. That means the event ir_XXXX for the first press of the key can not be overridden

Implementation details

The global variable ir_value is now uint32_t. It is still produced by isr_IR() and consumed by scanIR(). isr_IR() will set ir_value to something not Zero if meaningful input has been detected, and scanIR() will reset ir_value to Zero if the input has been consumed. Major change: the upper half word of ir_value 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 isr_IR()) 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant