Extra 5% OFF Use Code: OL05
Free Shipping over ₹999

Interface Servo SG90 with Arduino

Introduction

The SG90 is a small, lightweight servo motor capable of rotating approximately 180 degrees. It can be controlled by sending a Pulse Width Modulation (PWM) signal to set the angle.

Required Components

  • Arduino UNO, Nano
  • SG90 servo motor
  • Jumper wires
  • Breadboard (optional)
  • External power source (optional, if using multiple servos)

Pinout

Circuit Diagram / Wiring

  • Brown wire -> GND (Arduino)
  • Red wire -> 5V (Arduino) or an external 5V power supply if Arduino power is insufficient
  • Orange/Yellow wire -> Pin 9 (Arduino) (PWM-capable pin)

Arduino Code / Programming

To control the servo, you can use the built-in Servo library, which simplifies sending the control signals.

#include <Servo.h>

Servo myServo; // Create a Servo object

void setup() {
  myServo.attach(9); // Attach the servo to pin 9
}

void loop() {
  // Move the servo to 0 degrees
  myServo.write(0);
  delay(1000); // Wait for 1 second

  // Move the servo to 90 degrees
  myServo.write(90);
  delay(1000); // Wait for 1 second

  // Move the servo to 180 degrees
  myServo.write(180);
  delay(1000); // Wait for 1 second
}

Explanation of the Code

  • Include the Servo Library: The Servo library allows easy control of servo motors.
  • Create a Servo Object: This object represents the servo motor you’re controlling.
  • Attach the Servo: The attach() function specifies the pin used to control the servo.
  • Move the Servo: The write() function sets the servo to a specified angle between 0 and 180 degrees.

Testing and Troubleshooting

  • Power Issues: If the servo behaves erratically, consider using an external power source.
  • Angle Range: The SG90 typically moves between 0 and 180 degrees. If it doesn’t move as expected, check the power connections.
  • Servo Jitter: Make sure your power supply is stable; otherwise, the servo may not hold the position properly.

Common Issues and Solutions

  • Insufficient Power Supply: The SG90 servo motor may not work correctly if the power supply is unstable or insufficient. The servo requires 5V and around 500mA current. If the Arduino is not providing enough power, use an external 5V power source.
    • Solution: Use an external 5V power supply and ensure all grounds are connected. For example, connect the servo’s ground wire to both the Arduino GND and the external power supply GND.
  • Power Spike Issues: Servos can cause voltage spikes that may reset the Arduino or cause the servo to behave erratically.
    • Solution: Add a capacitor (100µF or larger) across the power supply to stabilize the voltage.
  • Servo Not Moving at All: If the servo does not move or jitters, double-check the connections and the code.
    • Solution: Verify that the signal pin is connected to a PWM-capable pin on the Arduino, and ensure the servo is not mechanically blocked.

Recommended Setup Using PCA9685

For using the SG90 servo motor with Arduino, the PCA9685 module is highly recommended, especially when you need to control multiple servos or require more precise control. If you find that your servo is not operating correctly when connected directly to the Arduino or if it is running but not accurately, using the PCA9685 can help resolve these issues. Here are some reasons why the PCA9685 is a good choice:

Multiple Servo Control:

  • The PCA9685 can control up to 16 servos using just two Arduino pins (SDA and SCL). This frees up other pins for additional sensors or modules.

Stable Power Supply:

  • It helps distribute the power supply to the servos more evenly, reducing issues caused by power spikes or voltage drops.

Simplified Wiring:

  • With the PCA9685, you only need to connect the power, ground, and signal lines for each servo to the module, making the setup less cluttered.

Precise Control:

  • The module provides 12-bit PWM resolution, allowing fine control over the servo position.

Improved Accuracy:

  • If your servo is running inaccurately when connected directly to the Arduino, the PCA9685’s precise PWM control can significantly enhance its performance.

Additional Recommendations

Using External Power:

  • When using more than one servo, it’s advisable to use an external 5V power supply to power the servos. Ensure that the power supply can provide sufficient current (at least 1A for every 2-3 servos).

Common Ground:

  • Make sure all devices share a common ground to prevent erratic behavior.

Arduino Projects:

Arduino Project 1 – Creating Ultrasonic Radar Scanner with Servo Control

Smart Radar System Using Sonar and Arduino is a real-time object detection project that combines a sonar sensor, servo motor, and Arduino. It scans the surroundings, measures distances, and visualizes data on a radar-style interface using Processing. Ideal for robotics and automation, it offers precise detection and environment mapping. Perfect for learning sensor integration and data visualization.

