How Rotary Encoders Work and Interface With Arduino

by Lisleapex Blog in Circuits > Arduino

134 Views, 0 Favorites, 0 Comments

How Rotary Encoders Work and Interface With Arduino

Connecting The Rotary Encoder To The Arduino.jpg

We are surrounded by rotary encoders without even realizing it, as they are used in many everyday items, from printers and cameras to CNC machines and robots. The most common application for a rotary encoder is the volume knob on a car radio.

Supplies

  • Rotary encoder
  • Arduino
  • servo motor

Rotary Encoders and Potentiometers

The rotary encoder is the modern digital equivalent of the potentiometer and is more versatile.


A rotary encoder can rotate a full 360° without stopping, while a potentiometer can only rotate 3/4 of a turn.


A potentiometer is used in situations where the exact position of the knob needs to be known. On the other hand, a rotary encoder is used in situations where the change in position needs to be known, rather than the exact position.

How Rotary Encoders Work

contact pins A and B.png

The encoder has a slotted disk inside that is connected to a common ground pin C. It also has two contact pins A and B.


When you turn the knob, A and B make contact with the common ground pin C in a specific order, depending on the direction you turn the knob.


When they make contact with the common ground, two signals are generated. These signals are 90° out of phase because one pin touches the common ground before the other. It is called quadrature encoding.


When the knob is turned clockwise, the A pin is connected to ground before the B pin. When the knob is turned counterclockwise, the B pin is connected to ground before the A pin.


By monitoring when each pin is connected or disconnected from ground, we can determine the direction the knob is turned. This can be done by simply observing the state of B when the state of A changes.


When A changes state:


If B != A, turn the knob clockwise.


If B = A, turn the knob counterclockwise.

Rotary Encoder Pinout

Rotary Encoder Pinout.png

GND is the ground connection.


vcc is the positive supply voltage, usually between 3.3 and 5 volts.


SW is the output of the push button switch (active low). When the knob is pressed, the voltage goes low.


DT (output B) is similar to the CLK output, but lags CLK by 90° phase shift. This output is used to determine the direction of rotation.


CLK (output A) is the main output pulse used to determine the amount of rotation. Each time the knob is turned in either direction with only one detent (click), the "CLK" output goes through a high then low cycle.

Connecting the Rotary Encoder to the Arduino

Connecting The Rotary Encoder To The Arduino.jpg

Now that we understand how the rotary encoder works, it's time to use it!


Let's connect the rotary encoder to the Arduino. The connections are pretty simple. Start by connecting the +V pin of the module to the 5V output of the Arduino and the GND pin to ground.


Now connect the CLK and DT pins to digital pins #2 and #3 respectively. Finally, connect the SW pin to digital pin #4.


The image below shows the wiring.

Controlling Servo Motors Using Rotary Encoders

Controlling Servo Motors Using Rotary Encoders.jpg

In the following example, we will use a rotary encoder to control the position of a servo motor.


This project can be very useful in a variety of situations. For example, if you want to operate a robotic arm, it can help you accurately position the arm and its grip. If you are not familiar with servo motors, read the following tutorial.


Wiring

Let's include a servo motor in our project. Connect the red wire of the servo motor to an external 5V power supply, the black/brown wire to ground, and the orange/yellow wire to digital pin 9, which is PWM enabled.


Of course, you can use the 5V output of the Arduino, but keep in mind that the servo may induce electrical noise on the 5V power line, which may damage your Arduino. Therefore, it is recommended that you use an external power supply.

Arduino Code

This is the code for precisely controlling a servo motor using a rotary encoder. Each time the knob is turned one notch (click), the position of the servo arm changes by one degree.


Here are the following codes,

// Include the Servo Library

#include <Servo.h>

 

// Rotary Encoder Inputs

#define CLK 2

#define DT 3

 

Servo servo;

int counter = 0;

int currentStateCLK;

int lastStateCLK;

 

void setup() {

 

// Set encoder pins as inputs

pinMode(CLK,INPUT);

pinMode(DT,INPUT);

// Setup Serial Monitor

Serial.begin(9600);

// Attach servo on pin 9 to the servo object

servo.attach(9);

servo.write(counter);

// Read the initial state of CLK

lastStateCLK = digitalRead(CLK);

}

 

void loop() {

     

// Read the current state of CLK

currentStateCLK = digitalRead(CLK);

// If last and current state of CLK are different, then pulse occurred

// React to only 1 state change to avoid double count

if (currentStateCLK != lastStateCLK && currentStateCLK == 1){

// If the DT state is different than the CLK state then

// the encoder is rotating CCW so decrement

if (digitalRead(DT) != currentStateCLK) {

counter --;

if (counter<0)

counter=0;

} else {

// Encoder is rotating CW so increment

counter ++;

if (counter>179)

counter=179;

}

// Move the servo

servo.write(counter);

Serial.print("Position: ");

Serial.println(counter);

}

// Remember last CLK state

lastStateCLK = currentStateCLK;

}