I currently have a project with a user interface that consists of an LCD screen and a small number of momentary pushbuttons. Users interact with the buttons to control the behavior of the device.
The buttons are a bit awkward, which has me thinking about replacing them with a pushbutton rotary encoder. The user would scroll through menus by turning the encoder, click it to choose a setting, then spin the encoder to increment or decrement the value. I can picture this having a sort of ipod-like simplicity and I really like it.
However, I don't have a bunch of free pins sitting around. The pushbuttons are working on an analog input pin with a series of resistors acting as voltage dividers such that I can detect which button was pushed and act accordingly. Has anyone ever done this approach with a rotary encoder? Does it strike anyone as being within the realm of possibility?
I've seen the rotary encoder page on the playground:
but after a quick scan it looks like all of those examples require multiple pins (worst case, interrupt pins). I don't care a ton about accuracy or speed. I have no experience with rotary encoders so I plan on experimenting a bit with this, but I figured I'd throw the question out to see if someone else had already solved this. Looking at the graph of "a" and "b" waveforms in the first example in the playground, it strikes me that you could put the two on one pin with a resistor divider, and then just work out the maths to determine which transitions indicated which state(s) for the encoder.
OK just thinking out load here. You could use a Nx1 rotary switch (remove the stopper) to select various resistors and feed that into an analog input. You could detect the turning in either direction that way but I've not seen a rotary switch that also has a push button.
Rotary encoders typically have a common terminal for the A and B channels and the pushbutton. This common terminal is normally connected to ground and the 3 outputs are sent to individual pins with pull-ups enabled.
However if you connect the common terminal to an analog pin, and via a 10k resistor to ground, then each of the other pins can be fed +5V via a different value resistor (say 4k7, 10k, 22k) then you will get a unique voltage at the analog pin for each of the 8 possible states I think...
MarkT:
However if you connect the common terminal to an analog pin, and via a 10k resistor to ground, then each of the other pins can be fed +5V via a different value resistor (say 4k7, 10k, 22k) then you will get a unique voltage at the analog pin for each of the 8 possible states I think...
This is what I had in mind, more or less.
I really doubt that an analog read would be anywhere near fast enough to catch a rotary encoder.
Care to explain? How fast does something need to be to catch a rotary encoder? This will be an input on a UI, i.e. a human will be turning a knob.
Also keep in mind that rotary encoders can be kinda jittery. I recommend a hardware debounce, which might be a little more complicated using a resistive network. Maybe not, but it would sure help to see the waveforms on a scope first. Do you have one?
On a related note... The nice thing about the interrupt / digital read is that the signal is either above the comparator or not. On an analog read, you could potentially be sampling somewhere along the LOW / HIGH transition. So, if your debounce slows the transitions much, you have that statistic to contend with as well.
Even with a human turning the knob, quadrature encoders are really chatty. You may need to change the ADC resolution to get faster samples (both to catch the pulse and to finish reading quickly enough to be available to catch the next one), which will of course make your readings less precise.
In other words, it's entirely possible, but it will likely complicate things. IMHO, encoders are complicated enough on "slow" GP microcontrollers as it is. You could always look into a dedicated driver IC that speaks serial, or get a knob with such a thing built in. Just a thought.
analogRead takes about 0.1ms, so it should be fast enough assuming no/little contact-bounce. But with a single pin there is the problem of recognising contact bounce in the first place, which I have glossed over.