Required Components

  • Arduino UNO, Nano
  • SG90 servo motor
  • Ultrasonic Sensor
  • Jumper wires
  • Breadboard (optional)
  • Computer: With Processing IDE software installed.

Circuit Diagram / Wiring

  • Ultrasonic Sensor with Arduino
    • ULTRASONIC SENSOR VCC → 5V (Arduino)
    • ULTRASONIC SENSOR GND → GND (Arduino)
    • ULTRASONIC SENSOR TRIG → Pin D10 (Arduino)
    • ULTRASONIC SENSOR ECHO → Pin D11 (Arduino)
  • Servo motor with Arduino
    • SERVO MOTOR VCC → 5V (Arduino)
    • SERVO MOTOR GND → GND (Arduino)
    • SERVO MOTOR PWM → Pin D9 (Arduino)

Arduino Code

// Includes the Servo library
#include <Servo.h>. 
// Defines Tirg and Echo pins of the Ultrasonic Sensor
const int trigPin = 10;
const int echoPin = 11;
// Variables for the duration and the distance
long duration;
int distance;
Servo myServo; // Creates a servo object for controlling the servo motor
void setup() {
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
  Serial.begin(9600);
  myServo.attach(9); // Defines on which pin is the servo motor attached
}
void loop() {
  // rotates the servo motor from 15 to 165 degrees
  for(int i=15;i<=165;i++){  
  myServo.write(i);
  delay(30);
  distance = calculateDistance();// Calls a function for calculating the distance measured by the Ultrasonic sensor for each degree
  
  Serial.print(i); // Sends the current degree into the Serial Port
  Serial.print(","); // Sends addition character right next to the previous value needed later in the Processing IDE for indexing
  Serial.print(distance); // Sends the distance value into the Serial Port
  Serial.print("."); // Sends addition character right next to the previous value needed later in the Processing IDE for indexing
  }
  // Repeats the previous lines from 165 to 15 degrees
  for(int i=165;i>15;i--){  
  myServo.write(i);
  delay(30);
  distance = calculateDistance();
  Serial.print(i);
  Serial.print(",");
  Serial.print(distance);
  Serial.print(".");
  }
}
// Function for calculating the distance measured by the Ultrasonic sensor
int calculateDistance(){ 
  
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH); 
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH); // Reads the echoPin, returns the sound wave travel time in microseconds
  distance= duration*0.034/2;
  return distance;
}

Explanation

  • Servo Motor Control: The servo motor rotates between 15° and 165° to scan the environment.
  • Distance Measurement: The ultrasonic sensor sends a pulse, and the time taken for the echo to return is used to calculate distance.
  • Data Output: The degree and corresponding distance values are printed to the Serial Monitor for each position of the servo motor.
  • Looping Process: The servo sweeps back and forth, continuously measuring distance at each angle and sending the data for processing.

Setup Processing Code

Install Processing Software:
Download and install Processing IDE.

Write or Paste Code:
Open Processing IDE and paste the radar visualization code provided.

  • Adjust the COM port in the Processing code to match your Arduino’s port.
  • Set the baud rate in Processing to the same value used in the Arduino code (e.g., 9600).

Run the Processing Code:
Click the Run button in Processing to start the radar visualization.

