Robotics & Arduino
Lesson 3 · Hands on

Project 08

Calibrate the servo

The code.

// Notes:
//  - Servo std pwm range - 544 to 2400.

//Declare
#include <Servo.h>  // Servo lib
Servo myServo;      // Servo obj

// Calibration limits - Adjust to real world limits

// Servo in Microseconds (us)
const int SERVO_MIN_US = 400;	//544;	// Real-world theoretical min - "0" degree angle position
const int SERVO_MAX_US = 2700;	//2600;	// Real-world theoretical max - "180" angle position

// Servo in agnle
const int SERVO_MIN_ANG = 0;   
const int SERVO_MAX_ANG = 180; 

const int SERVO_PIN   = 9;      // PWM servo signal pin
const int SWEEP_DELAY = 20;     // Sweep inter-step delay in ms (Lower because microseconds have more steps)
const int STEP_SIZE   = 10;     // How many microseconds per loop step
const int END_PAUSE   = 1500;   // Pasue at edge. Delay in ms.


//Setup
void setup() {
  // Init serial comm 
  Serial.begin(9600);         // Run at 9600 bits per second

  // Set pin to obj
  myServo.attach(SERVO_PIN);
}

//Run
void loop() {

  //sweepUpAngle();        // Sweep 0 to 180
  sweepUpPWM();
  delay(END_PAUSE); // Pause at limit

  //sweepDownAngle();      // Sweep 180 to 0
  sweepDownPWM();
  delay(END_PAUSE); // Pause at limit

}

 
// Logic


// ======= PWM SWEEP ======
void sweepUpPWM(){
  for (int us = SERVO_MIN_US; us <= SERVO_MAX_US; us += STEP_SIZE) {
    myServo.writeMicroseconds(us); // Move servo using raw timing
    prtServoPulse(us);             // Prt current pulse
    delay(SWEEP_DELAY);            
  }
}
      
void sweepDownPWM(){
  for (int us = SERVO_MAX_US; us >= SERVO_MIN_US; us -= STEP_SIZE) {
    myServo.writeMicroseconds(us); // Move servo using raw timing
    prtServoPulse(us);             // Prt current pulse
    delay(SWEEP_DELAY);            
  }
}
    
void prtServoPulse(int usVal){
  Serial.print("Current Pulse (us): ");
  Serial.println(usVal);
}


// ======= ANGLE SWEEP ======
void sweepUpAngle(){
  for (int angle = SERVO_MIN_ANG; angle <= SERVO_MAX_ANG; angle++) {
    myServo.write(angle);   // Move servo
    prtServoAngle(angle);   // Prt angle
    delay(SWEEP_DELAY);     // Sweep speed (lower = faster)
  }
}
      
void sweepDownAngle(){
  for (int angle = SERVO_MAX_ANG; angle >= SERVO_MIN_ANG; angle--) {
    myServo.write(angle);     // Move servo
    prtServoAngle(angle);     // Prt angle
    delay(SWEEP_DELAY);       // Sweep speed (lower = faster)
  }
}
    
void prtServoAngle(int angVal){
  Serial.print("Current Angle: ");
  Serial.println(angVal);
}

Servo calibration wiring: orange signal wire to D9, red power wire to 5V, and brown ground wire to GND.