Thank you for your donation!


Idea: Enhanced rotary encoder & button input
#1
Hi,

I've been enjoying moOde audio for a while now and would like to propose some enhancements to the rotary encoder and button input.

Right now, there is only one rotary encoder supported to control volume. Also the program is using polling and waking up regardless if there were turning events or not.
The buttons can be configured to execute only one command, but it would be nice to have an alternative / secondary command to execute for long-presses.

That said, I don't want to complain about the software the moOde audio team is making available to us, but I wrote two new tools which have the mentioned enhancements and a few more extra features.

Please check out the source code at:
https://sourceforge.net/projects/interactivipi/files/

Both tools can be built with a simple 'make' command and are named 'rotenc' and 'pushbtn'. (Yeah, it's also called rotenc since its a short and descriptive name and also inspired by your original code)

Both tools work with config files. rotenc supports up to 4 encoders with user-customizable commands per turning direction, different encoder models (e.g. with different signals per detent or 'click') and using absolute or relative position changes in the commands by putting '${%}' in them.
As a little add-on I think the encoder feels much more precise since the number of increments can be passed to scripts instead of fixed values.
pushbtn supports virtually endless buttons with user-customizable short- and long-press commands.

See included README and example .conf files for some more information, but the included example configs should explain most of it easily.

So, please try it and consider including this into your great moOde audio project if you also think it's an enhancement.
If you have some feedback or want something changed, I'm open to suggestions.

I don't have a concept on how to generate the config files from the UI of moOde yet, so this needs to be solved if you decide you want to include it. Also I'm not really experienced with web/php/... development.

best regards,
Peter
Reply
#2
Hi Peter,

Great work :-) I'll see what it might take to integrate these and provide UI config panels for them. One challenge is that the maintainer of WiringPi deprecated the project before fixing some bugs that prevent it from working correctly on Pi-4B :-(
http://wiringpi.com/news/

I had to switch to the Python based RPi.GPIO library because of this.

-Tim
Reply
#3
Hi Tim,

I'm glad you are considering using my tools in moOde audio!

I was aware that Gordon Henderson stopped development of his wiringPi library, but I thought it would work on Raspberry Pi 4s.

