We take a look at these powerful tactile devices. If you haven’t used one yet, you’ll want to soon!
Rotary encoders are perfectly suited for digital electronics. While they provide a tactile interface and have a rotary action, their function is substantially different from their analogue cousins, the potentiometer.
The function of a rotary encoder can be replicated by two tactile switches; an up switch and a down switch. In some instances, this is an appropriate (and perhaps even preferred) interface. However, a rotary encoder combines these into one rotary action.
A rotary encoder feels just like a potentiometer, however, there’s a series of “notches” which you can feel quite distinctly in your fingertips. Each “notch” is effectively like pushing a button, however, there’s additional data provided; direction.
The rotary encoder simultaneously provides a signal that it’s being turned, and also which direction. For each “notch” this data is provided. It effectively tells your electronics “I have just been turned anticlockwise one step” (or clockwise, as the case may be). However, it’s done so quickly that you can rotate it through many steps quickly, providing a potentiometer-like action.
In addition to the clear digital signals, a rotary encoder is “positionless”. This means that there’s no min/max points, and no “middle” in the hardware itself. You can rotate it as much as you like, and it will continue sending the appropriate signals. It’s then up to whatever you’re controlling to set the upper and limits.
This positionless functionality means that rotary encoders don’t need to be physically moved when the software makes a change to its state either. Consider you increase volume using a potentiometer, but the software then changes the volume. Motorised potentiometers are popular in the audio industry to help solve this problem, however, they still won’t overcome a few key challenges that may be faced when using a potentiometer.
POTENTIAL POTENTIOMETER PITFALLS
There are a few things to consider where potentiometers are involved. Realistically, their precision rarely came into question in analogue circuits because it didn’t matter. However, when we have high resolution analogue inputs reading potentiometers, we start to see a different picture.
Potentiometers have been a mainstay of electricity and electronics interfacing since their invention in the 1840s. However, they’re still very analogue, which can create some challenges depending on their use; especially in our digital world.
The first thing we notice at a digital level is that they aren’t necessarily linear. At 50% of their travel they may or may not measure as half of their total resistance. The first 10-15% and the last 10-15% tend to be relatively non-linear and unreliable from an accuracy standpoint. If you only need “rough” values, then you won’t really notice this problem. However, if you’re trying to measure the potentiometer with a high degree of accuracy you may have a few struggles.
The next problem with pots is that they can generate a reasonable amount of electrical noise. They consist of a curved (or straight for slide pots) piece of carbon with a mechanical contact (the wiper) touching the carbon. With repeated use, this can wear or damage the carbon and/or the wiper. This may cause intermittent contact or areas of resistance change giving more non-linearity. Naturally, the quality of manufacture does help, and some name-brand potentiometers are popular in audio circuits for their reliability, however, the variability is reduced, not eliminated.
Trimpots, multiturn pots, and other types of potentiometers each have pros and cons too, but the mechanical wiper itself is what can create variation in the reading. Temperature fluctuations will also affect the resistance of potentiometers since resistance of the materials used changes at different temperatures too. These factors all mean there’s a mismatch in precision. After all, surgeons don’t use steak knives for surgery do they?
ROCKING THE ROTARY
As we have explained in the introduction, rotary encoders do not provide a resistance value at all, so are not prone to variation from temperature like a potentiometer. Rotary encoders are very digital in their design, there’s nothing analogue about them whatsoever. This lends them to the ultimate in precision if you need it.
Unfortunately, a rotary encoder does require two pins (plus ground), but remember we have equated it to two tactile switches, so it does make sense. For many applications they’re more versatile than two switches given a “twist of the knob” is much faster for multiple pulses than pressing buttons, generally.
This monitoring requires some level of electronics and is an ideal application for your Arduino. The output from the rotary encoder is a simple on/off signal or pulse which sounds pretty simple to handle but there are two of these and they are 90° out of phase. This is called having the signals in quadrature. Refer to the diagram below. It’s this difference in position of one pulse to the other that shows that the encoder shaft has been rotated from the previous position but also the direction. This can be used as a value increase (clockwise) or a value decrease (turning the encoder counter-clockwise). However it's worth noting that how you handle the signals from a rotary encoder is entirely up to you.
TYPES OF ROTARY ENCODERS
There are many types of rotary encoder on the market, and different mechanisms can drive their output. At their core, they basically all provide the same functionality. There are a few key differences you’ll encounter.
NUMBER OF PULSES PER ROTATION
Depending on your applications, you may want more or fewer pulses for each full rotation. Most hobby versions will have a low number, perhaps 12 or 24 pulses per 360° rotation. They are also available with thousands of pulses per rotation.
ABSOLUTE AND INCREMENTAL
When we discuss rotary encoders broadly in DIYODE, we’ll naturally reference incremental encoders. These are the most commonly available low-cost encoders, and the type you’re most likely to encounter. A turn left is a pulse left, and a turn right is a pulse right, without regard or consideration for what happened previously. Some also emit a pulse on each revolution, for use in applications such as internal combustion engines, to determine crankshaft position.
Absolute encoders also exist and can provide their positional information back to the control circuit. This can be done in all sorts of ways, including binary via multiple contacts.
DETENT & DETENT-LESS
While probably less popular in hobby electronics, there are an array of rotary encoders which feature no detent (that is, the tactile “notch” of each pulse). There are all sorts of reasons for preferring rotary encoders with and without detent feedback. It really comes down to the application.
If the encoder is being used in a “rotary wheel” type setup where the user may perform multiple full revolutions rapidly, the detent may work against the user for this type of action. They’re also likely getting some visual feedback in some other way (from a screen or control panel). Detentless rotary encoders were used in early computer mice before optical mice became the standard. You can imagine how annoying it would be to have a mouse that vibrated as you moved it across the desk!
USING ROTARY ENCODERS
We have obtained a common encoder from Core Electronics to use with our examples, however just about any hobby encoder should work the same for the examples we’re going to explore. Equivalent options from Jaycar and Altronics are also suitable.
This great budget encoder from Adafruit is the perfect starting point. You might be looking at this encoder wondering why there are 5 pins. That’s because this unit has a small switch in the shaft also, which is handy for actuating additional functions (such as on / off) as well as your rotary encoder function. The three-pin group is for the rotary encoder output, and the two-pin group is for the built-in tactile switch.
There are also rotary encoders with LEDs and other functionality built-in, but we’ll stick with the basics for now. Once you get familiar with these, you might like to explore the fancy versions which are available too!
|Parts Required:||Jaycar||Altronics||Core Electronics|
|1 × Arduino Compatible UNO||XC4410||Z6240||CE05629|
|1 × Rotary Encoder||-||-||ADA377|
|1 × Breadboard||PB8820||P1002||CE05102|
|4 × 10kΩ ¼W Resistors*||RR0596||R7582||PRT-14491|
|1 × 47kΩ ¼W Resistor*||RR0612||R7598||-|
|2 × 100nF Ceramic Capacitor||RC5360||R2865||CE05188|
* Quantity shown, may be sold in packs.
Enough theory - let’s build something! This demonstration circuit is simple enough. We’re literally interpreting the rotation signals from the rotary encoder and outputting the resulting signal to the serial monitor.
The build is simple enough, and you can use just about any Arduino or your favourite microcontroller.
Depending on your encoder, you may encounter “bounce” on the contacts. Bounce is a short period (in the order of mere milliseconds) where the contacts can make and break a number of times before settling to hard on or off as the case may be.
We can attempt to handle this in software, but a hardware solution is generally the best option. This solution is a tried and true RC (resistor capacitor) network technique to filter this bounce out. As we are monitoring 2 pulse streams we have 2 debounce networks. Thankfully, these are a simple matter of 2 resistors and 1 small capacitor per network. The debounced pulses are then fed to digital pins on the Arduino to be processed.
There are many example sketches and libraries with different approaches to using rotary encoders. Some of these libraries are good solutions but quickly bloat the code. Therefore we have opted to heavily modify a demonstration sketch from Sparkfun to suit our purposes. It does not use interrupts or external libraries.
Load the rotary_encoder_build_1.ino sketch to your Arduino. Once it’s successfully compiled and loaded, open the Serial Monitor.
If you now twist your rotary encoder one way or the other, you will see output to serial monitor accordingly. You’ll see the output displays the direction of the shaft, as well as an incrementing/decrementing value according to the number of pulses received. We also have an additional output showing whether the switch built into the shaft is depressed or not.
Due to clock speeds, sampling, and other factors, it’s possible that your microcontroller will sample multiple increments or decrements from one turn. Our code also handles this to reduce this oversampling. The same issue occurs in various measurement methods of tactile switches too, so the problem is well known and easily catered for.
The use of interrupts can assist with this issue, however, we quickly run out of pins we can attach interrupts too. Therefore polling can be a more sustainable approach when attaching multiple interfaces.
This is only example code and could be improved over time too, depending on your preferred approach to the code and application.
|ADDITIONAL Parts Required:||Jaycar||Altronics||Core Electronics|
|1 × Servo SG90 180° Servo Motor||YM2758||Z6392||SER0043|
Serial monitor is great, but let’s look at controlling something. It could be motor speed (PWM), volume control, or just about anything else, but we’ll use it here to control a servo, since it provides a practical demonstration of a few different principles.
The wiring for this build is identical to the first build but we have added the servo motor as shown in the diagrams. Any servo will do, however, we’ve assumed the use of a SG90 180° servo motor.
Load the rotary_encoder_build_2.ino sketch onto your Arduino. As soon as it’s compiled and loaded, you should see your servo reset. Open Serial Monitor for additional information.
Now as you twist the rotary encoder clockwise, you’ll see the angle of the servo motor adjust its angle accordingly. The actions being taken are shown on serial monitor also. If your servo isn’t moving, double check the wiring.
You’ll notice a few things are being done here in the code, which provides good working examples for you.
MULTIPLIER & MAPPING: Since there are only 20-something pulses per rotation of the rotary encoder, it would take six or more full turns to take the servo angle from 0° to 180° if it was one pulse to one degree of rotation. Therefore, we map each pulse to a 5° rotation. This multiplier is set with the variable “servoIncrement”. This allows us to achieve a full 0° to 180° range with something closer to 1.5 rotations.
This multiplier can easily be adjusted to further reduce the number of turns required. A multiplier of 18 for example, would mean only 10 pulses are required for full servo range. If you wanted to have the servo only have 5 positions (0°, 45°, 90°, 135°, 180°) you can see how easy it is to achieve that. You could even feasibly have the software adjust the multiplier between "high" and "low" when you depress the pushbutton in the shaft!
SOFT LIMITING: While the rotary encoder can be turned in either direction perpetually, the hardware (or just the variables) you’re controlling likely has some limits. You can see in the code that we monitor the servo’s position. If the angle of the servo is at either limit (0° or 180°) then we simply ignore the request.
This sort of soft limit is a great way to ignore out of range requests. You won’t hurt the rotary encoder, you won’t damage hardware when it’s perhaps not limited internally (say, limiting a 300° servo to 180° of range), and you won’t potentially send your software out of range (say, assigning a long number to an integer).
WHERE TO FROM HERE?
You should now have a great understanding of rotary encoders and how they can be put into practice. Play around with the values, and see what other applications you can find for them too!