Interfacing Servo Motor with PIC Microcontroller

Servo Motor

Interfacing Servo Motor with PIC Microcontroller

Servo Motor

Servo Motor uses error sensing negative feedback to control the precise angular position. Servos are used for precise positioning in robotic arms, legs, RC Aeroplanes, Helicopters etc. Please read the article Servo Motor for more information about its working and construction. Hobby Servo Motors have three wires, two of them (RED and BLACK) are used to given power and the third one is used to give control signals. Servo can be easily be controlled using microcontrollers using Pulse Width Modulated (PWM) signals on  the control wire. Here we are using a servo whose angular rotation is limited to 0 – 180°. We can control the exact angular position by using  a pulse, whose width varying from 1 millisecond to 2 millisecond on the control wire. The actual behavior of a particular motor depends upon its manufacture, please refer the datasheet of the particular motor for that.

Here I am using VIGOR VS-10A servo motor.

Servo Angular Rotation Pulse Width Modulation

Servo Angular Rotation Pulse Width Modulation

Circuit Diagram

Interfacing Servo Motor with PIC Microcontroller

Interfacing Servo Motor with PIC Microcontroller

Note: VDD and VSS of the pic microcontroller is not shown in the circuit diagram. VDD should be connected to +5V and VSS to GND.


MikroC Programming

void servoRotate0() //0 Degree
{
  unsigned int i;
  for(i=0;i<50;i++)
  {
    PORTB.F0 = 1;
    Delay_us(800);
    PORTB.F0 = 0;
    Delay_us(19200);
  }
}

void servoRotate90() //90 Degree
{
  unsigned int i;
  for(i=0;i<50;i++)
  {
    PORTB.F0 = 1;
    Delay_us(1500);
    PORTB.F0 = 0;
    Delay_us(18500);
  }
}

void servoRotate180() //180 Degree
{
  unsigned int i;
  for(i=0;i<50;i++)
  {
    PORTB.F0 = 1;
    Delay_us(2200);
    PORTB.F0 = 0;
    Delay_us(17800);
  }
}

void main()
{
  TRISB = 0; // PORTB as Ouput Port
  do
  {
    servoRotate0(); //0 Degree
    Delay_ms(2000);
    servoRotate90(); //90 Degree
    Delay_ms(2000);
    servoRotate180(); //180 Degree
  }while(1);
}

Control wire of the Servo  is connected to RB0 of the PIC Microcontroller. Delay_ms() is used to make delay in milliseconds during the program execution while Delay_us() is used to make delay in microsecond during the program execution.

Download

You can download MikroC Code, Proteus files etc here…..
Interfacing Servo Motor with PIC Microcontroller

Want to See the Output ?



