Servo Motor Interfacing with 8051 Microcontroller

Published  July 11, 2015   14
J Jayant
Author
Servo Motor Interfacing with 8051 Microcontroller

Servo motors are very useful in electronics and embedded systems. You can find the use of Servo motor everywhere around you, they are used in toys, robots, CD tray of computer, cars, aeroplane etc. The reason of this wide scope is that, servo motor is very reliable and precise. We can rotate it to any particular angle. They are available in wide range, form high torque motor to low torque motors. In this tutorial we are going to interface a servo motor to 8051 microcontroller (AT89S52).

 

First we need to understand the working principle of servo motors. Servo motor works on PWM (Pulse width modulation) principal, means its angle of rotation is controlled by the duration of applied pulse to its Control PIN. Basically servo motor is made up of DC motor which is controlled by a variable resistor (potentiometer) and some gears. High speed force of DC motor is converted into torque by Gears. We know that WORK= FORCE X DISTANCE, in DC motor Force is less and distance (speed) is high and in Servo, force is High and distance is less. Potentiometer is connected to the output shaft of the Servo, to calculate the angle and stop the DC motor on required angle.

 

Servo motor can be rotated from 0 to 180 degree, but it can go up to 210 degree, depending on the manufacturering. This degree of rotation can be controlled by applying a LOGIC level 1 pulse for a duration between 1ms to 2ms. A 1 ms can rotate servo to 0 degree, 1.5ms can rotate to 90 degree and 2 ms pulse can rotate it to 180 degree. Duration between 1 to 2 ms can rotate Servo motor to any angle between 0 to 180 degree.

Servo Angular Rotation

 

Circuit Diagram and Working Explanation

8051 Servo Motor Interfacing Circuit Diagram

Servo motor has three wires Red for Vcc (power supply), Brown for Ground, and Orange is control wire. Control wire can be connected to 8051, we have connected it to Pin 2.1 of 8051. Now we have to keep this pin to Logic 1 for 1ms to rotate it 0 degree, 1.5ms for 90 degree, 2 ms for 180 degree. We have used on chip Timers of 8051 to create delay. We have created delay of 50us through the function “servo_delay”, and used “for” loop to create delay in multiple of 50us.

 

We are using Timer 0 and in Mode 1, so we have put 01H in TMOD register. Mode 1 is 16 bit timer mode and TH0 contain High byte and TL0 contain Low byte of 16 bit timer. We have put FFD2 in 16 bit timer register, FF in TH0 and D2 in TL0. Putting FFD2 will create the delay of approx. 50 us with the crystal of 11.0592MHz. TR0 and TF0 are the bits of TCON register, TR pin used to start timer when set and stop when reset(0). TF is overflow flag, set by hardware when overflow and need to reset it by software. Basically TF tells the completion of Timer, and set by hardware when 16 timer transit from FFFFH to 0000H. You can read about the “8051 Timers” to understand the calculation of value in timers registers, to create the 50 us delay.

 

Now when measured from CRO, 13 loops of servo_delay function will give the delay of 1ms, so we have started from 1ms (13 loops) and gone to 2 ms (26 loops) to rotate the servo from 0 to 180 degree. But we have slowly incremented the delay from 1ms, we have divided 1ms to 2 ms window into 7 parts like 1.14ms, 1.28 ms, 1.42ms and so on, so the servo will rotate in multiple of approx. 26 degrees(180/7). After 180 it will automatically return to 0 degree.

Code

// C program for interfacing servo motor with 8051 microcontroller

#include<reg51.h>
sbit output=P2^0;

void msdelay(unsigned int time)  // Function for creating delay in milliseconds.
{
    unsigned i,j ;
    for(i=0;i<time;i++)    
    for(j=0;j<1275;j++);
}

