Servo Motor
A servo motor is an electric device used for precise control of angular rotation. It is used where precise control is required, like in the case of control of a robotic arm.
- It consists of a suitable motor with control circuitry for precise position control of the motor shaft.
- It is a closed-loop system.
- The rotation angle of the servo motor is controlled by applying a PWM signal to it.
- By varying the width of the PWM signal, we can change the rotation angle and direction of the motor.
For more information about Servo Motor and how to use it, refer to the topic Servo Motor in the sensors and modules section.
Generating PWM using 8051
SG90 servo has a practical duty cycle time for -90° to +90 rotation that is different from ideal.
At ~0.54ms (2.7% duty cycle) we get shaft position at -90° of its rotation.
At ~1.4ms (7% duty cycle) we get shaft position at 0° (neutral) of its rotation.
At ~2.4ms (12% duty cycle) we get shaft position at +90° of its rotation.
To control the servo motor in between -90° to +90° rotation. We need to generate a PWM waveform of 50Hz with duty cycle variation from ~0.54ms to ~2.4ms. We can generate PWM using Timer in 8051.
Connecting SG90 Micro Servo Motor with 8051
Example
Now let’s program AT89S52 to generate 50Hz PWM to control Servo Motor in the angle between -90° to +90° rotation.
Here we have generated PWM on the P2.0 pin of AT89S52.
Servo Motor Controlling using 8051
#include <reg52.h>
#include <intrins.h>
/* Define value to be loaded in timer for PWM period of 20 milli second */
#define PWM_Period 0xB7FE
sbit Servo_Motor_Pin = P2^0;
unsigned int ON_Period, OFF_Period, DutyCycle;
/* Function to provide delay of 1ms at 11.0592 MHz */
void delay(unsigned int count)
{
int i,j;
for(i=0; i<count; i++)
for(j=0; j<112; j++);
}
void Timer_init()
{
TMOD = 0x01; /* Timer0 mode1 */
TH0 = (PWM_Period >> 8);/* 20ms timer value */
TL0 = PWM_Period;
TR0 = 1; /* Start timer0 */
}
/* Timer0 interrupt service routine (ISR) */
void Timer0_ISR() interrupt 1
{
Servo_Motor_Pin = !Servo_Motor_Pin;
if(Servo_Motor_Pin)
{
TH0 = (ON_Period >> 8);
TL0 = ON_Period;
}
else
{
TH0 = (OFF_Period >> 8);
TL0 = OFF_Period;
}
}
/* Calculate ON & OFF period from duty cycle */
void Set_DutyCycle_To(float duty_cycle)
{
float period = 65535 - PWM_Period;
ON_Period = ((period/100.0) * duty_cycle);
OFF_Period = (period - ON_Period);
ON_Period = 65535 - ON_Period;
OFF_Period = 65535 - OFF_Period;
}
int main()
{
EA = 1; /* Enable global interrupt */
ET0 = 1; /* Enable timer0 interrupt */
Timer_init();
while(1)
{
Set_DutyCycle_To(2.7);/* 0.54ms(2.7%) of 20ms(100%) period */
delay(1000);
Set_DutyCycle_To(7);/* 1.4ms(7%) of 20ms(100%) period */
delay(1000);
Set_DutyCycle_To(12);/* 2.4ms(12%) of 20ms(100%) period */
delay(1000);
}
}
Components Used |
||
---|---|---|
Servo Motor MG995 Servo Motor MG995 |
X 1 | |
8051 AT89c51 8051 AT89c51 |
X 1 |