mathertel / RotaryEncoder

RotaryEncoder Arduino Library
Other
342 stars 107 forks source link

add callback functions to be called on position change. #32

Closed Llaves closed 3 years ago

Llaves commented 3 years ago

Three different function signatures.

Llaves commented 3 years ago

I've implemented callback functions to be called from within the tick() method when the encoder changes position. Three different callback signatures are defined onChange(long position, int direction) onChange(RotaryEncoder & this_encoder) onChange(void * parameter)

I've tried to follow your coding conventions. The callbacks are implemented in a manner similar to your OneButton class.

Tested on Arduino nano with FOUR3 encoder.

mathertel commented 3 years ago

I personally like the idea of the callbacks but here is the problem:

To get good result I recommend using the tick() function in the interrupts when ever possible. This enables tracking the signals that appear by bouncing contacts in a good way. This is why the tick() function only checks the input and saves the new state/values. This all can happen quickly and the ISR will terminate very fast.

Now, with your changes more code will be executed on the ISR stack. Many thins are not possible during ISRs like delay() and using the Serial IO functions.

This is why the library actually is implemented this way and the examples check the new position in the loop() function.

to create callback functionality more work needs to be done to NOT call the callback during interrupts.

Llaves commented 3 years ago

I understand your reasoning. I am unaware of any clean way to force a function to be called after the return of the ISR without passing flags and checking for them. About all I can come up with is setting a "changed" flag in tick(), which has minimal impact on the ISR beyond the current implementation. The library would then need a checkChanged() function which would check the flag and call the callbacks, if they are defined. The user would have to place checkChanged in the loop() part of the program, just like they would have to call tick() if they didn't place tick in an interrupt. One might argue this is just bringing us back to polling.