You can read this and other amazing tutorials on ElectroPeak's official website
OverviewIn this tutorial, you’ll get to know how to use the rotary encoder. First, you’ll see some information about the rotational encoder, and then you’ll learn how to use a rotary encoder with three practical examples.
What You Will Learn:- What the rotary encoder is and how it works.
- Displaying encoder position
- Controlling a LED light using a rotary encoder
- Controlling a DC motor speed and direction using a rotary encoder
The rotary encoder is an electromechanical device that converts the position of the shaft angle to digital data. Rotary encoder has a circular plate with some holes and two channels A and B. By rotating the circular plate, when A and B channels pass the holes, a connection between that channel and a common base is established. These interruptions cause a square wave in the output channel. By counting these pulses, we can find the amount of rotation. On the other hand, channels A and B have 90 degrees of the phase difference, so you can also find the rotation direction depending on which channel pulse is ahead.
An encoder can be installed directly on the motor shaft or made as a module. The rotary encoder module, including 5 pins, is the most common rotating encoder. 2 pins support encoder supply, SW is a push button on the module, and CLK and DT show the A and B channels.
Some of the features of this module are:
- The ability of Rotate to infinity
- 20 pulse resolution
- 5V supply voltage
To use a rotary encoder, we should count the pulses of channels A and B. To do this, we used Arduino UNO and performed three projects for positioning the encoder, controlling the LED light and controlling the speed and direction of the DC motor.
Connect the + to 5V, GND to GND pin, CLK to pin number 6, and DT to pin number 7.
You need to know the position of the shaft to use the encoder. The position of the shaft varies depending on the amount of its rotation. It changes from 0 to infinity for clockwise rotation, and from 0 to minus infinity for the counterclockwise rotation.
Upload the following code on your Arduino and see the position of the shaft encoder in the serial monitor. You can use this code for all your projects with an encoder.
/*
Rotary Encoder - get the position
modified on 23 Feb 2019
by Saeed Hosseini
https://electropeak.com/learn/
*/
#define encoderOutA 6 // CLK
#define encoderOutB 7 // DT
int counter = 0;
int State;
int old_State;
void setup() {
pinMode (encoderOutA, INPUT);
pinMode (encoderOutB, INPUT);
Serial.begin (9600);
//Read First Position of Channel A
old_State = digitalRead(encoderOutA);
}
void loop() {
State = digitalRead(encoderOutA);
if (State != old_State)
{
if (digitalRead(encoderOutB) != State)
{
counter ++;
}
else {
counter --;
}
Serial.print("Position: ");
Serial.println(counter);
}
old_State = State; // the first position was changed
}
To determine the encoder position, we need to connect channels A and B as inputs to Arduino. We read and save the initial value of Channel A at the beginning. Then, we read the instantaneous value of channel A, and if the value of Channel B was ahead of it, we decrease the counter. Otherwise, we increase the counter number.
Controlling a LED Light with Shaft RotationCircuit
/*
Rotary Encoder - LED Brightness Control
modified on 23 Feb 2019
by Saeed Hosseini
https://electropeak.com/learn/
*/
#define encoderOutA 6 // CLK
#define encoderOutB 7 // DT
#define LED 9 // LED , must connect to pwm pin
int brightness = 0;
int State;
int old_State;
void setup() {
pinMode (encoderOutA, INPUT);
pinMode (encoderOutB, INPUT);
pinMode (LED, INPUT);
Serial.begin (9600);
//Read First Position of Channel A
old_State = digitalRead(encoderOutA);
}
void loop() {
State = digitalRead(encoderOutA);
if (State != old_State)
{
if (digitalRead(encoderOutB) != State)
{
brightness ++;
}
else {
brightness --;
}
if (brightness >= 255) brightness = 255;
if (brightness <= 0) brightness = 0;
Serial.print("brightness: ");
Serial.println(brightness);
}
old_State = State; // the first position was changed
analogWrite(LED , brightness);
}
At first you need to get the shaft position, and then you can reduce or increase the LED light with PWM. Since the PWM has some value between 0 to 255, we set the shaft position in this range in the code too.
Controlling DC Motor Speed and Direction with InterruptCircuit/*
Rotary Encoder - Controlling a DC Motor using L293D Shield
modified on 23 Feb 2019
by Saeed Hosseini
https://electropeak.com/learn/
*/
#include <AFMotor.h>
#define CLK 2
#define DT 5
#define SW 3
AF_DCMotor motor(1, MOTOR12_64KHZ);
int motor_dir = 0;
int State;
int old_State, change;
volatile int motor_speed = 0;
volatile boolean buttonState = false;
void setup() {
Serial.begin(9600);
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
pinMode(SW, INPUT_PULLUP);
old_State = digitalRead(CLK);
attachInterrupt (digitalPinToInterrupt(CLK), encoder_detect, CHANGE);
attachInterrupt (digitalPinToInterrupt(SW), button_detect, FALLING);
}
void loop() {
if (!buttonState)
{
if (motor_speed > 0)
{
motor.setSpeed(motor_speed);
motor.run(FORWARD);
Serial.print("Move Forward: ");
Serial.println(motor_speed);
}
else if (motor_speed < 0)
{
motor.setSpeed((motor_speed) * (-1));
motor.run(BACKWARD);
Serial.print("Move Backward: ");
Serial.println(motor_speed);
}
}
if (buttonState == true || motor_speed == 0)
{
motor.run(RELEASE);
Serial.println("Break");
}
}
void encoder_detect () {
buttonState = false;
State = digitalRead(CLK);
if (State != old_State)
{
if (digitalRead(DT) != State)
{
motor_speed ++;
if (motor_speed >= 255) motor_speed = 255;
}
else {
motor_speed --;
if (motor_speed <= -255) motor_speed = -255;
}
}
old_State = State;
}
void button_detect()
{
buttonState = true;
}
In this code, we have used an interrupt to read the shaft and key position. For more information about interrupts, you can check the Arduino Website.
The motor breaks by pushing the encoder key or setting the encoder in position 0.
You can see how to drive DC motor with the L293D shield here.
Like us on FaceBookIf you find this tutorial helpful and interesting please like us on facebook.
Comments
Please log in or sign up to comment.