Want rotary encoder with increasing counts per click as rotation speed increases.

wapo54001

Senior Member
I am designing a rotary encoder to send data via I2C to another board. The encoder controls across the range of 1-255 counts, and if each click controls one count it takes many turns of the encoder to go from 1 to 255.

If possible, I would like to design the software so that as the speed of rotation of the encoder knob increases, so too does the number of counts per click of the encoder. Thus, a slow rotation results in one count per click and delivers fine resolution, but a fast rotation delivers up to five counts per click for rapid movement from one end of values to the other.

I can't think of a way to accomplish this, but surely there is something out there? How do you measure the rate of clicking of an encoder??
 

Reloadron

Senior Member
Forgive me but what exactly is a "click"? Would a click be a pulse? You are looking at rotational speed as in measuring a shaft speed? Exactly what make and model encoder are you using and do you have a link to the data sheet?

Ron
 

eggdweather

Senior Member
You count the number of rotations per unit of time to measure rate of change, so store the current rotation count at a time value then count the rotations and act on the rotations, then read the time again and the number of rotations at that time and the new time will enable you to work out the unit-time rotations (rotations at the end - rotations at the start) / (time vale at the end - time value at the start) and if this value exceeds a given value quickly advance and act on say 5 extra rotations but outside of the normal routine, so no need to check for an input change from the shaft encoder.
 

wapo54001

Senior Member
Sorry, one never explains enough -- it's a rotary encoder with a knob that is turned by hand, it takes the place of a conventional potentiometer. A potentiometer would cover 255 (ADC) counts with one rotation of the knob but a rotary encoder with 12-20 counts per revolution requires a lot of turns to cover the same range if one encoder count equals one ADC count.

It certainly is possible to make one encoder count equal three or five or ten ADC counts, but then you lose resolution. The only way to get both speed of change and precision when you want it is to have the response act like a ballistic mouse -- the pointer of which travels further per unit of mouse movement the faster you move the mouse. That effect is what I would like to achieve with a rotary encoder.
 

AllyCat

Senior Member
Hi,

One possibility might be to emulate the "Reverse Vernier" (mechanical device) as used for tuning some old radios. Basically, when the knob is rotated (in either dircetion) it "tunes fast" (e.g. 5 steps per "click") but when it is then turned back in the opposite direction it steps by only one step per click. After perhaps 10 clicks it returns to "fast" movement (in the reversed direction).

An advantage of this method is that it doesn't require any "timing" as such; the code just needs to "remember" the last click direction (and the number of clicks in that direction) and then steps at the appropriate speed in the selected direction.

Alternatively, testing for an increase in the "time" variable can be a useful way for a program loop to check the click speed. For example, if the number of clicks increases by more than 2 between each time increment, then use a larger step value. You might even set the step size to the number of clicks which occurred in the previous second, to create a "pseudo-logarithmic" speed characteristic.

Cheers, Alan.
 

hippy

Technical Support
Staff member
eggdweather nails it in post#3; it is a time domain problem. You apply a multiplier to the actual number of clicks to increment by depending upon the rate of clicks.

You can do that two ways: As eggdweather suggests by counting clicks in a time period, or by determining the time since the last click.
 

wapo54001

Senior Member
I think I have found an easier alternative to time-based solutions.

I set a byte counter to 1, then increment it with every click of the encoder and then increment the next click with the value in the counter. So, as the number of clicks increases within one set, the count-per-click also increases. Right now, with my particular encoder, it looks like at the end of each 'spin' the count is moving by 10~12 per click. That may be too much, but I can easily put a limit on the counter.
 

hippy

Technical Support
Staff member
the number of clicks increases within one set
What exactly is a set, and how is that determined ?

I think I understand what you are doing but I recall the usual problem with that technique is a slow continuous turn can give the same result as a quick short turn. That might not however be a problem for this case or implementation.
 

wapo54001

Senior Member
It works because of matherp's original brilliant code which is a loop within a loop. My understanding is that the inner loop holds the operation until movement stops, and then goes to the outer loop (but there is a complicated interrupt arrangement involved, so I may not understand it all). I reset the counter in the outer loop after the inner loop finishes.

His original code can be found here http://www.picaxeforum.co.uk/showthread.php?20710-Controlling-and-application-with-both-IR-and-a-rotary-encoder&highlight=matherp+rotary+encoder.

And it's definitely working well, I can move one count with one click and fifty or more counts with a smooth full rotation of the knob.
 

wapo54001

Senior Member
In case this technique is of interest to someone else, I'll pass on that I found that steadily increasing counts-per-click from one count per click to nine counts per click (1,2,3,4,5,6,7,8,9,9,9,9,9 ....) didn't work well because of inconsistencies in the twisting of the knob. I had much better luck more rapidly going to six counts per click and staying there (1,2,4,6,6,6,6,6,6,6 ....) It gave just about the same high speed result per twist of the knob, and in a much more consistent way. Normal rotation of the knob stays at one count per click.
 
Top