ATtiny45/85 Servo Library

Recently I worked on a project where I wanted to control a servo using an Atmel ATtiny85. I checked online for ready made code that did this but I couldn’t find anything satisfactory. Not wanting to switch to a larger microcontroller I decided to write my own servo library for the ATtiny85.

I call it Servo8Bit. It supports up to 5 servos, runs on the ATtiny85 or ATtiny45 and uses only one 8 bit counter. It can generate a servo control pulse from 512 to 2560 microseconds with 256 steps of resolution. And, most importantly, it is very easy to use.

Управление 5 сервоприводами на ATtiny45/85

I enjoy using ATtiny microprocessors in my projects, particular the ATtiny85. It is very small with only 8 pins, and it costs about two dollars each. All the code I found for it controlled the servo with about 12 steps of resolution. The problem is that the ATtiny85 only has 8 bit timers. There is excellent servo control code for most other ATtiny microcontrollers and they all make use of 16 bit counters. I could have used another ATtiny, one that has a 16 bit timer, but all of those have more pins than the ATtiny85.

This library is modeled after then Arduino servo library and has an identical interface. Here is a short example program that shows how this library is used.

The definition of the delay() function is omitted, which is needed to for this code to compile. The example file included with this library contains all the code. Here is a video that shows this example code in action:

Functions overview

These are the functions that are available in this library. They behave identical to the functions of the Arduino servo library with no surprises.

  • attach() – Attach the Servo variable to a pin.
  • write() – Writes a value in degrees to the servo, controlling the shaft accordingly.
  • writeMicroseconds() – Writes a value in microseconds to the servo, controlling the shaft accordingly
  • read() – Read the current angle of the servo (the value passed to the last call to write()).
  • attached() – Check whether the Servo variable is attached to a pin.
  • detach() – Detach the Servo variable from its pin.

When a servo is attached to a pin a PWM servo control signal will start being generated on that pin. By default it will command the servo to move to its middle position. You can command the servo to move by calling the write() function and passing in a number between 0 and 180. This number represents rotational position in degrees. For example, depending on how you’re looking at the servo, 0 would mean go all the way left, 180 would mean go all the way right and 90 would mean go to the center. If you are using a continuous servo then this number represents speed and direction, where 0 is full speed forward, 180 is full speed backwards and 90 is stop.

Not all servos go to the same position for each pulse length. You might notice this if you use a continuous servo and instead of stopping it rotates slowly in one direction when you tell it to go to position 90. In this case you might want to change the pulse lengths used by the driver. You can do this by calling the attach function with 3 arguments, like so: myServo.attach(pin, min, max), where pin is the pin on portB to be pulsed, min is the minimal pulse length to generate at 0 degrees and max is the maximum pulse length to generate at 180 degrees. The default is 544 and 2400 microseconds. You can also use the function writeMicroseconds() to manually set the pulse length.

To completely stop pulsing the servo call the detach() function. The pin will not be pulsed again until the attach() function is called.

Limitions of current version
This library has some limitations to it. Here is a list of some that come to mind:

  • Works only on the ATtiny45 and the ATtiny85. It might work on other ATtiny microcontrollers, such as the ATtiny15, but I haven’t checked.
  • Supports only 5 servo.*
  • Supports only one clock frequencies: 8MHz.
  • Supports only pins on Port B. Which is only port available on the ATtiny45/85.
  • Uses timer0 by default with no easy way to configure it to use another timer.

* The driver can easily be tweaked to support more servos, at the cost of extended time between pulses. See the notes in file ‘Servo8Bit.h’.

Planned enhancements

  • Support for multiple clock frequencies.
  • An easy way to configure which timer the driver should use.

Demonstration

Download

Source Code, make-file, example - download
The library comes with an example project that sweeps the servo, and a Make file to compile it for you.