In this arduino tutorial it is explained what rotary encoder is and how to use it with Arduino. In the rotary Arduino example provided here users can control the brightness of an LED using a rotary encoder. Rotating the encoder clockwise increases the brightness, and rotating it counterclockwise decreases the brightness. Pressing the encoder button turns off the LED. The number of turns of the encoder and the current brightness value are displayed in the serial monitor.
A rotary encoder is an electromechanical device used to convert the angular position or rotation of a shaft into digital signals. It provides a way to measure and track the rotation of a knob or shaft. Rotary encoders are commonly used in various applications, including robotics, industrial control systems, gaming devices, and audio equipment.
There are two main types of rotary encoders: incremental and absolute.
1. Incremental Rotary Encoder:
An incremental rotary encoder generates pulses as the shaft rotates. It consists of two output channels, typically labeled as A and B. Each channel has a series of evenly spaced pulses. The channels are typically out of phase by 90 degrees (also known as quadrature encoding). As the shaft rotates, the encoder produces a series of pulses on the A and B channels. The direction of rotation can be determined by examining the order in which the pulses arrive on the A and B channels. By counting the number of pulses, the encoder's position or the number of rotations can be determined.
2. Absolute Rotary Encoder:
An absolute rotary encoder provides a unique digital code or value for each position of the shaft. It can directly indicate the absolute angular position of the shaft without the need for counting pulses. Absolute encoders use various techniques to achieve this, such as binary code, Gray code, or a combination of multiple tracks or bits. Each unique position corresponds to a specific code, which can be read to determine the shaft's angular position.
Working Principle:
In both types of rotary encoders, the basic principle involves the rotation of a disk or a wheel with evenly spaced slots or marks, and a sensor or set of sensors that detect these marks as the shaft rotates. The sensors may use different technologies, such as optical, magnetic, or capacitive, depending on the encoder type.
For incremental encoders, the marks on the disk produce pulses as they pass by the sensor. The A and B channels generate square wave signals that are out of phase with each other. By analyzing the sequence and timing of the pulses on the A and B channels, the direction of rotation and the number of rotations can be determined.
Absolute encoders, on the other hand, provide a unique code for each position of the shaft. The code can be read by the sensors or read heads, which are positioned to detect the specific marks or patterns on the encoder disk or wheel. The code is then translated into a digital value that represents the absolute angular position of the shaft.
Overall, rotary encoders provide a way to measure and monitor the rotation of a shaft or knob, enabling precise control and feedback in various applications.
Arduino Rotary Encoder Circuit Diagram
The following shows the circuit diagram of connecting rotary encoder with Arduino and a LED.
In the above, rotary encoder module, KY-040, is used.
The rotary encoder clock (CLK), data (DT), and switch (SW) pins are connected to Arduino pins A0, A1, and A2. A LED is connected to pin 6 with a resistor 220Ohm.Arduino Rotary encoder Program
This code is an implementation of a rotary encoder using an Arduino board. A rotary encoder is an input device that converts the rotation of a shaft into digital signals. The code reads the rotation and button press of the rotary encoder and adjusts the brightness of an LED accordingly.
int CLKpin= A0; // pin A or clock pin
int DTpin= A1; // pin B or data pin
int SWpin= A2 ; // switch pin
int LEDpin = 6; // LED on PWM pin
int bright = 120; // initial LED value
int fade = 10; // amount to change LED
int rotate = 0; // number of rotary turns
int oldA = HIGH; // status of pin A
int change, result, newA, newB;
void setup(){
Serial.begin(9600); // define Serial output baud rate
pinMode(LEDpin, OUTPUT); // LED pin as output
pinMode(SWpin, INPUT_PULLUP); // switch pin uses internal pull-up resistor
}
void loop(){
if(digitalRead(SWpin) == LOW)
bright = 0; // switch, active LOW,
// turns off LED
change = encoder(); // function for direction of rotation
rotate = rotate + abs(change); // number of turns of rotary encoder
bright = bright + change*fade; // change LED brightness
bright = constrain(bright, 0, 255); // constrain LED brightness
if(change != 0){ // display number
Serial.print(rotate);
Serial.print("\t"); // of rotary turns
Serial.println(bright); // and LED brightness
}
analogWrite(LEDpin, bright); // update LED brightness
}
// function to determine direction
int encoder(){
result = 0;
newA = digitalRead(CLKpin); // state of (CLK) pin A
newB = digitalRead(DTpin); // state of (DT) pin B
// falling edge on (CLK) pin A
if (oldA == HIGH && newA == LOW) result = 2*newB - 1;
oldA = newA; // update state of (CLK) pin A
return result;
}
Let's go through the code step by step:
1. Pin Definitions:
int CLKpin = A0; // pin A or clock pin
int DTpin = A1; // pin B or data pin
int SWpin = A2; // switch pin
int LEDpin = 6; // LED on PWM pin
These variables define the pin connections for the rotary encoder and the LED.
2. Variable Initialization:
int bright = 120; // initial LED value
int fade = 10; // amount to change LED
int rotate = 0; // number of rotary turns
int oldA = HIGH; // status of pin A
int change, result, newA, newB;
These variables store various states and values used in the code. bright
represents the current LED brightness value, fade
determines the amount by which the brightness changes, rotate
keeps track of the number of turns of the rotary encoder, oldA
stores the previous state of pin A, and change
, result
, newA
, and newB
are used for temporary calculations.
3. Setup Function:
void setup() {
Serial.begin(9600); // define Serial output baud rate
pinMode(LEDpin, OUTPUT); // LED pin as output
pinMode(SWpin, INPUT_PULLUP); // switch pin uses internal pull-up resistor
}
In the setup
function, the serial communication is
initialized with a baud rate of 9600. The LEDpin is set as an output,
and the SWpin (switch pin) is configured as an input with an internal
pull-up resistor.
4. Main Loop:
void loop() {
if (digitalRead(SWpin) == LOW) bright = 0; // switch, active LOW, turns off LED
change = encoder(); // function for direction of rotation
rotate = rotate + abs(change); // number of turns of rotary encoder
bright = bright + change * fade; // change LED brightness
bright = constrain(bright, 0, 255); // constrain LED brightness
if (change != 0) {
Serial.print(rotate); Serial.print("\t"); // display number of rotary turns
Serial.println(bright); // and LED brightness
}
analogWrite(LEDpin, bright); // update LED brightness
}
The loop
function is the main part of the code that runs repeatedly. It performs the following steps:
- It checks if the switch pin is LOW, indicating that the button on the rotary encoder is pressed. In this case, it sets the brightness value (
bright
) to 0, turning off the LED. - It calls the
encoder
function to determine the direction of rotation of the rotary encoder. The result is stored in thechange
variable. - The absolute value of
change
is added to therotate
variable to keep track of the number of turns of the rotary encoder. - The
bright
variable is updated based on thechange
andfade
values. Ifchange
is positive, the brightness increases; ifchange
is negative, the brightness decreases. - The
bright
value is constrained to be within the range of 0 to 255 using theconstrain
function. - If there was a change in the rotary encoder (change != 0), the current number of turns (
rotate
) and LED brightness (bright
) are printed to the serial monitor. - Finally, the LED brightness is updated by calling
analogWrite
on the LEDpin with the updatedbright
value.
5. Encoder Function:
int encoder() {
result = 0;
newA = digitalRead(CLKpin); // state of (CLK) pin A
newB = digitalRead(DTpin); // state of (DT) pin B
// falling edge on (CLK) pin A
if (oldA == HIGH && newA == LOW)
result = 2 * newB - 1;
oldA = newA; // update state of (CLK) pin A
return result;
}
The encoder
function is responsible for determining the direction of rotation of the rotary encoder. It reads the current states of the CLKpin (pin A) and DTpin (pin B). By comparing the old and new states of pin A, it determines if a falling edge (change from HIGH to LOW) has occurred.
- If a falling edge is detected, the
result
value is updated. This value is calculated based on the state of pin B (newB
). IfnewB
is HIGH, the result will be 1; ifnewB
is LOW, the result will be -1. - The
oldA
variable is updated with the new state of pin A. - The
result
value is returned to theloop
function.