You could just use
encoder.read() / 4, so the value would only change every 4 steps.
Or if you know how many menu options you have, you could use range mapping to map the potentiometer’s output range to your options.
(Before anyone says ‘a rotary encoder is not a potentiometer’, I am aware they’re different things, but they’re both angular inputs so I’m doing some handwaving and pretending they have the same abstract role.)
Arduino comes with a
map function which will probably suit your needs, but be careful about fractions.
If you have a lot of options and the fractions issue becomes a problem then you may be better off using a
float map(float value, float lowerInput, float higherInput, float lowerOutput, float higherOutput)
return (lowerOutput + ((value - lowerInput) * ((higherOutput - lowerOutput) / (higherInput - lowerInput))));
Anyway, you’d use it like:
// Assuming 1023 is the maximum value you'll get out of the potentiometer
option = map(encoder.read(), 0, 1024, 0, optionCount);
The effect is that the potentiometer’s turn arc essentially gets divided up like a pie chart, with each slice of the arc representing a different menu option.
However, this assumes your potentiometer has a ‘start’ and ‘end’ point and doesn’t just spin constantly like a mouse wheel.
If you’ve got a ‘mouse wheel’ style input then you pretty much have to just use the delta (the change in position). Though you can still shrink and maginify that change with division, multiplication or mapping.
A few other tips…
If you do end up sticking with the clockwise/anticlockwise approach, you might be better off using a scoped enumeration instead of a pair of
enum class TurnDirection : uint8_t
Alternative you could use the difference between the old value and the new value to determine the direction, because the difference will be negative, positive or zero depending on the direction the potentiometer has moved.
Which way round it is would depend on how the potentiometer is set up. Assuming the values increase as the potentiometer is turned clockwise, doing
(newPosition - oldPosition) would give a positive result for clockwise turns and a negative result for anticlockwise turns.
Then you can just do:
if (difference < 0)
else if (diffence > 0)
// No change
For what it’s worth, you may as well just do
oldPosition = newPosition; regardless of whether
newPosition != oldPosition, it’ll make your code a bit easier to read and the 2-4 cycles saved by trying to dodge the assignment aren’t really worth it.
Lastly, make sure to avoid using ‘all caps’ (a.k.a. macro case) for anything other than macros, as is C++ convention.
For the record, I think
Encoder is a really terrible library name because encoding is an abstract concept and there are many different types of encodings. E.g. text encodings. Without more details, one would be forgiven for assuming
Encoder was for encoding text or did base 64 encoding or something similar.