void servo_delay(int times)     // Creating Delay in multilple of 50us using 8051 Timers
{
    int m;
    for(m=0;m<times;m++)
    {
        TH0=0xFF;
        TL0=0xD2;
        TR0=1;
        while(TF0==0);
        TF0=0;
        TR0=0;
    }
}
void main()
{
    int n;
    TMOD=0x01;                // Selecting Timer 0, Mode 1
    output=0;
    while(1)
    {
        for(n=13;n<28;n=n+2)
        {
            output=1;
            servo_delay(n);     
            output=0;
            servo_delay(260);
            msdelay(200);
        }
    }
}

Video

Comments

Submitted by Murugan on Mon, 11/23/2015 - 20:01

Permalink

hi this is murugan, i did not understand this line " for(n=13;n<28;n=n+2) , wil u pls explain ? y ur using n=13.......13?????????

Hi Murugan,
This is clearly mentioned in last paragraph that 1ms delay can be created by passing 13 in servo_delay function and we are passing "n" in servo_delay(n); that means "for" loop inside servo_delay function will be executed 13 times to create a delay of 1ms (for 0 degree). Then again passed n+2, means 13+2 in servo_delay to create delay of 1.14ms to rotate the servo by 26 degrees then again increment it by 2 (13+2+2) for further 26 degrees rotation, and so on.
Hope its clear now.

Submitted by eira on Sun, 05/22/2016 - 08:47

Permalink

hai sie.. can i know that programming above also can include for the keypad.. how i can calculated the duty cycle..

Submitted by Monu singh on Sat, 10/29/2016 - 01:12

Permalink

hy there i need some help...i was looking to rotate my motor 0-90°(when power is turn on) n then 90-0°(when power ids turn off). can any one hlp me in coding....?

Submitted by sreerag on Fri, 11/25/2016 - 09:10

Permalink

sir I didn't understand about the last line mentioning servo delay (n) and servo delay (260) can u explain

To rotate the servo we need to provide HIGH signal for some time (1.5ms for 90 degree) and then low signal for some time. (20-1.5= 18.5ms for 90 degree). Check the diagram given, so servo delay (n) is for applying high logic and servo delay (260) for applying low logic to servo.

Submitted by Tauqeer Altaf … on Tue, 04/04/2017 - 11:42

Permalink

I tried to recreate this program in assembly program using a DXW90 micro servo motor.
The program only rotates the motor in steps without​stopping it anywhere. Can anyone tell me what's wrong with it and how do I rotate the motor anticlockwise?
The program -
strt: mov r0,#13
loop1: setb p1.0
acall servo_delay
clr p1.0
acall servo_delay_260
acall delay
mov a,r0
add a,#2
mov r0,a
cjne r0,#19,loop1
sjmp strt
servo_delay: mov tmod,#01h
mov th0,#0ffh
mov tl0,#0d2h
setb tr0
back: jnb tf0,back
clr tr0
clr tf0
djnz r0,$
ret
servo_delay_260: mov th0,#0d1h
mov tl0,#32h
setb tr0
back1: jnb tf0,back1
clr tr0
clr tf0
ret
delay: mov r1,#20
here: mov th0,#0dbh
mov tl0,#0ffh
setb tr0
back2: jnb tf0,back2
clr tf0
djnz r1,here
clr tr0
ret
end

Submitted by Nikta on Thu, 05/04/2017 - 17:24

Permalink

Can you please tell me how can I rotate the servo motor anticlockwise ?

Submitted by AMAN on Sat, 11/11/2017 - 13:43

Permalink

hey Nikta,
did you find something about rotating the servo in reverse direction???

Aman, there is no clockwise or anti-clockwise direction for a servo motor. There are only degrees. For each duty cycle the motor will position itself at a degree as explained above

Submitted by Baha dhaoui on Sun, 03/25/2018 - 11:51

Permalink

hey sir, first thanks for the tutorial.
can you please tell me what to do if I want to control this servo using bluetooth

Submitted by Hamza on Sat, 05/12/2018 - 22:22

Permalink

The servo_delay function gives delay in multiples of 50 us. So when we pass argument n = 13, it should logically be a pulse of (50 * 13)/1000 = 0.65 ms and not 1 ms as mentioned. Kindly clarify...