AVR/Source/Servo

From OmgaV Wiki

Jump to: navigation, search

Contents

Servo Controller

A normal servo usually only needs three pins: Vcc, GND and a Signal-pin.
The signal is typically a 50Hz (20ms) PWM-signal with a Duty cycle variating between 0.9ms and 2.1ms,
but these figures may vary. The length of the Duty cycle controls the angle of the servo.


Atmega128 Code Example

This code shows how to setup a timer to control a servo connected on Port B pin 6 (OCR1B).
The Atmega is assumed to run at 8Mhz, and the timer is set to run at 1/8th of this.
As usual we recommend that you read the relevant part in the datasheet.

servo.h

#ifndef SERVO_H
#define SERVO_H
#include <inttypes.h>
 
void servo_init(void);
void servo_set(uint8_t p);
 
#endif

pwm.c

#include "servo.h"
#include <avr/io.h>
 
const static uint16_t servo_max = 2100;
const static uint16_t servo_min = 900;
 
void servo_init(void) {
// Set pin to output
DDRB |= (1<<PB6);
 
// Timer Top
ICR1 = 20000; // (8MHz/8)/ICR1 = 50Hz
 
// Initial compare value 50%
servo_set(255/2);
 
// Set mode and start timer
TCCR1A = (0<<WGM10) | (1<<WGM11) | (1<<COM1B1); // Fast pwm = 14 & Enable pwm on OSC1B
TCCR1B = (1<<WGM12) | (1<<WGM13) | (1<<CS11); // Fast pwm = 14 & Clk/8
}
 
 
/*! \param p 0-255 */
void servo_set(uint8_t p) {
uint16_t pos = (servo_max-servo_min)*(p/255.0) + servo_min;
OCR1B = pos;
}


Image highlighting the relationship between the timer and the pin output:
Fast PWM

Personal tools