My plan is to migrate from wiringPi to some other (maintained) library in the near future, but I am actually not sure what library to use instead of wiringPi yet. Currently the most promising project I have found is pigpio ( http://abyz.me.uk/rpi/pigpio/ ).
It seems to be maintained, stable and feature-rich. Also, there are a few ports to different programming languages (and an official Python module by the way) which make this project quite interesting.


Maybe you can share your opinion on pigpio or propose something else (usable with C preferably), since you'd have to include the library in moOde if you'd like to include it. As I said, I'm not really sure what will be a good substitute for wiringPi, so I'd appreciate any thoughts on this matter.

Some other things I have on my mind are config options for
- pull-up/-down resistors
- defining high or low level as 'button pressed'
- another mode for buttons that work as switch instead of push buttons (i.e. executing commands depending on state)

But since this is a 'hobby' project for me, I won't finish these tomorrow. And after learning wiringPi will cause issues on Raspberry Pi 4s, I'll probably do the switch to another library rather sooner than later.

Peter
Reply
#4
Hi, Peter.

This item caught my eye:

Quote:- another mode for buttons that work as switch instead of push buttons (i.e. executing commands depending on state)
Have you considered the possibility of using multi-position selector switches, like a rotary switch with 8 positions? If encoded, the position could be determined with 3 input bits.

Just a thought.

Regards,
Kent
Reply
#5
Hi Kent,


I haven't considered these yet, but only because I didn't know they existed.
You mentioned one of these selector switch with 8 positions and 3 outputs (which makes sense since bits have two states and 2 to the power of 3 is 8), but after a very short search I didn't find any of these.
Just out of curiosity, do you own one of these and is it something one can buy ready-to-use or are these DIY projects made of similar switches (which I found but have about as many pins as positions)?

But including support for these and similar switches should be possible by reading the pin states as bitmaps and making unique values determining specific commands to be executed.
I'd have to add support for multiple pins, a few more distinct commands per button and think of a appropriate configuration format for these.
Do you know of any of these switches with 16 or maybe even 32 positions? If I add it, I should probably consider variants.

Peter
Reply
#6
Hi, Peter.

I don't have one now. I was thinking of tricks we'd play with rotary switches in machine control.

Similarly, we'd use diode matrices to encode push buttons when we had more buttons we had input pins.

All very DIY.

Regards,
Kent
Reply
#7
(05-02-2020, 09:15 PM)Tim Curtis Wrote: I had to switch to the Python based RPi.GPIO library because of this.

Tim, would you consider including the pigpio lib in moOde or would you prefer another library (available for C) as replacement for wiringPi?
I don't want to make the possibility of using my tools unnecessary complicated for you and as I said, I still haven't really decided what to use in the future myself. So I'd really appreciate your feedback on this.

(05-03-2020, 09:41 PM)TheOldPresbyope Wrote: All very DIY.

If you're planning to build a selector switch I'd be really interested in the wiring, since I can't imagine any easy way.
Alternatively, a easier solution may be adding a 'modifier button' that allows a secondary set of functions to the other buttons if pressed to save GPIO pins. Of course this would lead to less possible functions (2*(n-1) vs. 2^n) and not work with rotational switches, but would avoid the complicated wiring.
Reply
#8
@pgzh1

My apology for this lengthy word description but I discovered after a few minutes that my favorite diagramming tools are great for circuits and lousy for diode matrices.

Let's consider the 8-position switch I mentioned. It will be obvious from the following how to use switches with fewer or more positions.

Eight states can be represented by three bits: 000, 001, 010,..., 111, which we old minicomputer programmers think of as octal 0-7. 

So take three GPIO input pins pulled down to ground internally (and maybe with external 10K pulldown resistors to ensure adequate diode current flow).

Wire the common pole of the single-pole 8-position rotary switch to +V (probably +3.3V for RPi GPIO).

Position 1 is left unwired. (state 000)

Position 2 is connected via 1 diode to input pin 1 (state 001).

Position 3 is connected via 1 diode to input pin 2 (state 010)

Position 4 is connected via 2 diodes: one to input pin 1, one to input pin 2 (state 011).

Position 5 is connected via 1 diode to input pin 3 (state 100).

Position 6 is connected via 2 diodes: one to input pin 1, one to input pin 3 (state 101).

Position 7 is connected via 2 diodes: one to input pin 2, one to input pin 3 (state 110).

Position 8 is connected via 3 diodes: one to input pin 1, one to input pin 2, one to input pin 3 (state 111).

In all cases, the diode's anode is wired to the switch position and the cathode to the input pin. (If one decides to reverse the sense of the circuit so that pins are normally pulled up to +V and the switch/diode selections pull them down to ground, then the diode directions must be reversed.)

That's 12 diodes (and 3 resistors). Easy peasy for a hacker's junkbox like the one in my basement.

Usually this is represented in a rectangular diode matrix aka diode crossbar form (look up "diode matrix").

It can be extended to more states but the diode count keeps mounting. More likely one would use 7400-series OR gates, a bespoke 7400-series IC encoder, or even a microcontroller chip (there's a ton of nice little chips-on-boards out there, all of them cheap and easy to program).

Things to think about: 

- Garden variety diodes have an internal voltage drop of about 0.6V, so a GPIO input pin would see about 2.7V in the high state if we wire to +3.3V. As I understand the RPi docs, the voltage threshold for a GPIO pin is guaranteed to be somewhere in the range of 0.8V-2.0V, so we should be good.
- All three input pins would have to be monitored for a change of state.
- As with any mechanical switch, debouncing is required, either in hardware or software, but the situation is made complicated by the nature of a rotary switch. Whether the contacts are break-before-make or make-before-break, the short-term outputs generated by rotating the switch through one position or many are "interesting". Gray code was invented to avoid some of this but it's not a panacea. Probably just a long time-out is the easiest way out.

Alternatives one could think of for making one-of-many selections (like, say, a specific radio station) include using an entry keypad. O, the tangle webs we weave!

Regards,
Kent
Reply
#9
(05-08-2020, 09:49 AM)pgzh1 Wrote:
(05-02-2020, 09:15 PM)Tim Curtis Wrote: I had to switch to the Python based RPi.GPIO library because of this.

Tim, would you consider including the pigpio lib in moOde or would you prefer another library (available for C) as replacement for wiringPi?
I don't want to make the possibility of using my tools unnecessary complicated for you and as I said, I still haven't really decided what to use in the future myself. So I'd really appreciate your feedback on this.

(05-03-2020, 09:41 PM)TheOldPresbyope Wrote: All very DIY.

If you're planning to build a selector switch I'd be really interested in the wiring, since I can't imagine any easy way.
Alternatively, a easier solution may be adding a 'modifier button' that allows a secondary set of functions to the other buttons if pressed to save GPIO pins. Of course this would lead to less possible functions (2*(n-1) vs. 2^n) and not work with rotational switches, but would avoid the complicated wiring.

I don't have enough experience with GPIO libs to make a specific recommendation but I certainly could include the pigpio library in upcoming moOde 6.6.0. The only concern is that the maintainer notes that there may be issues on Pi-4B http://abyz.me.uk/rpi/pigpio/

"At the moment pigpio on the Pi4B is experimental. I am not sure if the DMA channels being used are safe. The Pi4B defaults are primary channel 7, secondary channel 6. If these channels do not work you will have to experiment. You can set the channels used by the pigpio daemon by invoking it with the -d and -e options, e.g. sudo pigpiod -d 5 -e 8 to specify primary 5, secondary 8."


But unlike WiringPi this lib is actively maintained and so there would be a likelihood that 4B issues would be fixed :-)

-Tim
Reply


Forum Jump: