Control Servo Motor using Rotary Encoder with Arduino and LCD

Control Servo Motor using Rotary Encoder with arduino and lcd Control Servo Motor using Rotary Encoder with arduino and lcd

Introduction

In this interesting Arduino Project learn to control a servo motor with a rotary encoder using Arduino microcontroller and display the angle rotated on the LCD display. You will learn the process of interfacing a servo motor, rotary encoder with an Arduino to achieve accurate control over a servo motor. We will also explain about servo motors and rotary encoders, and their working principles.

The project of controlling a servo motor using a rotary encoder with Arduino can be used in various practical applications like Robotic Arm Control, Camera Pan-Tilt Mechanism, Surveillance camera systems, Manual Solar Trackers, CNC Machine Control, Industrial Automation, and more. With the help of this project, it is easy to rotate the objects at specified angles with good accuracy.

What is a Servo Motor

servo motor pinout diagram

A servo motor is a special type of motor commonly used in robotics and automation projects. It is designed to provide precise control over angular rotation, making it ideal for applications requiring specific movements or positions. Servo motors consist of a DC motor, gears, and a control circuit. The control circuit receives a control signal, usually in the form of a pulse width modulation (PWM) signal, to determine the desired position of the motor shaft.

What is a Rotary Encoder

what is rotary encoder

A rotary encoder is an electromechanical device used to convert angular position or rotation into digital or analog signals. It provides feedback on the rotational movement, enabling accurate measurement and control. Rotary encoders typically consist of a rotating disk, sensors (optical or magnetic), and output circuitry. As the encoder rotates, the sensors detect the changes in position, generating corresponding electrical signals.

For more details refer: What is Rotary Encoder? Types, Principle, working in detail

Working Principle of Servo Motors and Rotary Encoders

Servo motors work on a closed-loop control system. The control signal sent to the servo motor determines the desired position. The internal control circuit compares the current position with the desired position and adjusts the motor’s rotation accordingly. This feedback loop ensures accurate positioning.

Rotary encoders, on the other hand, provide feedback on the rotational movement. The encoder generates electrical signals, such as pulses or digital codes, representing the direction and magnitude of rotation. By monitoring these signals, we can track the position, speed, and direction of the rotary encoder.

Related Project: DIY Measuring Wheel using Arduino and Rotary Encoder

Interfacing Servo motor and rotary encoder with Arduino to display angle on LCD

Required components:

Product NameQuantityamazon logoamazon logo india
Arduino Microcontroller1https://amzn.to/3H4cKxZhttps://amzn.to/3638aTS
Servo motor sg901https://amzn.to/42TlD9yhttps://amzn.to/3hA5jVihttps://amzn.to/41VeJ2jhttps://amzn.to/368WjUE
Rotary encoder module1https://amzn.to/45qSLqFhttps://amzn.to/3MNOOoT
16X2 LCD display with I2C adapter1https://amzn.to/3WnDDXhhttps://amzn.to/3Ou14ME
5V power supply (USB or External).1https://amzn.to/3s1a8g3https://amzn.to/364yInH
Few Connecting Wireshttps://amzn.to/3H2BV4ehttps://amzn.to/3J0WVu2
You can buy the required components from the given best buy links. We choose the components according to value for money.

Circuit Diagram:

Now connect all the required components on by one as shown in the below schematic diagram.

control servo motor with rotary encoder using arduino and display angle on lcd display circuit diagram

 

As you can see from the above circuit diagram Servo motor RED and BROWN wires which are positive and negative are connected to 5V and GND pins of Arduino respectively. The ORANGE wire which is for control is connected to Arduino digital pin 9.

And next Rotary encoder power pins + and GND are connected to 5V and GND pins of Arduino respectively. And next CLK, DT and SW pins of Encoder are connected to digital pins 2,3 and 4 of Arduino respectively.

And finally we are connecting an LCD display module with I2C adapter which has only 4 pins. LCD display power pins VCC and GND are connected to 5V and GND of Arduino respectively and I2C pins SDA and SCL are connected to A4 and A5 respectively. Thats it for connection, next we need to write a program and upload it to Arduino.

Control Servo with rotary encoder using Arduino source code

After connecting all the required components we need to upload the program. Connect Arduino to PC where Arduino IDE is installed, and copy the below code and paste it in the Arduino IDE workspace, install required libraries listed below, choose correct port and upload the code.

Required Libraries:

  • Encoder library – Encoder.h by PaulStoffregen – link
  • Servo library – Installed by default
  • Liquid Crystal I2c library – link
/* Control Servo motor with Rotary encoder and display angle on LCD display
// for Best performace connect this both pins to interupt capable pins of Arduino
 */
#include <Encoder.h>
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

//define a pin for rotary encode switch
const int SW_PIN = 4;
const int PIN_A =2;
const int PIN_B =3;
// for Best performace connect this both pins to interupt capable pins of Arduino

