How to control a servo motor.

servo motor controller pic2

In ths project you can learn how to build a servo controleer motor with the ATMEGA328 board. The position of the servo motor is controlled by the software (sweep back and forth) or by a potentiometer.

 The position of the servo motor is set by the length of a pulse. The servo expects to receive a pulse roughly every 20 milliseconds. If that pulse is high for 1 millisecond, then the servo angle will be zero, if it is 1.5 milliseconds, then it will be at its centre position and if it is 2 milliseconds it will be at 180 degrees.

servo motor controller pic1


Parts

Part qty
servo motor 
servo motor controller pic1
breadboard
breadboard
1
ATMEGA328 board
atmega328v2 1 tb
1

jumper wires

jumper wires

 a bunch 

Schematic and board layout for sweep function

servo motor controller sch

  servo motor controller brd

C-Code for sweep function

Below is the C-code made with the WINAVR compiler.

// program name: servo motor controller for sweep function
// date: 27-jun-2017
// author: www.avrprojects.net
// target device : ATMEGA328

#include <avr/io.h>
#include <util/delay.h>
#define F_CPU = 16000000;


int main (void)

{
DDRB = 0xFF; // set portb for output
PORTB = 0;

int pos = 0;
while(1)
{
for (pos = 750; pos <= 2250; pos += 10)
{
PORTB = 0x00000001;
_delay_us (pos);
PORTB = 0x00000000;
_delay_us (20000 - pos);
}
for (pos = 2250; pos >= 750; pos -= 10)
{
PORTB = 0x00000001;
_delay_us (pos);
PORTB = 0x00000000;
_delay_us (20000 - pos);
}
}
}

 


Schematic and board layout potmeter function

servo motor potmeter sch

C-Code for potmeter function

// program name: servo motor controller with potmeter
// date: 08-mrt-2017
// author: www.avrprojects.net
// target device : ATMEGA328

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#define F_CPU = 16000000;

#define FOSC 16000000 // clock speed
#define BAUD 9600 // baud rate
#define MYUBRR FOSC/16/BAUD-1


// this function read the value of ADC channel 0
int readADC(char channel)
{
//adc init
ADMUX = channel; // set ADC channel
ADCSRA = 0b10000111; //set ADEN, precale by 128
ADCSRA |= 1<<ADSC; //start conversion;
while (ADCSRA&(1<<ADSC)); //wait conversion end
int ADC_temp = ADCL; // read out ADCL register
ADC_temp += (ADCH << 8); // read out ADCH register
return ADC_temp;
}

int main (void)

{
DDRB = 0xFF; // set portb for output
PORTB = 0;

while(1)
{
// potmeter function
int pos = readADC(0);
pos = (pos * 2) + 500;

PORTB = 0x00000001;
_delay_us (pos);
PORTB = 0x00000000;
_delay_us (20000 - pos);
}
}