Share this post

  • da

    maybe you have some microC code which can do the same servo control via uart? (pic to pic communication)

  • EE103

    What would you do to make the servo go in reverse?

  • Note that sevo will not rotate continuously… and its position is determined by the pulse width..

  • Note that sevo will not rotate continuously… and its position is determined by the pulse width..

  • Janelle Serrano Polinga

    Hi!!! can you please give me a sample program for five degree freedom robotic arm using servo motor? we are using mikroc in 16f84a as our pic and we are having a hard time solving it. thanks! 😀

  • Simple vary the pulse width depending on the type of servo you are using.. Pulse width of servos may vary for different manufactures..

  • edwin

    In your program you have given like this,
    PORTB.F0 = 1;
    Delay_us(1000);//1ms Delay
    PORTB.F0 = 0;
    Delay_ms(1000);
    but as per the diagram of the input pulses it should be like this right?
    PORTB.F0 = 1;
    Delay_us(1000);//1ms Delay
    PORTB.F0 = 0;

    Delay_ms(20);

  • 20ms is the minimum required time period…

  • adpeian

    why is that the signal of the servo is connected to the interrupt port of the microcontroller not the ccp port?

  • As indicated above, you need a frequency of about 50Hz, to control the servo motor…. thus you need to use a very low clock frequency to produce that frequency using ccp module…

  • edwin

    so instead of 20 ms,1000 ms will work too???

  • edwin

    can i have your mail id??? namalum malayaliya:)

  • Felipe Rezende Dejano

    So…what is the values that i need to use to bring back to the older position, for example, im using a servo to open and and close a claw, so i need to run the motor for a side and after run againt to another size….how can i do this? whats the values that i need to put? Thanks!

  • Servo’s position is determined by the pulse width..
    if 1ms its position will be at 0 degree..
    if 1.5 its position will be at 90 degree…

  • roboblaze

    What if i want to servo motor to turn 270 degrees? i mean first 0 degree…then 90 deg…then 180…then 270 degree?? coz my bot requires complete circular rotation…need help!

  • The angle of the servo is directly propotional to the pulse width… So provide a pulse width corresponding to 270 degree

  • neville

    Hi, I want to use a mikroE 4×4 matrix keypad to input a specific angle that the servo should go to. Do you know how I can code the keypad and servo to do this in MikroC? Or a good tutorial that could help? Thanks

  • sarawrislammooon

    hi i use those codes for servo sg 91r servo but my motor does not move it goes some 30-45 degree and stops what can i do please help ………

  • magnai

    Hello LIGO Gearge

    I can control it in simulation Proteus. It is Ok.

    But i can’t control it in real time.

    Tell me please where is wrong?

    Code C is ok.

    I have used quartz crystal 20Mhz.

    I use servomotor (DF25MG made in china).

  • Bassant M. Mohamed

    how to make a code for a servo using ADC in pic16f877a?

  • zealeth .

    Can I use Pic 16F887 instead of using 877A?

  • Yes,
    Just regenerate the hex file by building the project after changing pic in mikroc project settings.

  • Arjunk47

    Dear Sir, i wanna build a 4-20 mA analog display with servo motor. I had succeeded moving the motor in both way with PIC 16F887, But it is not moving precisely when i give same pulse to it, may be the FUTABA S3003 motor is not precise or i am making some mistakes,also wanna control the speed,plz do the needful

  • You cannot control the speed of servo motor….Try using another servo..
    But I think your Idea is a bad one… Microcontroller is a digital device.. So you are going to make an analog display using digital components ?

  • Arjunk47

    Dear Sir,
    You r right but in this project i don’t wanna display any current value,instead,it’s a rotary pneumatic actuator,so i wanna show the pneumatic moments with servo motor,plz guide me,thanks

  • You can control the position using servo motor… Speed of servo may vary for different types.

  • H,K

    @Ligo
    Hi i been trying to make this code turn 0 then 90 then 0 then -90
    but all i am getting is 0 then 45 then 90 then 0
    here is my code
    Thank you
    void servoRotate0() //0 Degree
    {
    unsigned int i;
    for(i=0;i<50;i++)
    {
    PORTC.F0 = 1;
    Delay_us(1500);
    PORTC.F0 = 0;
    Delay_us(18500);
    }
    }

    void servoRotate90() //90 Degree
    {
    unsigned int i;
    for(i=0;i<50;i++)
    {
    PORTC.F0 = 1;
    Delay_us(2000);
    PORTC.F0 = 0;
    Delay_us(18000);
    }
    }

    void servoRotate_90() //-90 Degree
    {
    unsigned int i;
    for(i=0;i<50;i++)
    {
    PORTC.F0 = 1;
    Delay_us(1000);
    PORTC.F0 = 0;
    Delay_us(19000);
    }
    }

    void main()
    {
    TRISC = 0; // PORTB as Ouput Port
    do
    {
    servoRotate90(); //90 Degree
    servoRotate0(); //0 Degree
    servoRotate_90(); //-90 Degree

    }while(1);
    }

  • Pulse width required for servos depends on it manufacture.. Please try after reading your servo datasheet.

  • enrmarl

    what if i want to have a push button switch ..

    portb.f0=1 // my input

    when my button is active the motor will be on 90 and if not active the motor will be back on 0 degree

  • velu

    i’m trying this code in mplab v8.10 ide it throws following error —- Error [500] ; . undefined symbols:

    ___delay_ms (se.obj)___delay_us (se.obj), i’ve tried following commands delay_ms(1000);,delay(1000);_delay_ms(1000); someone help me to solve this problem ,i’m new to pic

  • So what is the problem for it ? It is very simple, do like this :

    if(switch pressed)
    {
    Rotate to 90 degree
    }
    else
    {
    Rotate to 0 degree
    }

  • Brett Buckley

    I’m doing a project using PIC16F887, which is gonna remotely control a crane using servos. Kind of lost , will this code above be a helpful aid for this type of project?

  • It may be, depends upon how you are planning to make the project.

  • Firass

    in this code , why you are using a loop ??? :
    for(i=0;i<50;i++)

  • Loop give time for servo to rotate to that specific angle.