Servo motor control using AVR

Servo motors are so called “closed feedback” systems. This means that motor comes with control circuit, which senses if motor mechanism is in desired location and if not it continuously corrects an error until motor reaches proper point.

Servo motors are widely used in robotics, remote controlled planes, vehicles. So they come in many shapes and sizes, but they operate in almost the same way. Usually Servo motors are controlled by computer, microcontroller or even simple timer circuit. Of course you may find more advanced servos – R/C so called radio controlled. But again, they are same servos just it takes signals from receiver.

How Servo Motor Control Works

Usually servo motors are put in plastic box, but inside there is a whole system: motor itself, gears and motor driving and control circuit.

(www.seattlerobotics.org )

the gears reduces motor speed but increases torque. As we mentioned that servos works with closed feedback loop. This is actually potentiometer which is connected to mechanical shaft and senses the angle of turn. So potentiometer voltage directly indicate the angle of turn. Potentiometer signal goes to digital controller of motor which powers motor until potentiometer reaches desired angle, then logic shuts the motor.

Servos usually are powered by DC voltage from 4.8 to 7.2V.

Usually servos are designed with limited rotation angle like 90° or 180° and so on. Of course they can be modifier for continuous rotation. Precise rotation and force thanks to gear system servos are ideal for robotic purposes.

Servo control signals

Servo motor shaft is positioned with pulse width modulated signals. So all servos comes with three wires (Power, Ground and Control). So pulses are sent via control wire. Usually in hobby servos with rotation angle 90° signal width vary between 1 and 2ms. If pulse is more wide rotation continues until reaches mechanical limits.

The frequency of PWM usually is in range from 30 to 60Hz – this is so called refresh rate. If this refresh rate is too small then then accuracy of servo reduces as it starts lose its position periodically if rate is too big, then servo can start chatter. It is important to select optimal rate, that servo motor could lock its position.

The motor powering circuit power motor depending on what is difference between current position and where it should be. If this difference is small the energy portion given to motos is small that it wouldn't overshoot the position – motor in this situation is driven slowly. But is difference is big, then motor is powered to turn at full speed that it could reach new position as fast as possible. When shaft approaches to new position, at he end of movement motor slows down in order to stop at accurate position. This complicated process lasts for about a half a second when rotation angle is 60°.

Servo control using Atmega8

Lets see simple example of servo control using Atmega8 and Timer1 fast PWM. Circuit represents only main parts.

Program code written for WinAVR toolset:

//-------------------------

#include <avr\io.h>

int main(void) {

//Port D pins as input

DDRD=0x00;

//Enable internal pull ups

PORTD=0xFF;

//Set PORTB1 pin as output

DDRB=0xFF;

//TOP=ICR1;

//Output compare OC1A 8 bit non inverted PWM

//Clear OC1A on Compare Match, set OC1A at TOP

//Fast PWM

//ICR1=20000 defines 50Hz PWM

ICR1=20000;

TCCR1A|=(0<<COM1A0)|(1<<COM1A1)|(0<<COM1B0)|(0<<COM1B1)|

(0<<FOC1A)|(0<<FOC1B)|(1<<WGM11)|(0<<WGM10);

TCCR1B|=(0<<ICNC1)|(0<<ICES1)|(1<<WGM13)|(1<<WGM12)|

(0<<CS12)|(1<<CS11)|(0<<CS10);

//start timer with prescaler 8

for (;;) {

if(bit_is_clear(PIND, 0)){

//increase duty cycle

OCR1A+=10;

loop_until_bit_is_set(PIND, 0);

}

if(bit_is_clear(PIND, 1)) {

//decease duty cycle

OCR1A-=10;

loop_until_bit_is_set(PIND, 1);

}

}

}

//----------------------------------

Comments

Man is it frustrating trying to google for information about creating your own servo motor controllers. The thing you're talking about here is a servo or hobby servo not a servo motor - it would be freaking awesome if folks wouldn't interchange the terms so google searches might have a chance of coming up with the right things...

go away loser, this is what people want to do.
Thanks to the author for making this useful tutorial available for us.

gtfo f%ckin freak, i was serchin 4 this info for 3 days and its very useful

how to control with potentiometer in same atmega8

wonderful tutorial.......helped a lot!

Hi admin, I have written my code with Win-avr and simulate in Proteous. I setup like you: mode 14, clear compare match set Top, prescale = 8. I work well when I set the Atmega8 in Proteous have Int RC 8Mhz, but when I choose other option (1Mhz,2,4 ... ), the servo not move ... Can you explain it for me, why Servo not work if I choose other Int Rc option for atmega chip. thanks.

The PWM is controlled by the timer and is linked to the master clock (the timer counts clock cycles). As stated in the original article, Analog RC Servos require a refresh pulse every 20ms / 50Hz (nom.) with a pulse width of 1.5ms +/- 0.5ms (nom.) to control the position of a Standard Servo. To maintain the PWM timing (nominally 50 Hz  20ms) you must change the timer setup to match the clock change. Look at the tech specs on the Parallax website (or the make of RC Servo you are using).