From OmegaV-wiki
Jump to: navigation, search

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.


<source lang=c>

  1. ifndef SERVO_H
  2. define SERVO_H
  3. include <inttypes.h>

void servo_init(void); void servo_set(uint8_t p);

  1. endif



<source lang=c>

  1. include "servo.h"
  2. 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; } </source>

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