A Servo is a small device that has an output shaft. This shaft can be positioned to specific angular positions by sending the servo a coded signal. As long as the coded signal exists on the input line, the servo will maintain the angular position of the shaft. As the coded signal changes, the angular position of the shaft changes. In practice, servos are used in radio controlled airplanes to position control surfaces like the elevators and rudders. They are also used in radio controlled cars, puppets, and of course, robots.

The guts of a servo motor are shown in the picture below. You can see the control circuitry, the motor, a set of gears, and the case. You can also see the 3 wires that connect to the outside world. One is for power (+5volts), ground, and the white wire is the control wire.

Servo motor

So, how does a servo work? The servo motor has some control circuits and a potentiometer (a variable resistor, aka pot) that is connected to the output shaft. In the picture above, the pot can be seen on the right side of the circuit board. This pot allows the control circuitry to monitor the current angle of the servo motor. If the shaft is at the correct angle, then the motor shuts off. If the circuit finds that the angle is not correct, it will turn the motor the correct direction until the angle is correct. The output shaft of the servo is capable of travelling somewhere around 180 degrees. Usually, its somewhere in the 210 degree range, but it varies by manufacturer. A normal servo is used to control an angular motion of between 0 and 180 degrees. A normal servo is mechanically not capable of turning any farther due to a mechanical stop built on to the main output gear.

The amount of power applied to the motor is proportional to the distance it needs to travel. So, if the shaft needs to turn a large distance, the motor will run at full speed. If it needs to turn only a small amount, the motor will run at a slower speed. This is called proportional control.

How do you communicate the angle at which the servo should turn? The control wire is used to communicate the angle. The angle is determined by the duration of a pulse that is applied to the control wire. This is called Pulse Coded Modulation. The servo expects to see a pulse every 20 milliseconds (.02 seconds). The length of the pulse will determine how far the motor turns. A 1.5 millisecond pulse, for example, will make the motor turn to the 90 degree position (often called the neutral position). If the pulse is shorter than 1.5 ms, then the motor will turn the shaft to closer to 0 degress. If the pulse is longer than 1.5ms, the shaft turns closer to 180 degress.

Standard time vs. angle

Procedure

If you want to control your servo motor from a microcontroller,then you must follow-

bring high a digital port
wait between 1-2ms
bring low the same digital port
cycle a few dozen times per second


Here,i have used PIC16F887  microcontroller.Code is written in C using mikroC PRO for PIC.

Source Code

void main(){

int i;
ANSEL  = 0;                                    // Configure AN pins as digital I/O
ANSELH = 0;

PORTD=0x00;
TRISD=0x00;

while(1){

//Move Anti Clockwise direction
for(i=1;i<=500; i++){
PORTD=(1<<RD2); //output_high(PIN_D2);
delay_us(1000); //want servo to move to 0 degrees.
PORTD=(0<<RD2);  //output_low(PIN_D2);
delay_ms(20);

}

//Move Clockwise Direction
for(i=1;i<=500; i++){
PORTD=(1<<RD2); //output_high(PIN_D2);
delay_us(2000); //want servo to move to 180 degrees.
PORTD=(0<<RD2);  //output_low(PIN_D2);
delay_ms(20);

}

}
}

Circuit Diagram

Advertisements

