ATtiny45/85 Servo Library

Recently I worked on a project where I wanted to control a servo using an 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.

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include "Servo8Bit.h"
 
int main()
{
    Servo8Bit myServo;  //create a servo object.
                        //a maximum of five servo objects can be created 
 
    myServo.attach(1);  //attach the servo to pin PB1
 
    //sweep the servo
    while(1)
    {
        for(int pos = 0; pos < 180; pos++)  // goes from 0 degrees to 180 degrees
        {                                   // in steps of 1 degree
            myServo.write(pos);             // tell servo to go to position in variable 'pos'
            delay(15);                      // waits 15ms for the servo to reach the position
        }
 
        for(int pos = 180; pos > 1; pos--)  // goes from 180 degrees to 0 degrees
        {
            myServo.write(pos);             // tell servo to go to position in variable 'pos'
            delay(15);                      // waits 15ms for the servo to reach the position
        }
    }
}

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.

Download

You can download the Servo8Bit library from its GitHub page here: Servo8Bit Library
The library comes with an example project that sweeps the servo, and a Make file to compile it for you.


89 Comments on “ATtiny45/85 Servo Library”

  1. Nice writeup, Well documented and clean code! I have noticed that most servos are capable of 200 degrees of movement. I like that you allow for that in the code.

  2. jeff cooperider says:

    I have unfortunately little erperience in programming but have no lack of interest. I have tried a bit with PIC16F690 and have a PicKit2. i have also bought an Arduino and like it a lot, What I would like to ask you is how can the ATtiny45/85 be programmed?

  3. phillip ryals says:

    I’ve needed a library like this for a long time, specifically for the ’85. Thanks so much for your effort!

    • ilya says:

      Awesome, I’m glad you find it useful.

    • phillip ryals says:

      I haven’t been able to get your library to work, unfortunately. Full disclosure, I’m not using WinAVR, but avrdude on a Mac. Everything else is standard… attiny85, Hitec HI55 servo. The code compiles without issues.

      When I run it with the sweep example code though, the servo jumps to one side and refuses to move after that. I’ve tried adjusting the microseconds, and have messed with lots of other variables, but to no avail.

      I even tried another servo, just to make sure it wasn’t the issue.

      Any pointers?

    • ilya says:

      What are your fuse bits set to? Sounds like you have the chip running at a clock speed other then 8mhz. If you never set the fuse bits, the factory default sets the chip to run at 1mhz clock speed.

    • phillip ryals says:

      That was it! I feel silly, but I didn’t know CKDIV8 was set by default!

      The library is working great. Thanks again!

  4. Joe says:

    I am a little new to this, how do I get it to compile in the Arduino IDE? Do I create a new sketch with 3 tabs with the example, the .cpp and the .h file?

    I am using Arduino 0022 with the ATtiny45/85 core files to allow the IDE to program them through an Arduino right now. When I do that and try to compile (not upload) I get this error:

    sketch_sep27a.cpp: In function ‘int main()’:
    sketch_sep27a:21: error: call of overloaded ‘delay(int)’ is ambiguous
    /Users/Harddrive/Documents/Arduino/hardware/attiny45_85/cores/attiny45_85/wiring.h:128: note: candidates are: void delay(long unsigned int)
    sketch_sep27a.cpp:10: note: void delay(uint16_t)

    And it seems to repeat for every time delay is called. Any help would be appreciated

    • ilya says:

      The example file, and the whole library really, is written so that it can run standalone without needing anything additional, such as the Arduino files. That said, it should be possible to use this library with the Arduino ATtiny45/85 core files. I’ve never tried using these core files myself, but try out the following, it should work out:

      1) Start a new blank sketch and save it.
      2) Download this servo8bit example that I modified to be an Arduino sketch. http://www.cunningturtle.com/wordpress/wp-content/uploads/2011/09/servo8bit_example_arduino.pde Copy and past it into the blank sketch that you made.
      3) Open up the sketch folder that Arduino made when you saved the blank sketch.
      4) Place into it the files Servo8Bit.h and Servo8Bit.cpp. This folder should have three files in it now; the two files you just placed plus the sketch .pde file.
      5) Hit the Upload button in the Arduino IDE. The example should compile and upload with no problems.

      Now since this servo library was not written with the Arduino ATtiny45/85 core files in mind it will probably interfere with them. For example, if the core files uses Timer0 to keep track of time, using this servo library will stop the millies() functions from working. I’ve seen three different efforts on the web to create ATtiny45/85 core files for the Arduino IDE. Which ones are you using? It should be fairly straight forward to modify this servo library to play nice with those core files.

    • Joe says:

      Doh, read the page over again, omitted it, compiled, loaded. I tried 3 different servos. When the sketch starts, it centers and then pulses maybe 2-3 times a second and gradually makes its way to one side and decelerates but does not sweep back and forth. Any ideas?

  5. Joe says:

    Just saw your reply.
    I am using these core files:

    http://toasterbotics.blogspot.com/2011/08/using-arduino-with-attinys.html

    I did as you said, also noticed the difference between the first sketch and the arduino sketch, void loop and void setup. I was able to get it onto the ATtiny using my Arduino duemilanove as an ISP but it does the same thing. The servo starts at one end starts off quick and then decelerates while pulsing and does not turn back.

    Thanks!

    • ilya says:

      I just looked through these core files. Yep using my servo class with them totally wrecks everything. The core files use Timer0 for a lot of things and my servo library tries to take control of it for its own use. Also it seems the core files set the ATtiny to run at 1MHz, while the servo library currently only works at 8MHz. Very not surprising the example file is not working for you.

      I’ll make some quick changes to the library tonight to make it use Timer1 instead of Timer0 and to support operating at 1MHz. That should make the library work with the ATtiny cores you are using.

  6. Joe says:

    Woah that would be awesome! Thanks!

  7. Brad says:

    I also am interested to get this working inside the arduino IDE. i’m pretty new, and i’ve had a hell of a time trying to get a servo working with an attiny85. i only need to control one servo, i have made my own pcb, and just can’t get the damn thing working!

    side note, you have to set your attiny85 to work at 8 mhz. if you include
    and in void setup() add the line
    clock_prescale_set(0);

    it will set your attiny85 to run at 8mhz and solve that problem.

  8. Brad says:

    hmm… it did not post my comment properly i meant to say

    you should have the statement

    “#include ”

    i am using core files from http://hlt.media.mit.edu/wiki/pmwiki.php?n=Main.ArduinoATtiny4585

  9. Brad says:

    okay one more time.. stupid comment…

    “#include avr/power.h” and have the standard less than equal than symbols around it.

  10. ilya says:

    I’ve made the changes to the library I mentioned above and I got it working with the attiny core files running at 1mhz. There’s some odd things I’m seeing though. Some function in the core files seems to be overwriting my Timer1 settings, which I was able to override again in the setup function in the sketch. Pretty hacky… but it worked. The servo also seems to jitter a bit at certain positions as it sweeps left and right. This might be a bug in my code caused by running it at 1mhz.

    The next version of this library that I’ll release will have the modifications to allow it to work with the Arduino Attiny core files. But that release wont happen until I look into and fix these bugs I’m seeing. In the mean time, I can post the library with my modifications (as it is now) if you guys want to play around with it.

  11. Joe says:

    I would really like to see the code, or better, how you knew what to change. (I am still new to programming, seeing other peoples work instead of the finished project is really helpful)

    I only plan to use it to drive two to three servos for a simple robot drive, so I can handle a few bugs here and there. Also, you mention the Arduino core files only runs at 1MHZ, is there any way to tweak it to 8MHZ ?

    • ilya says:

      I agree, looking at other people’s unpolished code is helpful. Here is my work-in-progress code http://www.cunningturtle.com/wordpress/wp-content/uploads/2011/09/servo8bit-Arduino-test.zip

      In this library I generate a servo pulse by setting a pin high, waiting some time, and then setting it low. To keep track of time, I use one of the chip’s built in hardware timers. To get the pulse resolution I want I set up the timer to tick in increments of 8 microseconds. So every time the timer value increases by 1 I know that 8 microseconds have elapsed. This means I can adjust the length of the pulse I’m creating in 8 microsecond steps.

      This hardware timer is able to keep track of time because it is connected to the main CPU clock. In my original code I assume this clock runs at 8mhz. That means it ticks once every 1/8 of a microsecond. Since the timer I’m using is directly controlled by the CPU clock I know to configure the timer to divide its input clock by 64. 1/8 divide by 64 is 8. Which means this hardware timer will tick once every 8 microseconds.

      When the CPU clock is lowered from 8mhz to 1mhz it reduces the speed of the hardware timer by the same amount. So now one tick takes up 64 microseconds of time instead of the previous 8. This also means the pulses my code is generating get stretched out 8 times longer, way outside the range of what the servo is expecting.

      To deal with this I added logic in my code to check if the clock speed is 8mhz or 1mhz. If it is 8 then setup up the hardware timer as usually to divide its input by 64. If its is 1mhz then I setup the timer to divide its input only by 8. This makes it so each timer tick represents 8 microseconds of time in both cases.

      I learned what timers are from this tutorial http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=50106&sid=94f9b05729c5c95cd466060b3990ffc8

      If you set the chip to run at 8mhz the Arduino core files are probably programmed to handle that. You can toggle the chip speed between 1 and 8 mhz by setting the fuses bits. I learned what fuses bits are and how to set them, from here http://www.ladyada.net/learn/avr/avrdude.html

  12. Joe says:

    I tested out the code, it works just like you said, a few hiccups. I will be sure to keep an eye out for the updated code though. I could really use a servo library for the ATtiny85 since I do not always need a monstrous ATmega to drive a few servos.

    I also tried adding:
    #include
    clock_prescale_set(0);

    as Brad mentioned. In the original it slams the servo to the side and hums, in the updated code it slams the servo to the side but does not hum.

    • Brad says:

      Just to clarify you must include the power.h library in the /avr folder so in your code you will place

      #include avr/power.h

      inside it and you must use the less than, and greater than symbols before and after “avr/power.h” like how other libraries are included. the post box here will not allow me to display it properly, it omits the symbols.

  13. Joe says:

    I had it but the site erased everything between the less than and greater than symbols. I meant to change it but forgot.. 🙂

    • ilya says:

      That is pretty annoying that it strips the brackets aways. I added a plugin to make it easy to insert code into comments. Now you can type in

      <code> #include<avr/power.h> </code>

      which will result in

      #include<avr/power.h>

  14. niek says:

    I tried everything, set my attiny fusebits to 8Mhz, used the [code]#include [/code] but it just goes to one side in little steps and stops there. I’m using arduino IDE btw.

  15. niek says:

    when i try that, it outputs 20+ lines of errors 🙁

    • ilya says:

      It should compile without errors.

      Are you using the Arduino Attiny library from High-Low Tech http://hlt.media.mit.edu/?p=1229 ?

      Did you select your board as Attiny85 (or Attiny45) before you hit compile?

      If you answered yes to both questions then I’m curious to know, out of the compile errors that you get, what does the first error say?

  16. niek says:

    Nope, i used the attiny library from High-Low Tech before but the servo’s just jittered, now i’m using arduino tiny but i’ll try the HLT library now..

  17. niek says:

    Nope, tried the HLT one but it gives the exact same errors :S

  18. sirdan says:

    I just came across this post and thought I’d use your library (http://www.cunningturtle.com/wordpress/wp-content/uploads/2011/09/servo8bit-Arduino-test.zip) with the High-Low Tech library to try out a servo with an ATtiny85. I created a library out of the code per the tutorial on the Arduino site. It compiled fine for me. Should it work? My servo just jittered. Anyway, thank you for your efforts. It will be very useful to power a servo with this chip. I look forward to trying out your next version!

    • ilya says:

      Thanks for your thanks. Yep, the files in servo8Bit-Arduino-test.zip work for me and should work for you too. There are very few steps to get it working, and since you say you got it to compile it looks like you did most of them. In addition check that your fuse bits are set to have your attiny run at 1mhz. I think this is the default factory setting, so if you never touched the fuse bits before, it probably is already set to 1mhz. Easy way to confirm: load up the blink sketch into the attiny and make sure the delay between the LED turning on and off is 1 second. If the attiny is set to 8mhz, this delay will be only 0.125 seconds.

      If the blink sketch works perfectly for your then the next step is to make sure your power supply can provide enough current. For example, I’ve had trouble powering the attiny and the servo from the USB bus. The attiny would reset almost constantly on me every time the servo tried to move. I added a big capacitor between the power and ground on my breadboard and that stopped the attiny from resetting. My capacitor value was 16,000uf – which just happened to be the largest capacitor within arms reach at the time. You can also try using reachable batteries. They provide more current than the USB bus. Hope this helps you out.

    • sirdan says:

      It’s a very small micro servo that I have powered off the Arduino Uno board, but I bet you are right, I’ll try a different power source and confirm that it works. Again, thank you for your work on this library. Great stuff!

    • sirdan says:

      So I tried this again, but didn’t have any luck. I verified the ATtiny85 was running at 1MHz using the Blink sketch. I then hooked the servo up to Arduino Uno and used the Sweep example sketch to verify the servo works. It did. Then I modified a copy of Sweep to use your 8-bit library and Pin 0 and uploaded that to the ATtiny85. I power the ATtiny and micro servo through the 5V output of the Arduino. Rather than powering with the USB, I power the Arduino with a DC adapter that is rated at 1A. I’ve successfully powered the Arduino and a larger servo this way, so I hope this would be sufficient.

      When power is applied, the servo makes a rapid tick-tick-tick. Is there something I’ve missed? Do you still think it’s a power issue? I’m using this servo: http://www.adafruit.com/products/169

    • ilya says:

      Using a separate power supply is definitely a good choice. You are drawing power from the Arduino’s Vin pin and not the 5v pin right? 5v pin gets its power from the on board voltage regulator that can only provide a limited number of milliamps, not enough to power a servo during current spikes, most likely not even the micro servo. The Vin pin provides power directly from your power supply, at the same voltage. You should power the Attiny and the servo directly from the power supply (which is the Vin pin). Unless of course the power supply gives more than 5 volts, then don’t connect it to the ATtiny. If the supply gives about 6 volts you can still power the servo with it and power the ATtiny separately from the Arduino’s 5v pin.

      I finished my next version of the servo8Bit library. I’m writing a tutorial on how to use it with the Arduino ATtiny cores. Once that is done I’m going to officially announce it. If you like though, you can take it for test drive now: http://www.cunningturtle.com/wordpress/wp-content/uploads/2011/11/servo8bit_arduino_example.zip This new version works at both 1mhz and 8mhz. Try out the included example as is. It works fine for me as long as I supply enough power for the ATtiny and the servo.

    • sirdan says:

      Ahhh. Ok. I’m going to have to get a different power supply then, since my DC converter is 12V. It may take a few days, but I’ll let you know when I can try out your new library.

  19. Erni says:

    Hi,
    I just tried your servoexample (from github) and it worked flawlesly, very smooth and without glitches. It is first time ever I tried using a make file instead of the Arduino IDE.

    However if i try the example that should work in the Arduino IDE, I get this errormessage ?

    Servo8Bit.cpp.o: In function `ServoSequencer::registerServo()’:
    C:\Users\EC\AppData\Local\Temp\build8481209357343769614.tmp/Servo8Bit.cpp:195: multiple definition of `ServoSequencer::registerServo()’
    servo8bit\Servo8Bit.cpp.o:D:\download\arduino\arduino-0021\libraries\servo8bit/Servo8Bit.cpp:195: first defined here

    • ilya says:

      Thanks for your feedback. Very cool that this is the first Make file you tried and succeeded.

      From your error message it seems that you have servo8bit.h and servo8bit.cpp files in two places. In the ‘libraries’ folder and in your local work folder. Get rid of them from one of these locations and that should make this error message go away.

  20. Erni says:

    Thankyou ilya,
    You were right, i delete the files and now it is working without problems.
    I am using Coding Bqadly’s core:

    http://code.google.com/p/arduino-tiny
    and a Pololu programmer

    Although I was very proud of myself for being able to use the make file, the advantage with the Arduino IDE is that I can use fx. analogRead() to control the servo with a potmeter

  21. wes wortman says:

    From the link below I bought some of these chips and I’ve been trying to program them.

    http://hlt.media.mit.edu/?p=1706

    The first problem is they don’t give the correct file locations to modify and where unzip the files to. I got through some of that but then I couldn’t get a compile.
    It can’t find all the basic library files now.

    Has an one done this before? Have you gotten it to work?

    Program(Runs and compile on an Arduino UNO etc.) :

    /*
    Fade

    This example shows how to fade an LED on pin 9
    using the analogWrite() function.

    This example code is in the public domain.

    */
    int brightness = 0; // how bright the LED is
    int fadeAmount = 5; // how many points to fade the LED by

    void setup() {
    // declare pin 9 to be an output:
    pinMode(0, OUTPUT);
    pinMode(1, OUTPUT);
    pinMode(2, OUTPUT);
    }

    void loop() {
    // set the brightness of pin 9:

    analogWrite(0, brightness);

    // change the brightness for next time through the loop:
    brightness = brightness + fadeAmount;

    // reverse the direction of the fading at the ends of the fade:
    if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ;
    }
    // wait for 30 milliseconds to see the dimming effect
    delay(30);

    analogWrite(1, brightness);

    // change the brightness for next time through the loop:
    brightness = brightness + fadeAmount;

    // reverse the direction of the fading at the ends of the fade:
    if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ;
    }
    // wait for 30 milliseconds to see the dimming effect
    delay(30);

    analogWrite(2, brightness);

    // change the brightness for next time through the loop:
    brightness = brightness + fadeAmount;

    // reverse the direction of the fading at the ends of the fade:
    if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ;
    }
    // wait for 30 milliseconds to see the dimming effect
    delay(30);

    analogWrite(0, 255); analogWrite(1, 0); analogWrite(2, 0);
    delay(150);
    analogWrite(0, 0); analogWrite(1, 255); analogWrite(2, 0);
    delay(150);
    analogWrite(0, 0); analogWrite(1, 0); analogWrite(2, 255);
    delay(150);

    }

    Errors:

    Fade3color.cpp:10:21: error: Arduino.h: No such file or directory
    Fade3color.cpp: In function ‘void setup()’:
    Fade3color:14: error: ‘OUTPUT’ was not declared in this scope
    Fade3color:14: error: ‘pinMode’ was not declared in this scope
    Fade3color.cpp: In function ‘void loop()’:
    Fade3color:22: error: ‘analogWrite’ was not declared in this scope
    Fade3color:33: error: ‘delay’ was not declared in this scope

    These chips are very cheap and can be used to blink LED and even run a couple of servos with PWM.

    Datasheet for chip:
    http://www.atmel.com/dyn/resources/prod_documents/doc2586.pdf

    Here the ship play old video game music also very cool.

    http://hackaday.com/tag/attiny/

    Wes

  22. Frank says:

    Hi,
    I’ve been trying to use your library with an ATtiny85 with this core http://code.google.com/p/arduino-tiny/ at 8 MHz. This works all fine until I start to use it with other commands such as delay. I tried it with a blink command and ‘delay(32000)’ is a delay of about 1 second.
    I’ve also tried this library at 1 MHz and this also doesn’t work.
    I think this is because the servo8bit library uses the same timer as delay and millis, but I can’t find out which timer is used by the core. I want to change which timer is used by the library but how should I do that?
    Thanks,
    Frank

  23. Bostjan says:

    Hello!

    Foud your library nice, with only one problem that i have. When compiled, (Tiny 85 at 8 mhz), servo jist swings from one side to another, and it needs like 4 seconds to do that sweep. Maybie someone knows what might be a problem?? If servo would move as smooth as it sweeps now, you have done a beautifull work..
    Best, Bostjan

  24. Guilherme says:

    Tried your last version you posted on January 7. It totally works, thanks a lot!

    I see people all over the forums asking for this… I’ve tried using the Software Servo before, but it doesn’t seem to work too well with Arduino 1.0. Your code does!

    You should make a new post about it, so more people can find it!

    • ilya says:

      Awesome! I actually started writing a post for the next version along with a tutorial on how to use the library with arduino and configure the attiny’s fuse bits to get it to run at 8mhz (for best performance) but never finished it. Instead I spent my time working on the Cunning Turtle store, which just launched this wednesday =D. (https://store.cunningturtle.com/) Thinking about it now I’ll probably create a separate post for the new library version, to make it official and stuff, and follow it up with a tutorial post. Thanks for the feedback!

  25. DimiK says:

    Hi!
    I am really newb on this library and generally with the ATtiny45/85. I have a project where I have make an I2C bus connection between an ATtiny45 and an Atmega328P I am writing code on the arduino IDE and on this circuit the Atmega328P has the role of the master and the ATtiny45 has the role of the slave. When I upload to the ATtiny45 a code I received the following avrdude: verification error, first mismatch at byte 0x0000 0x0f != 0x00 avrdude: verification error; content mismatch

    I upload the code to the ATtiny45 directly on it through the USBtinyISP…

    Can you help me on that??
    Thank you in advance!

    • DimiK says:

      This problem was maybe because of the load of the servo motor when it was connected to the PB1 pin of the ATtiny45 during the uploading of the code to the microcontroller… My main problem now is that does not execute the code of your example as in the video that you have uploaded… The uploading seems to be right but the servo motor is just going to the 0 point and there is doing a type of tremor…
      If you have any idea about this problem…

    • ilya says:

      In reference to your second comment: This seems to be a pretty common sang people come across. I’ll wager that you have your fuse bits set such that they configure the ATtiny to run at 1mhz, but you are compiling the code to run at 8mhz.

  26. jim says:

    When I place the software servo folder into the libraries folder, I can not get the Arduino ISP program to start. Take it out again, starts up fine. So where should I put it? What is going on?
    Thanks!

  27. jim says:

    Please disregard that last incorrect statement… I got it to work!
    Great, thanks

  28. iain says:

    Hi there,

    Congratulations on a great library!
    I have just started playing around with attiny85 chips and your stuff was exactly what i was after!
    I have managed to upload the blink file, all works fine, blinking once a second.
    I upload the servo sweep example and the servo sweeps back and forth, taking about 4 seconds per sweep.
    The problem I have is if I try to change the delay or the angle the servo moves to and upload it, the servo moves exactly as before.
    Does anyone have any idea what is going wrong?
    Any help would be very much appreciated!

    • iain says:

      I forgot to mention, I am programming the 85 using an arduino uno and arduino 1.0 software!

  29. ilya says:

    I have a silly question, are you sure your updated code is uploaded and running on the chip? This is a werid problem you’re having. Can you post your code?

    • iain says:

      Thanks for the quick reply!
      I’m pretty sure the code is uploading, after every try with the servo code, I upload the blink again to make sure it’s uploading, then try a new servo sketch!

      All I’m doing at the moment is trying different delay times and/or different angles, just by altering your example, it doesn’t seem to make any difference to what the servo actually does though!
      Here is the latest attempt:

      #include “Servo8Bit.h”

      Servo8Bit myServo; //create a servo object.
      //a maximum of five servo objects can be created

      void setup()
      {
      myServo.attach(0); //attach the servo to pin PB1
      }

      void loop()
      {
      for(int pos = 0; pos 1; pos–) // goes from 180 degrees to 0 degrees
      {
      myServo.write(pos); // tell servo to go to position in variable ‘pos’
      delay(100); // waits 15ms for the servo to reach the position
      }
      }

  30. ilya says:

    Have you tried making the servo go to discreet positions? For example, like this:

    myServo.write(0); //go all the way left
    delay(1000); //stay there for one second
    myServo.write(180); //go all the way right
    delay(1000); //stay there for one second
    myServo.write(90); //go to the center
    delay(1000); //stay there for one second

    • iain says:

      Yeah, I have tried that too, same result!
      When I connect the servo it initially jumps from one end of its range to the other then to around 90 and then settles into a slow sweep back and forth.
      I’ve tried disconnecting and reconnecting the arduino between each upload, using different 85 chips, powering the servo independently, all with the same result, I don’t get it! 🙁

  31. ilya says:

    Lol, I’m going to go with possessed. Yep definitely possessed. Can you upload a video of it doing this? Maybe there is something subtle it does that will give me a clue to what’s wrong. What’s the least amount of code needed to see this problem? What about if you just attach the servo but never tell it to move anywhere? Does it still start sweeping back and forth? What about if you attach it and issue it one and only one move command?

    • iain says:

      Ok, I think I agree with possessed! I will try making a short video showing what’s happening and put the link up.
      I just tried uploading the blink sketch, works fine, i can alter delays and see the difference.
      I then uploaded this:

      #include “Servo8Bit.h”
      Servo8Bit myServo;
      void setup()
      {
      myServo.attach(0); //attach the servo to pin PB1
      }
      void loop()
      {
      }

      and it makes the servo do the sweep thing again! ? !

  32. iain says:

    here is a link to a video showing the problem!

    http://www.youtube.com/watch?v=h00HUi6iynU

    • iain says:

      Problem solved!

      I looked in the Servo8bit library and deleted the ‘example.cpp’ file, now everything works perfectly!

      Thanks for all your help Ilya!

  33. ilya says:

    Awesome! Glad you got it working. I’m surprised that didn’t give you a compiler error. If it helps you out any more, here’s an old thing I noticed from your video. It’s hard to make out, but it looks like you are plugging in the servo PWM signal into pin PB1. Which is weird cause in your code you ‘attach’ the servo to pin PB0.

  34. cliff says:

    Ok I can’t get this to even compile let alone load on my attiny85.

    C:\arduino-1.0-windows\arduino-0022\hardware\arduino\cores\arduino\pins_arduino.c:362: error: ‘DDRC’ undeclared here (not in a function)
    C:\arduino-1.0-windows\arduino-0022\hardware\arduino\cores\arduino\pins_arduino.c:363: error: ‘DDRD’ undeclared here (not in a function)
    C:\arduino-1.0-windows\arduino-0022\hardware\arduino\cores\arduino\pins_arduino.c:370: error: ‘PORTC’ undeclared here (not in a function)
    C:\arduino-1.0-windows\arduino-0022\hardware\arduino\cores\arduino\pins_arduino.c:370: error: initializer element is not constant
    C:\arduino-1.0-windows\arduino-0022\hardware\arduino\cores\arduino\pins_arduino.c:370: error: (near initialization for ‘port_to_output_PGM[3]’)
    C:\arduino-1.0-windows\arduino-0022\hardware\arduino\cores\arduino\pins_arduino.c:371: error: ‘PORTD’ undeclared here (not in a function)
    C:\arduino-1.0-windows\arduino-0022\hardware\arduino\cores\arduino\pins_arduino.c:371: error: initializer element is not constant
    C:\arduino-1.0-windows\arduino-0022\hardware\arduino\cores\arduino\pins_arduino.c:371: error: (near initialization for ‘port_to_output_PGM[4]’)
    C:\arduino-1.0-windows\arduino-0022\hardware\arduino\cores\arduino\pins_arduino.c:378: error: ‘PINC’ undeclared here (not in a function)
    C:\arduino-1.0-windows\arduino-0022\hardware\arduino\cores\arduino\pins_arduino.c:378: error: initializer element is not constant
    C:\arduino-1.0-windows\arduino-0022\hardware\arduino\cores\arduino\pins_arduino.c:378: error: (near initialization for ‘port_to_input_PGM[3]’)
    C:\arduino-1.0-windows\arduino-0022\hardware\arduino\cores\arduino\pins_arduino.c:379: error: ‘PIND’ undeclared here (not in a function)
    C:\arduino-1.0-windows\arduino-0022\hardware\arduino\cores\arduino\pins_arduino.c:379: error: initializer element is not constant
    C:\arduino-1.0-windows\arduino-0022\hardware\arduino\cores\arduino\pins_arduino.c:379: error: (near initialization for ‘port_to_input_PGM[4]’)

    I started with version 1 then tried 23 and then this is the error I get with 22. 22 seemed to load the example the best.

    I’m missing a fundamental step somewhere. I’m not compiling and loading just trying to compile.

    Thanks

  35. Wayne Holder says:

    It seems like your library should work fine with the ATTiny 24/44/84 series, at least with the pins on PORTB. Have you tried this?

    • ilya says:

      I’ve never used any of the chips from the ATTiny 24/44/84 series. For some reason I always just use Atmega328’s and Attiny85’s for my projects. A lot of the ATTinys from different series share very similar architecture. It can very well be possible that my servo library works on a lot of them. You’re certainly welcomed to try it out, and then come back and write about your findings. =D

  36. Z says:

    Brilliant, beautiful code and always nice to be able to make the most out of those old 8 bit, 8 pin controllers.
    Once I figured out my sporadic servo movement was due to power supply issues, it worked like a charm for the miniature railroad crossing I just built for my son’s 3rd birthday.
    Thanks!

  37. JOhn says:

    How can i include this header in codevision avr ?

  38. JOhn says:

    How can i use this library in codeision AVR

  39. […] more involved method, the “Cunning Turtle” team has a servo library that seems to control a servo with the ATtiny45/85 quite well.  Again, I haven’t tried this method, so you’re on your own here.  As for […]

  40. Paulo says:

    Does your Servo8Bit library will run a servo motor with potentiometer control? I did try and it don’t work well. I use Arduino 0023 version and some times Arduino 1.0.1. The ATtiny85 don’t work with Servo.h library using the sketch Knob. Please, reply to my e-mail address. Thanks.

    • ilya says:

      Yep, it should work well with potentiometer control. Try running this example code, it might help you find the problem:
      http://www.cunningturtle.com/wordpress/wp-content/uploads/2011/11/servo8bit_arduino_example.zip
      This example code is a bit simpler than the sketch knob code, and it should work just fine. If it doesn’t, let me know.

    • Paulo Cherem says:

      Well, Your suggested code does not have the potentiometer. The code just sweep the servo. I need a code similar to the example Knob.ino in Arduino library 1.0, but it can be used in ATtiny85. The ‘map’ function is not understood by ATtiny85. I hope that I have explained properly. Thanks.

    • ilya says:

      The code I linked you to is just test code. It is code that is confirmed to work with arduino. You can use it as a starting point to debug your code, that I assume is using a potentiometer. I have not followed the Arudino development for over a year now. I’ll try to set some time aside this week and test out my Servo8Bit library with the latest Arduino stuff to verify that everything still works.

  41. Martin says:

    I am having some trouble getting my servo to stop rotating.

    I am using the Arduino IDE 1.0 with the MIT HLT ATTiny libraries and a Fitec Continuous Rotation Servo.

    The servo reacts well to my inputs and functions smoothly except that it still rotates when I ‘write(90)’ to stop it. While I don’t understand this (pulse length issues?), I thought I could just use a workaround by calling the detach() function. However when I call

    myServo.detach(1); //detach the servo on pin PB1

    the compiler returns:
    “no matching function for call to Servo8Bit::detach(int)

    servotest:32: error: no matching function for call to ‘Servo8Bit::detach(int)’
    C:\Users\jhgjhg\Documents\Arduino\libraries\Servo8Bit/Servo8Bit.h:63: note: candidates are: void Servo8Bit::detach()

    I take this to mean that I shouldn’t put anything in the brackets, however leaving that blank doesn’t stop the servo either.

    I am very new to this and I really appreciate any help you could provide.

    Thanks,

    Martin

    • ilya says:

      There is a bug in the detach() function that prevented it from working correctly. I uploaded a fix for it about an hour ago. Download the code from github again to get the latest version that has the fix in it.

      The way you tried to call detach() the first time was the correct way to call it. Like this: “myServo.detach();”. With nothing placed in the parentheses.

      With a continuous rotation servo you have to tune your code to find its center. Otherwise the servo will still slowly rotate when you call “myServo.write(90);”

      Try out using
      myServo.writeMicroseconds(1500); // set servo to mid-point

      The number 1500 microseconds is the same as 90 degrees, but offers you more precise control. Try to vary this number a little bit to find the value that gets your servos to stand still. For example, try 1505, 1510, 1495, 1490, and others.

      Also, see http://arduino.cc/en/Reference/ServoWriteMicroseconds

  42. Martin says:

    ilya, Thank you so much for the quick reply and update!

    I have tried the update, however this causes the servo to be completely unresponsive despite having the same code.

    The old version of the library works as it did before however I have noticed another possible bug.

    When I include the library in my code my ‘blink’ style test routine does not run, including reading the button. When I comment out everything Servo8Bit related it functions perfectly, including button read.

    Could it be that the HLT files and the Servo8Bit library play with he pins differently?

    • ilya says:

      I tried using just the servo8bit stuff and it works in arudino. I then appended code to that file to make an LED blink and doing that stopped the servo from moving. Though the LED did blink just fine. From that point on I wasn’t able to get my attiny85 to control the servo at all. Even when I got rid of the arduino stuff and went back to the original make file. Something weird is going on. I don’t have any answers for you right now. It’s going to take me a while to debug this.

  43. Martin says:

    Ilya, thanks again for the quick reply.
    I am gonna futz with it some more tonight and see if I cant find find out more about how its breaking. I wish I could code so I could help out more but at-least for now I can try to bang my head against the wall constructively.

    -Martin

  44. Kaysee says:

    Hi Ilya. First of all thanks for sharing this library. I’m a newb in arduino and lately having interest in attiny45/85. I’ve been looking for a way to drive a servo using attiny and i found your post.

    I’ve setup my Arduino IDE to work with attiny using the latest cores for arduino 1.0 from https://code.google.com/p/arduino-tiny/ and download your Servo8Bit.h to my Arduino libraries folder.

    My first test with the blink sketch prove to be successful thus telling me the attiny cores are a ok. Then i try the servo sweep sketch after changing the #include and pin number and set the board to Attiny85 @8Mhz (internal oscillator; BOD disable).

    I cant get the servo to work. Seems like theres no output on the pwm pin that i used. I’ve tried changing the pwm pin with no success.

    Where did i do wrong. Help!

    • Kaysee says:

      I’m getting this error once uploaded the servo sketch. I know i can ignore the first two lines, but the error after that can it be the problem?

      Binary sketch size: 1,918 bytes (of a 8,192 byte maximum)
      avrdude: please define PAGEL and BS2 signals in the configuration file for part ATtiny85
      avrdude: please define PAGEL and BS2 signals in the configuration file for part ATtiny85
      avrdude: verification error, first mismatch at byte 0x0000
      0x10 != 0x00
      avrdude: verification error; content mismatch

  45. Chad says:

    I’ve been playing with this for a while now and can’t get it to sweep. It will only output a single pulse width. Originally, it was pulsing a 500us pulse every 20ms. I changed myservo.attach to include the max and min range of 1000, 2000. That increased the pulse length to about 580ms. It still isn’t sweeping. I think the pulse is working fine, but I can’t seem the find the problem with the while loop. Any suggestions?

  46. Cosmin says:

    Hi, I have tried this library, form arduino IDE it works ok but when I write for example myServo.write(80); and nothing else the servo makes small steps like it is unstable. I use the internal 8mhz clock.I see that there is an fix for the detach function in version 0.7 but could you please apply it to the arduino version too ?
    thank you,
    regards
    Cosmin

    • ilya says:

      Hi Cosmin,
      Thank you trying out this library with the arduino IDE. From what I hear the library does not work well in that scenario. This is something I wanted to investigate for a while now but I’ve had no time to work on. It’s on my todo list of things to fix.
      Ilya

  47. erwin says:

    why do u use int main() and not void setup() and void loop() ?

  48. Iván says:

    Hi!, could you tell me how to join the attiny and the pc with usb? I use to upload the sketches from arduino as ISP and don’t know how do without it.

  49. ivan says:

    Hello,

    I cant upload any sketch with your library into my attiny85 with arduino as ISP

    could you help me to fill up the makefile? where can I find how to refer to my port?
    and the directory of my arduino is too long, it gives me an error when compiling and if i dont pur nothing it compiles but I can’t upload…
    I dont know what to do! thank you very much


Leave a Reply

Your email address will not be published.