How to use Rotary Encoder with Arduino
We were using a pot to light up all LEDs in this 8×8 LED Matrix this week. Well, look at Rotary encoders, the electronic parts that are also the type of position sensors, but they achieve the same objective in a completely different way. If you want to see how rotary encoders work and how they differ from rotary potashometers stick around Music here is the rotary encoder. It looks similar to Rotary potentiometer, but there are some distinct differences. Encoders shaft can turn endlessly in any direction, unlike potoshometer shaft, which can only turn by 270 degrees. Potentiometer shaft turns smoothly, while encoders shaft gives some intermittent resistance when turning accompanied by the clicking sound. Also, when pressing the shaft, it works as a momentary push button, which is not the case for the potashometer rotary encoder has five pins usual ground and 5 volt pins and then CLK and DT pins, which are output, pins that produce electronic pulses when the shaft is Rotated you would ask why two pins, and not just one this will be explained later in this video and finally, SW is an active low push button output when the shaft is pressed. The voltage on that pin goes low. Now lets look closer at the encoder when turning the shaft. The signal at the CLK pin looks like this. The signal at the DT pin looks very similar, but it is not the same. It lags behind CLK by 90 degrees. Phase shift why this shifted output is used to determine the direction of rotation.
This is actually pretty smart idea, but before I will show you the method to figure out which direction the shaft is turning, lets, look at how the encoder is built and how the two out outputs, the primary one and the shifted one are produced inside the encoder. Is a slotted disk that is connected to the common ground? It also contains two contact pins when you turn the shaft those pins connect to the Common Ground, pin in a particular order, according to the direction in which you are turning the shaft when they come into contact with the Common Ground, signals are generated. These signals are 90 degrees out of phase with each other, as one pin comes into contact with the common ground before the other pin so before we start writing the code to detect if the shaft is moved and in which direction lets connect the encoder to Arduino. First, starting with connecting ground to ground and positive pin of an encoder to 5 volt pin of Arduino, then we connect CLK, pin to Arduino digital pin D3. This pin can be configured to trigger interrupts if you are not familiar with using Hardware interrupts. Please check this recent video of mine, so here we would use falling mode, which means well check and react when the signal on digital pin D3 would change from high to low. In this case, ISR interactive service, routine, called shaft moved, would be executed. And finally, we have DT pen connected to Arduino digital pin 4.
lets do a quick simulation and see if we can figure out in which direction the shaft is turning using interrupt and the shifted signal read at the DT pin rotary encoder, unlike potentiometer, does not remember The current position it can be turned infinitely to the right and to the left. So whenever you power the project that is using the encoder, the current shaft position is the starting position and in the code it would be represented by counter variable. This variable stores the relative count of impulses detected at CLK pen since the start. In this example, we have 0, as is the starting point. Shaft is turned to the right until we reach the moment in time where the signal on CLK pin drops from high to low that triggers the interrupt service routine, and in this ISR we check what was the reading at the DT pin at the time when interrupt Was triggered, you could see that we read High signal and if you look closely youd realize that this only happens when we turn the shaft to the right. This way we just detected rotation direction. The shaft is turning clockwise. We also increase the counter by one. If we continue turning the shaft to the right well get to the another situation, where interrupt would be triggered again, DT pin returns, High signal direction is still clockwise and we increase the counter to two lets check. What happens when we turn the shaft to the right when we get to the point where signal on clock pin goes from high to low we check and see what is the current signal on a DT pin and this time it is low that indicates that the Direction is counterclockwise.
Now we decrease the counter by one continuing we encounter yet another interrupt triggering event, and the counter is now back to zero one more and you will see that the counter could go to negative territory when turning the shaft each time. The signal changes on either of the two pins you hear and feel a distinct click. So in this scenario the counter would change every two clicks of the shaft. Knowing what we know now, we are ready to write simple code that will recognize the direction of the shaft movement and keep track of the relative position of the shaft since the schedule started. So we need two variables. One would be counter and we would choose to start at zero and the other one is the variable representing direction. We start with blank value as at the start, the direction is not yet known in setup. We open the serial port and declare that interrupt at Pin 3 that will execute ISR called shaft moved and it will be executed when the signal at Pin 3 would change from high to low. Since we also need information from DT pin, we declare it as input in Loop. We only send the current values of Cam enter and dir variables to the serial, monitor nothing more. So all the fancy stuff happens in the ISR function. When this function is executed. We know that the signal at clock pin has just changed from high to low if we at this exact moment check the signal at DT pin and it is high.
We know that we are turning the shaft to the right and thus we increase the counter by 1 and set the dir variable to clockwise CW. We do the similar if statement for the situation when we read low at the DT pin. In this case, we decrease the counter and change the direction to counterclockwise. I always like to protect the ISR routine against glitches and situation, where triggering event is interpreted as two triggering events, and the ISR is performed twice unnecessarily. That additional code makes sure that ISR is only performed when at least 5 milliseconds passed since the last execution of that ISR lets connect the encoder to Arduino, starting with ground 5 volts, then clock, pin data pin and finally, SW pen lets load the code and open The serial monitor you can see that you can increase the counter by turning the shaft right and decrease it by turning the shaft left. The counter value can go below zero. If you watched my video about potentiometers, you would remember that at this stage we discussed map function where we would map the reading of the potentiometer that was within the potentiometer range to whatever range we needed in our code. We cannot really use map function in this code, AS encoder has an infinite range. So if we wanted to control a sample range like this one 5 to 10, how could we do it? For starters, we have to change the initial value of the counter variable, so it is set within controlled range.
I chose to set it to the lower end of the range in this example and then in ISR. We change two lines of code, so we only change the counter variable if we are moving within defined range when we move outside that range further. Turning on the shaft does not affect the comp and it stays at border value. Only when we move the shaft in the opposite direction, the counter value can change again. Lets reload the changed code and check the result in serial monitor. We start with counter value 5 and we are turning shaft clockwise. We can increase the counter up to 10.. If we turn shaft further to the right, the counter value remains unchanged same with turning the shaft to the left. We can go down to 5 and then the counter would not decrease further. In the potentiometer video, we are controlling the range from 0 to 63, which was representing LEDs in this 8×8 Matrix lets control a different range. Today in one of my videos, I created the single digit module that was using shift register. I will not explain how this works, but if you want you can always check it out. This video would explain the concept of using shift register to control multiple seven segment displays, and those two would show you how I built that particular module for the purpose of this video. The only thing you need to know is that there is function called display digit that outputs the desired digit you can find the link to the entire code, including the shift register stuff in the description below connecting this module to Arduino, is also of the topic.
Lets create the project in which we control this display with rotary encoder with one extra twist pressing. The push button will reset the range to zero. With the module connected. We can now write the code, well, not write it from scratch, but rather adjust the code from the previous example. The range is now from 0 to 9, so we need to adjust the initial counter value to 0. First also, we need to update range border values in the ISR routine will not use dir variable so lets get rid of this declaration, plus the two obsolete lines in the ISR code will not output anything to the serial monitor, so lets get rid of print commands In the loop function, we would call the display digit function instead to display the current counter value. Since we are not using serial monitor, we do not need to open serial Port, we are nearly done. We need to program the push button to do it. We Define the second interrupt on digital pin 2, which is the PIN to which we connected SW pin of rotary encoder. It is also triggered upon the change of the signal from high to low. Since the push button is active low. We need to activate built in pull up resistor for the digital pin 2.. We do it by declaring this pin as input pull up. This interrupt has a different, interrupt service, routine called reset to zero, which resets counter value back to zero lets load the code and see how this works.
We can control the display, lets see the button works, it does so generally encoder works, but have you noticed every now and then the digit skips back to the previous value, and this can be quite annoying. I was looking for quite a while for a solution to this, and the answer was to change the interrupt mode from falling to low Im, still unsure why this would make a difference, but, as you can see, it clearly does. If you can explain this to me by all means enlighten me in the comment section below so I think this is time to compare the encoder to potentiometer and pinpoint five major differences between the two. First and foremost encoder is a digital component and potentiometer is analog. So we use digital, read method, to read the value from encoder pin and we are able to use interrupts for potentiometer. We need to use analog method to read analog values from the potentiometer pin. Potentiometer has a fixed range and remembers the current position within that range. It also recognizes the direction in which the shaft is turning. Encoder does not have a fixed range and moving within the range, then remembering the position and recognizing in which direction the shaft is rotating has to be programmed in the Arduino sketch. Thus, potentiometers are used in situation where you need to know the exact position of the shafts, whereas rotary encoders are used in situations where you need to know the changed in position rather than the exact position.
The reading from encoder is more stable. That is, of course, after fixing the problem we encountered in this video values from a potentiometer fluctuate a bit. We also had a problem and had to use tweaks to represent border values of the controlled range for potentiometers to control the desired range. We used map function to convert the pots range to the desired range for encoder. We cannot really use map function and to control desired range. We need to code it and finally, the encoder has push button functionality which can prove very useful at times and potashometer does not. So if you need that functionality, you need additional components in your project. There here are five main differences. Have I missed anything, and that brings us to the end of this video. I hope you learned something new. I definitely did thanks for all the likes and subscriptions. They help this channel to grow still waiting for your super thanks.