import processing.serial.*; // imports library for serial communication
import java.awt.event.KeyEvent; // imports library for reading the data from the serial port
import java.io.IOException;
Serial myPort; // defines Object Serial
// defubes variables
String angle="";
String distance="";
String data="";
String noObject;
float pixsDistance;
int iAngle, iDistance;
int index1=0;
int index2=0;
PFont orcFont;
void setup() {
  
 size (1200, 700); // ***CHANGE THIS TO YOUR SCREEN RESOLUTION***
 smooth();
 myPort = new Serial(this,"COM14", 9600); // starts the serial communication
 myPort.bufferUntil('.'); // reads the data from the serial port up to the character '.'. So actually it reads this: angle,distance.
}
void draw() {
  
  fill(98,245,31);
  // simulating motion blur and slow fade of the moving line
  noStroke();
  fill(0,4); 
  rect(0, 0, width, height-height*0.065); 
  
  fill(98,245,31); // green color
  // calls the functions for drawing the radar
  drawRadar(); 
  drawLine();
  drawObject();
  drawText();
}
void serialEvent (Serial myPort) { // starts reading data from the Serial Port
  // reads the data from the Serial Port up to the character '.' and puts it into the String variable "data".
  data = myPort.readStringUntil('.');
  data = data.substring(0,data.length()-1);
  
  index1 = data.indexOf(","); // find the character ',' and puts it into the variable "index1"
  angle= data.substring(0, index1); // read the data from position "0" to position of the variable index1 or thats the value of the angle the Arduino Board sent into the Serial Port
  distance= data.substring(index1+1, data.length()); // read the data from position "index1" to the end of the data pr thats the value of the distance
  
  // converts the String variables into Integer
  iAngle = int(angle);
  iDistance = int(distance);
}
void drawRadar() {
  pushMatrix();
  translate(width/2,height-height*0.074); // moves the starting coordinats to new location
  noFill();
  strokeWeight(2);
  stroke(98,245,31);
  // draws the arc lines
  arc(0,0,(width-width*0.0625),(width-width*0.0625),PI,TWO_PI);
  arc(0,0,(width-width*0.27),(width-width*0.27),PI,TWO_PI);
  arc(0,0,(width-width*0.479),(width-width*0.479),PI,TWO_PI);
  arc(0,0,(width-width*0.687),(width-width*0.687),PI,TWO_PI);
  // draws the angle lines
  line(-width/2,0,width/2,0);
  line(0,0,(-width/2)*cos(radians(30)),(-width/2)*sin(radians(30)));
  line(0,0,(-width/2)*cos(radians(60)),(-width/2)*sin(radians(60)));
  line(0,0,(-width/2)*cos(radians(90)),(-width/2)*sin(radians(90)));
  line(0,0,(-width/2)*cos(radians(120)),(-width/2)*sin(radians(120)));
  line(0,0,(-width/2)*cos(radians(150)),(-width/2)*sin(radians(150)));
  line((-width/2)*cos(radians(30)),0,width/2,0);
  popMatrix();
}
void drawObject() {
  pushMatrix();
  translate(width/2,height-height*0.074); // moves the starting coordinats to new location
  strokeWeight(9);
  stroke(255,10,10); // red color
  pixsDistance = iDistance*((height-height*0.1666)*0.025); // covers the distance from the sensor from cm to pixels
  // limiting the range to 40 cms
  if(iDistance<40){
    // draws the object according to the angle and the distance
  line(pixsDistance*cos(radians(iAngle)),-pixsDistance*sin(radians(iAngle)),(width-width*0.505)*cos(radians(iAngle)),-(width-width*0.505)*sin(radians(iAngle)));
  }
  popMatrix();
}
void drawLine() {
  pushMatrix();
  strokeWeight(9);
  stroke(30,250,60);
  translate(width/2,height-height*0.074); // moves the starting coordinats to new location
  line(0,0,(height-height*0.12)*cos(radians(iAngle)),-(height-height*0.12)*sin(radians(iAngle))); // draws the line according to the angle
  popMatrix();
}
void drawText() { // draws the texts on the screen
  
  pushMatrix();
  if(iDistance>40) {
  noObject = "Out of Range";
  }
  else {
  noObject = "In Range";
  }
  fill(0,0,0);
  noStroke();
  rect(0, height-height*0.0648, width, height);
  fill(98,245,31);
  textSize(25);
  
  text("10cm",width-width*0.3854,height-height*0.0833);
  text("20cm",width-width*0.281,height-height*0.0833);
  text("30cm",width-width*0.177,height-height*0.0833);
  text("40cm",width-width*0.0729,height-height*0.0833);
  textSize(40);
  text("OceanLabz", width-width*0.875, height-height*0.0277);
  text("Angle: " + iAngle +" °", width-width*0.48, height-height*0.0277);
  text("Distance: ", width-width*0.26, height-height*0.0277);
  if(iDistance<40) {
  text("        " + iDistance +" cm", width-width*0.225, height-height*0.0277);
  }
  textSize(25);
  fill(98,245,60);
  translate((width-width*0.4994)+width/2*cos(radians(30)),(height-height*0.0907)-width/2*sin(radians(30)));
  rotate(-radians(-60));
  text("30°",0,0);
  resetMatrix();
  translate((width-width*0.503)+width/2*cos(radians(60)),(height-height*0.0888)-width/2*sin(radians(60)));
  rotate(-radians(-30));
  text("60°",0,0);
  resetMatrix();
  translate((width-width*0.507)+width/2*cos(radians(90)),(height-height*0.0833)-width/2*sin(radians(90)));
  rotate(radians(0));
  text("90°",0,0);
  resetMatrix();
  translate(width-width*0.513+width/2*cos(radians(120)),(height-height*0.07129)-width/2*sin(radians(120)));
  rotate(radians(-30));
  text("120°",0,0);
  resetMatrix();
  translate((width-width*0.5104)+width/2*cos(radians(150)),(height-height*0.0574)-width/2*sin(radians(150)));
  rotate(radians(-60));
  text("150°",0,0);
  popMatrix(); 
}

    Leave a Reply

    Your email address will not be published.

    Need Help?