Comments on: "Servo Motor Control Using Microcontroller" (19)

  1. Hello, i had tried to simulate using the exact configuration and compile the program using the same compiler. But the servo motor will only turn clockwise and not counter clockwise. maybe i missed one step, or maybe u forgot to include one step. can u help me here? thx

    • First, servo moves anticlockwise, wait few times on that direction.After that it moves clockwise and wait few times.This process is continuously running for this program.So ,You see carefully when you simulates or practically implementing.

      Or you can change the loop to decreasing delay.

      for(i=1;i<=20; i++){}

      • Yes i had tried to change the integer i value to become less than 500, (eg: 20 like u had stated) but still i can see the servo to move ccw in the simulation. here is the source file for the proteus 7.7 and microC file that i had made. can u check the file? thx for your time

        http://www.mediafire.com/?wf11jtamkgxg7ij

  2. I think ,problem is to setup clock frequency.When you create project,you set 20 Mhz clock frequency but at the simulation you are not using 20 Mhz.

    So,Set the clock frequency 20 Mhz at simulation and test it.

    Thanks

    • Thanks for your time. But as you can see, i had already select the processor clock frequency to 20Mhz (Edit component section). and still could not make it to work. If it is not a hustle to you, could you upload your source file and I really want to see where is my mistake. thanks again

      p/s: i had use proteus for 2 years, but maybe there is another way i can configure the clock frequency that i don’t know because the way this i configure the clock frequency trough component properties just lead me to the dead end. i always working with dc motor before, but never with servo, thanks again

  3. Thanks, but I still got the same result. But anyhow, I had already got the solution. The difference only the coding syntax .. maybe it some kind of bug in proteus.. Thanks for your help. Nice blog ^^

  4. […] The control signals for the rotation of the motor are provided by 8051 microcontroller.For basic concepts and know-how of a servo motor, refer to the article Servo Motor. […]

  5. Dimitris Themistocleous said:

    First of all, congratulations for your comments here. All the explanations are really helpful.
    Because I’m not familiar with all these electronics I would like to ask if you can help me to create a program to control one servo motor slightly different from what you are doing here.

    I want to use the same micro controller (PIC16F877). I need also one push button and as you press the button once the servo must perform one full revolution (360 degrees). I refer the code to be in C language or in Assembly (MPLAB). If you can give me also the circuit diagram for that I’ll really appreciate all this!

    Thanks in advance!

  6. hello, how will my program will be, if i put a flex sensor as a controller of servo?

  7. Thank you friend.for your help.

  8. Please help me to use GH311 sonar (3-pin , ping sensor),by using micro-c programming.
    i have 16f877A pic and i’m working with “mikroC PRO for PIC” .
    help me soon.(i want to checked the distance and run my robot in correct way)
    thanks.

  9. mehdi_hym said:

    thank after any thing you for this program ,but if i do simulation for this program in isis proteus and i charge the program to this Pic he display errer :
    internal exeption accec voilation in module ”[54003152]
    Help me please ……….I

  10. how to use in micro c language for servo motor.??

  11. hello, tq for the program..btw how can i make this program turn off and on using push switch button?

  12. chirag patel said:

    can any one please tell me the meaning of bellow sentense?
    PORTD=(1<<RD2);

    i know what is PORTD.its a port number D of microcontroller but i cant understand the meaning of (1<<RD2); ?????
    pls explain me
    thanks

  13. i kept getting syntax error on the int i; part. Help me please

  14. Anonymous said:

    refer electroidware.blogspot.in

  15. HERE SAMPLE CODING FOR U ALL…. U CAN EMAIL ME FOR ASK ANY QUESTION AT —>>> fariqfauzan50@gmail.com
    I used PIC16F877A and Hitec Compiler
    _______________________________________________________________________
    #include
    __CONFIG(FOSC_HS&WDTE_OFF&PWRTE_ON&BOREN_OFF&LVP_OFF);
    #define _XTAL_FREQ 20000000
    #define ANSEL RE0
    #define ANSELH RE1
    int i;
    void main()
    {

    ANSEL = 0; // Configure AN pins as digital I/O
    ANSELH = 0;

    PORTE=0x00;
    TRISE=0x00;

    while(1)
    {

    //GERAK FULL 90
    for(i=0;i<50; i++)
    {
    PORTE=(1<<RD2); //output_high(PIN_D2);
    __delay_us(900); //want servo to move to
    PORTE=(0<<RD2); //output_low(PIN_D2);
    __delay_us(19200);
    }
    //GERAK TGH
    for(i=0;i<50; i++)
    {
    PORTE=(1<<RD2); //output_high(PIN_D2);
    __delay_us(1500); //want servo to move to
    PORTE=(0<<RD2); //output_low(PIN_D2);
    __delay_us(18500);
    }

    //GERAK FULL KE INITIAL
    for(i=0;i<90; i++)
    {
    PORTE=(1<<RD2); //output_high(PIN_D2);
    __delay_us(2000); //want servo to move to
    PORTE=(0<<RD2); //output_low(PIN_D2);
    __delay_us(17800);

    }
    }
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: