[PLUGIN] RotaryEncoder II

:flushed: Ok, I assume with back-powering like that, that is hardly the issue… I‘m just wild guessing, so just tried to remember, what issues I observed in the past.
An accessible Alps Encoder is definitely easier to analyze - let‘s see.
I‘m still trying to come up with a failure mode, that would only hit the decoding of the Kernel driver but not the simpler logic of the onoff_rotary… but my creativity fails me.

parts didn’t come, sorry, delayed to next week : (

Parts came, but the wrong ones, will be a longer fight.

However, meanwhile I unmounted the ky-040 encoders. I soldererd two 68nF capacitors, each to pin clk and dt for the debouncing for Sayato’s encoder plugin. I removed them and it works like a charm, one tick, one volume step, perfect.

However, there is still no click catched, nothing in the log except for the volume-changes.
Tested with a Multimeter, switch is ok, a click closes the SW-pin to ground.

Any ideas?

Nice to hear that it works now. However, I am still wondering how the capacitors could have been connected to produce the observed behavior. If the online resources are right and the KY-040 has 200Ω 10kΩ Pull-ups and you used 68nF, the time-constant for the charging should have been:
𝜏_c = 10kΩ x 68pF = 68ms (reasonable)
That probably did not give you a lot of debouncing. But if you did not use a limiting resistor, the discharge was probably quite quick and may have caused issues or the connection was not good… does not matter, as long as it works now.

For the push-button:
Which GPIO are you using? The push-button implementation is pretty similar between both plugins. It is quite strange, if it works in one and not in the other. Both plugins use the npm onoff package for the button interaction.
Maybe basic checks:

  • Did you use the right GPIO number (plugin expects the BCM number, so if you still have 22 as the push-button pin, it should be on physical pin 15 aka GPIO3 in wiringPi terms).
  • Do you have the right button logic (active low, if you pull to GND)? In the log you posted, pushState0 has the value false which would be active high and now you write, that pushing the button pulls to GND. However, even if that would be wrong, I would expect to see error messages in that case in your log, warning about a potentially wrong button logic (because the plugin checks, how long a button is pressed and with wrong logic setting, it will think that the button is pressed for long time and ask if you have the right logic).
  • You could also try to play with the debounce timing again. If you do not have hardware debouncing, the button likely needs 50ms or 100ms debouncing.

If you do not see any reaction in the log, it probably is an issue with the hardware, still. Because it likely means, that onoff does not generate any events. If it still is the case, that the old plugin works with the push-button and the new one does not, I would need to compare the code to see, if there is a difference in how they use onoff

I found that you also need a capacitor (50 - 100nf) between ground and the switch other wise it didnt switch or was really eratic as to whether it did switch or not.
Also, you are using the switch to pull the gpio low you need " button logic-level active low" enabled in the options

Hmmm… the schematic I found for the KY-040 says its using 10K pullup resistors https://www.kn34pc.com/tmp/arh/arduino_dds_vfo_ad9850_20m_cw/enc_sch.gif

Yes, that’s correct, on the backside of the encoders circuit board there are 3 10k resistors.

I have “button logic-level active low” enabled, soldered one of the no longer used 68nF capacitors between GND and SW pin of the encoder, which now triggers a button press by every volume-tick, button press alone is not logged, I’ve also tried various debouncing times between 40 and 150 with no effect.

Log

CoreCommandRouter::executeOnPlugin: volumiodiscovery , saveDeviceInfo info: CoreCommandRouter::volumioPushState info: [ROTARYENCODER2] Push Button 1 pressed. info: [ROTARYENCODER2] addEventHandle received from rotary: 1 -> Dir: -1 info: [ROTARYENCODER2] emitDialCommand: 1 with value -1for Rotary: 1 info: [ROTARYENCODER2] emitDialCommand: VOLUME DOWN info: VolumeController::SetAlsaVolume- info: CoreStateMachine::pushState info: CorePlayQueue::getTrack 15 info: CoreCommandRouter::executeOnPlugin: volumiodiscovery , saveDeviceInfo info: CoreCommandRouter::volumioPushState info: [ROTARYENCODER2] Push Button 1 longpush timer elapsed. (true, 6) info: [ROTARYENCODER2] Push Button 1 pressed. info: [ROTARYENCODER2] Push Button 1 starting timers. info: [ROTARYENCODER2] Push Button 1 doublepush timer elapsed. (true, 1) info: [ROTARYENCODER2] addEventHandle received from rotary: 1 -> Dir: -1 info: [ROTARYENCODER2] emitDialCommand: 1 with value -1for Rotary: 1 info: [ROTARYENCODER2] emitDialCommand: VOLUME DOWN info: VolumeController::SetAlsaVolume- info: CoreStateMachine::pushState info: CorePlayQueue::getTrack 15 info: CoreCommandRouter::executeOnPlugin: volumiodiscovery , saveDeviceInfo info: CoreCommandRouter::volumioPushState info: [ROTARYENCODER2] Push Button 1 pressed. info: [ROTARYENCODER2] addEventHandle received from rotary: 1 -> Dir: -1 info: [ROTARYENCODER2] emitDialCommand: 1 with value -1for Rotary: 1 info: [ROTARYENCODER2] emitDialCommand: VOLUME DOWN info: VolumeController::SetAlsaVolume- info: CoreStateMachine::pushState info: CorePlayQueue::getTrack 15 info: CoreCommandRouter::executeOnPlugin: volumiodiscovery , saveDeviceInfo info: CoreCommandRouter::volumioPushState info: [ROTARYENCODER2] Push Button 1 pressed. info: [ROTARYENCODER2] Push Button 1 longpush timer elapsed. (true, 3) info: [ROTARYENCODER2] addEventHandle received from rotary: 1 -> Dir: -1 info: [ROTARYENCODER2] emitDialCommand: 1 with value -1for Rotary: 1 info: [ROTARYENCODER2] emitDialCommand: VOLUME DOWN info: VolumeController::SetAlsaVolume- info: CoreStateMachine::pushState info: CorePlayQueue::getTrack 15 info: CoreCommandRouter::executeOnPlugin: volumiodiscovery , saveDeviceInfo info: CoreCommandRouter::volumioPushState info: [ROTARYENCODER2] Push Button 1 pressed. info: [ROTARYENCODER2] Push Button 1 starting timers. info: [ROTARYENCODER2] addEventHandle received from rotary: 1 -> Dir: -1 info: [ROTARYENCODER2] emitDialCommand: 1 with value -1for Rotary: 1 info: [ROTARYENCODER2] emitDialCommand: VOLUME DOWN info: VolumeController::SetAlsaVolume- info: CoreStateMachine::pushState info: CorePlayQueue::getTrack 15 info: CoreCommandRouter::executeOnPlugin: volumiodiscovery , saveDeviceInfo info: CoreCommandRouter::volumioPushState info: [ROTARYENCODER2] Push Button 1 pressed. info: [ROTARYENCODER2] addEventHandle received from rotary: 1 -> Dir: -1 info: [ROTARYENCODER2] emitDialCommand: 1 with value -1for Rotary: 1 info: [ROTARYENCODER2] emitDialCommand: VOLUME DOWN info: VolumeController::SetAlsaVolume- info: CoreStateMachine::pushState info: CorePlayQueue::getTrack 15 info: CoreCommandRouter::executeOnPlugin: volumiodiscovery , saveDeviceInfo info: CoreCommandRouter::volumioPushState info: [ROTARYENCODER2] Push Button 1 pressed. info: [ROTARYENCODER2] Push Button 1 doublepush timer elapsed. (true, 3) info: [ROTARYENCODER2] Push Button 1 longpush timer elapsed. (true, 3)

I will try other capacitors with different values, maybe that will help.

There must be something wrong with the way you have wired it up as that should not happen.

Just to confirm, a capacitor between GND and DT, another between GND and CLK, and another between GND and SW.

Also with that done you should not need to use software debounce.

No, this far it’s only one 68nF capacitor between GND- and SW-pins on the encoder.
I do not see any need for capacitors between clk-gnd and dt-gnd when volume control works perfectly by rotating the encoder, or do I miss here something?

As mentioned before, when I flip to my volumio2 sd-card, button press works without any error.
Certainly, due to the removed capacitors (between dt-pin and pi, clk-pin and pi)
volume control now no longer works with the sayato-plugin on volumio2.

Just tested, if I set the debounce value in the plugin setting to 0 there are no longer button clicks occuring by rotating the encoder. however, button click still does not work.

Sorry, I must have mis read your previous comment.

If you have a capacitor accross all the switches (DT, CLK, SW) then you should be all hardware debounced and no need for software.

The reason I suggest there may be something a miss with your wiring, turning the rotary should not have any effect on the button as they are not internally connected.

As stated above, for rotating there is obviously no need for hardware debouncing when it works perfectly. It’s just that freaking button click :smiley:

It’s interesting that button clicks are catched when setting a debounce value in the plugin.

Yeah something strange going on.

Have you had your meter between GND an SW while its powered up ? It should read 3.3V until the button is pressed then it should read 0V.

Hi,
I tried to read the new log you posted, but it is quite incomplete. Cannot see the configuration and the lines are only partly there and the timestamps are missing, as well as the carriage returns. Difficult to draw anything out of it.
But at least we can see that the Push-Button is causing falling edges now (Push Button 1 pressed.) that the timers for double-click and long-click detection are starting (Push Button 1 starting timers.) and that it obviously is pressed longer than the setting of the double-push and the long-push timers (Push Button 1 doublepush timer elapsed. (true, 1), Push Button 1 longpush timer elapsed. (true, 1).
If you only short pressed, it means there is already something wrong. BTW: Did you change the timers for long-push and double-push? In your first log they were at 1500ms and 700ms - which is fine.

What is strange is, that there are also often log entries where it says (true,3) or (true, 6) and that is strange. true means, that the plugin considers the button pressed when it logs.
The integer number tells us, how often it detected a rising edge, since the first pressing. But strangely, there never is a log message that it released (should read Push Button 1 released after ###ms.'). Normally the integer is counted up, up to the moment, when the long-push timer elapses and then reset to 0 (even earlier, if a release or double-press is detected).

It almost looks like onoff is only sending falling edge events(pressed) but never a rising edge (released button). I would guess this is either due to a problem with your wiring (as others suggested as well) or something defective with the GPIO. Could also be cross-talk (are you using very long cables?) or leakage (tin whisker, broken isolation)… Or did you wind data-cables around the button cables that could induce digital noise…? Something is really strange.
The other plugin is immune to this. I looked into the code: it also watches rising and falling edges, but it only reacts on the falling edge and does not use the rising one, so it will still work, if there is never a rising edge. But I cannot implement it like that, because to be able to have double-press and long-press detection, I have to use both edges.

Regarding your description of your wiring and the info we received about the KY-040 now, the schematic should look like below, right? However, there must be something hidden in your setup, which is not yet in the schematic, because normally GPIO 4 and 27 should not do anything, when you press the button.

Here is a log of my debug system, showing how it looks normally. (I deleted the redundant stuff) Short Click

Aug 20 21:40:06  Push Button 1 pressed.
Aug 20 21:40:06  Push Button 1 starting timers.
Aug 20 21:40:06  Push Button 1 released after 174ms.
Aug 20 21:40:07  Push Button 1 doublepush timer elapsed. (false, 1)
Aug 20 21:40:07  Push Button 1 sending single push command.
Aug 20 21:40:07  emitPushCommand: 13for Rotary: 1
Double Click

Aug 20 21:40:38  Push Button 1 pressed.
Aug 20 21:40:38  Push Button 1 starting timers.
Aug 20 21:40:38  Push Button 1 released after 152ms.
Aug 20 21:40:38  Push Button 1 pressed.
Aug 20 21:40:38  Push Button 1 released after 133ms.
Aug 20 21:40:38  Push Button 1 doublepush timer elapsed. (false, 2)
Aug 20 21:40:38  Push Button 1 sending double push command.
Aug 20 21:40:38  emitPushCommand: 0for Rotary: 1
Long Click

Aug 20 21:40:43  Push Button 1 pressed.
Aug 20 21:40:43  Push Button 1 starting timers.
Aug 20 21:40:44  Push Button 1 doublepush timer elapsed. (true, 1)
Aug 20 21:40:45  Push Button 1 longpush timer elapsed. (true, 1)
Aug 20 21:40:45  Push Button 1 sending long push command.
Aug 20 21:40:45  emitPushCommand: 0for Rotary: 1
Aug 20 21:40:45  buttonAction: button of rotary 1 pressed but no action selected.
Aug 20 21:40:46  Push Button 1 released after 2510ms.
("but no action selected" just means, that on my test system I have not configured long press and double press)

No, sadly we don’t. To clarify, at no time I pressed the button, not once. The log was written while just rotating the encoder, without pushing, and a configured debounce time of 50ms. At some point while rotating the configured button press action (play/pause toggle) is fired. Simply configuring zero ms leads to no action beeing fired anymore, no more push-related entries in the log.

I will additionally test the second ky-040 encoder tomorrow, which also works perfectly on volumio2: rotate toggles next/pevious track, push cycles through 3 equalizer presets. This encoder is wired to gpio 5 (clk), gpio 6 (dt) and gpio 13 (sw), and I’ll check the voltages of both encoders…

Tested the second encoder, same behaviour, rotating ok after removing the capacitors, but no button click possible. This now eliminates all suspicions of faulty wirings for me, additionally, voltages are 3.3v, at both encoders

And yes, I still don’t get tired to mention that the encoders work well by just inserting a volumio2-sd-card :grin:

I wondered if my troubles really are sourced by the rotary encoder plugin itself, so I swiftly disabled it, happily installed Darmur’s “GPIO Buttons”-Plugin, reboot, just to be sure (yes, I’m a windows victim), and guess what?

No button click is catched, both encoders fail.

Just for fun, I tested an alps-encoder by just connecting the two switch-pins, no button click catched.

alps

data sheet pdf

Good idea, that proved, that it is not code related. Did you try to connect to another pin? If it doesn’t work with two different rotaries and two different plugins, it might be that the GPIO is damaged.
Or did you do some configuration on your old SD card, that is missing on the new one (e.g. some IO remapping in /boot/userconfig.txt or another config file)? It is still strange, that it works with one card and not with the other.

Can’t remember if I touched any config file on volumio2 (it’s been setup 2 years ago) concerning gpio-mapping in regard of button click thingies, but will have a look. Volumio3 is vanilla, no changes on any config files.

Meanwhile, a feature request: one tick rotating left, two ticks rotating right, one tick rotating left again will toggle play/pause.

Just like opening a safe, so I don’t need button clicks anymore :joy:

what GPIO are you using for the push-button?

you can try to enable the pull-up resistor on that GPIO, adding this line in /boot/userconfig.txt

gpio=26=ip,pu

this example is done with GPIO26, please change the number according to your connections