Encoder myEnc(PIN_A, PIN_B);
//avoid using pins with LEDs attached

//Define Servo motors
const int homePosition = 90; //initial position
const int stepValue = 3;//how fast the servo should rotate when turning the knob
const int servoPin = 9;//~must be a pin that that is labeled with ~

Servo myservo;  // create servo object to control a servo
int servoAngle =homePosition;

// Set the LCD address to 0x27 or 0x3F for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  Serial.begin(9600);
  pinMode(SW_PIN, INPUT);
  Serial.println("Control Servo with Rotary encoder:CircuitSchools");
   myservo.attach(servoPin);  // attaches the servo on pin
   myservo.write(servoAngle);//move servo to initial position

  lcd.init();
  // Turn on the blacklight and print a message.
  lcd.backlight();     
  lcd.print("Encoder Servo");
  lcd.setCursor (0,1); // go to start of 2nd line
  lcd.print("Servo Test");   
  delay(2000);   
   lcd.clear();// clear previous values from screen   
  lcd.print("Encoder Servo");
  lcd.setCursor (0,1); // go to start of 2nd line  
  lcd.print("Angle: ");   
}

long oldPosition  = -999;

void loop() {
  long newPosition = myEnc.read();
  if (newPosition != oldPosition) {

    if(newPosition >  oldPosition)
    {
    int newStep = abs(newPosition - oldPosition);
      Serial.print("Angle ");
      Serial.println(servoAngle);      
      servoAngle -= stepValue;
      if(servoAngle <0)
          servoAngle =0;      
      myservo.write(servoAngle); //move servo to new angel
      lcdAngle(servoAngle);//print on LCD
    }

    if(newPosition <  oldPosition )
    {
    int newStep = abs(newPosition - oldPosition);
      Serial.print("Angle ");
      Serial.println(servoAngle);        
      servoAngle += stepValue;
      if(servoAngle >180)
          servoAngle =180;
      myservo.write(servoAngle); //move servo to new angel
      lcdAngle(servoAngle);//print on LCD
    }
   oldPosition = newPosition;//remember the new position
  }

  if( digitalRead(SW_PIN) == LOW)
  {
    Serial.print("Home: ");
    Serial.println(homePosition);
    servoAngle =homePosition;
      myservo.write(servoAngle); //move servo to new angel
      lcdAngle(servoAngle);//print on LCD
  }

  //delay(200);
}

void lcdAngle(int angle)
{
  
  int startChar =7;
  for(int i=startChar; i<16; i++)
  {
   lcd.setCursor (i,1);    
    lcd.print(" ");   
  }
 
   lcd.setCursor (startChar,1); // line 1 
   lcd.print(angle); 
   lcd.print((char)223);
}

Code explaination

  1. The code includes several libraries: Encoder for handling the rotary encoder, Servo for controlling the servo motor, Wire for I2C communication, and LiquidCrystal_I2C for interfacing with the LCD display.
  2. Pin assignments and constants are defined:
    • SW_PIN represents the pin connected to the rotary encoder switch.
    • PIN_A and PIN_B are the pins connected to the rotary encoder’s A and B channels.
    • homePosition is the initial position of the servo motor.
    • stepValue determines how fast the servo rotates when turning the knob.
    • servoPin is the pin to which the servo motor is connected.
  3. An instance of the Encoder class is created, passing the A and B pins as arguments.
  4. The servo motor is initialized by creating an instance of the Servo class and attaching it to the servoPin. The servoAngle variable is set to the homePosition, and the servo is moved to that initial position.
  5. The LCD display is initialized, and a welcome message is printed on it. After a short delay, the screen is cleared, and the “Encoder Servo” and “Angle: ” texts are displayed.
  6. The loop function is where the main logic resides. It reads the current position of the rotary encoder using the myEnc.read() function.
  7. If the position has changed (newPosition != oldPosition), the code checks if the new position is greater or smaller than the old position to determine the direction of rotation.
  8. If the new position is greater, the servoAngle is decreased by stepValue. The code ensures that the angle does not go below 0 and then moves the servo to the new angle. The lcdAngle function is called to update the angle on the LCD display.
  9. If the new position is smaller, the servoAngle is increased by stepValue. The code ensures that the angle does not exceed 180 and then moves the servo to the new angle. The lcdAngle function is called to update the angle on the LCD display.
  10. The oldPosition is updated to store the current position for comparison in the next iteration.
  11. If the rotary encoder switch is pressed (SW_PIN is LOW), the servo is moved back to the homePosition, and the lcdAngle function is called to update the LCD display.
  12. The loop function then repeats, continuously monitoring the rotary encoder and reacting to changes.
  13. The lcdAngle function updates the angle value on the LCD display by clearing the previous characters and printing the new angle.

 

Add a comment

Leave a Reply

Your email address will not be published. Required fields are marked *