PWMServo

Arduino 0016 introduced a spanking new Servo library that makes it possible to control a Servo from any pin. The old library used PWM, which limited its use to pins 9 or 10.

Unfortunately, the new library uses an interrupt-based technology which breaks NewSoftSerial. If you’re building a project that needs Servo and Soft serial, you might try this library instead. (I didn’t write it; this is really just the old library renamed.)

[August, 2011 update]
Paul Stoffregen recently updated the library to include support for Teensy, Teensy++, Sanguino, and the Mega varieties and Arduino 1.xx.  This is really a nice and much appreciated improvement. Because of the additional timers that the Mega and Teensy processors provide, these platforms can support a third simultaneous servo.

Thanks Paul!

The pins that are available for controller servos vary from controller to controller, so here’s a tidy table showing you which pins are available:

Board                     SERVO_PIN_A   SERVO_PIN_B   SERVO_PIN_C
-----                     -----------   -----------   -----------
Arduino Uno, Duemilanove       9            10          (none)
Arduino Mega                  11            12            13
Sanguino                      13            12          (none)
Teensy 1.0                    17            18            15
Teensy 2.0                    14            15             4
Teensy++ 1.0 or 2.0           25            26            27

Download

Download the original PWMServo library (as it was shipped with pre-0016 Arduino). (This is useful mostly only for historical reasons.)
Download Paul’s version 2 library with Teensy, Teensy++, Mega, and Sanguino support. This version also supports Arduino 1.xx.

Mikal

Page last updated on October 15, 2012 at 9:30 am
37 Responses → “PWMServo”

  1. Kevin

    13 years ago

    Mikal,
    Can you explain how the old PWM works? If it isn’t interrupt based is it reliable? Are there any reasons to not use it?
    I am trying to use it in a very simple example sketch to drive an RC car through and ESC and it is very erratic. I can’t seem to identify what the RC car needs to drive it reliably. I can get the wheels to turn but not in a controllable, methodical way. I learned that this library doesn’t have the writeMicroseconds method available.
    Your thoughts?


  2. Mikal

    13 years ago

    Kevin,

    The old servo library is very reliable. It coexists with other libraries like tone and NewSoftSerial a lot better. The only drawback is that it only supports a total of 2 servos and these must be on pins 9 and 10.

    Mikal


  3. Desmond

    13 years ago

    desmond,

    Is PWMservo the new or OLD servo library? Because i want to be able to drive a single servo while using newsoftserial.


  4. Mikal

    13 years ago

    PWMServo is the library you want if you want to use NewSoftSerial at the same time.

    Mikal


  5. Desmond

    13 years ago

    Mikal,

    COuld you please tell me where i would find information on this library. Because i need to be able to produce a PWM that i can adjust the duty cycle to drive a normal motor.
    And
    i need to be able to turn a normal motor 90degress in both direction.

    How do i use this library to do that.


  6. Mikal

    13 years ago

    Desmond, this library has (mostly) the same interface as the current Servo library. (See the documentation in arduino.cc for that.) Neither of them will allow you to drive a normal motor. That’s a different technology.

    Mikal


  7. Charles

    12 years ago

    Mikal,

    Is it possible to rework the PWMServo library to work on pins other than 9 and 10? I am working on a project with a duemilanove ATmega328 with a sdmicro shield using pin 10, and I have two servos that I need to control. I also have several serial devices which require the use of newsoftserial.

    Thanks for any help you can offer!

    -Charles


  8. Nikko

    12 years ago

    This library does not seem to have been updated to function with arduino 1.0, can we expect a fix any time soon?


  9. Mikal

    12 years ago

    @Nikko,

    I believe the version 2 PWMServo that Paul Stoffregen built (posted here), works correctly in Arduino 1.0.


  10. Antonio Siqueira

    11 years ago

    Hi,

    I need control 16 servos and use USB/serial port default on Arduino Uno or 2009.

    Can this library help me?

    Thank you,
    AC


  11. Mikal

    11 years ago

    @Antonio,

    No, PWMServo is the old Arduino servo library. It can only support 2 servos and these must live on pin 9 or 10.


  12. Mark Grass

    11 years ago

    I’m trying to use the PWMservo library but the neither of the examples compile. I get the following errors:
    Knob.pde:-1: error: ‘PWMServo’ does not name a type
    Knob.cpp: In function ‘void setup()’:
    Knob.pde:-1: error: ‘myservo’ was not declared in this scope
    Knob.pde:-1: error: ‘SERVO_PIN_A’ was not declared in this scope
    Knob.cpp: In function ‘void loop()’:
    Knob.pde:-1: error: ‘myservo’ was not declared in this scope

    Any idea on what’s wrong?


  13. Mikal

    11 years ago

    @Mark,

    What processor are you trying to compile for? This is pretty old code that probably doesn’t support it.


  14. Lazaros

    11 years ago

    I have the same problem with Mark Grass but instead, I have the issue with SoftwareServo library from http://playground.arduino.cc/ComponentLib/Servo.
    I want to control up to 8 servos with arduino UNO -> ATMEGA328P-PU so I need this functionality for non-PWM pins. Any alternative suggestion?


  15. Ben

    11 years ago

    Hi,
    I need to use only one pin to control a servo but I also need to use every single other PWM pin on my Arduino Uno. The new servo library disables PWM on pins 9 and 10, therefore I am 2 pins short on my project. I tried to use “Paul’s version 2 library”, however whenever I used the attach method onto pin 9, the PWM on pin 10 stopped working. Is their a way to control one servo and to still have PWM capabilities on ALL other PWM capable pins using this library? or is their another way to make it work?


  16. Mikal

    11 years ago

    @Ben,

    I’m sorry to say that I can’t think of a better solution than to migrate to the Mega. Sorry!


  17. aleem

    10 years ago

    hello guys
    i have the same problem , when i attached to the motor driver shield to arduini uno , the easyvr stopped listening to my voices commands .
    and you suggested using PWMServo.h instead of Servo.h but i am using AFMotor.h . is there any other library which offers same flexibility as PWMServor , for motors ???


  18. F6AGV

    9 years ago

    Hi Mikal,
    Best regards from France, with BRAF : Ballons Radioamateurs France
    First ballooning association.
    See also : http://www.radioamateurs-france.com/

    Alan F6AGV – BRAF


  19. Touchstone

    9 years ago

    Getting the following errors when I try and compile:

    C:\Users\Mike\Documents\Arduino\libraries\PWMServo\PWMServo.cpp: In static member function ‘static void PWMServo::seizeTimer1()’:
    C:\Users\Mike\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:40: error: ‘clockCyclesPerMicrosecond’ was not declared in this scope
    C:\Users\Mike\Documents\Arduino\libraries\PWMServo\PWMServo.cpp: In member function ‘uint8_t PWMServo::attach(int, int, int)’:
    C:\Users\Mike\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:72: error: ‘LOW’ was not declared in this scope
    C:\Users\Mike\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:72: error: ‘digitalWrite’ was not declared in this scope
    C:\Users\Mike\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:73: error: ‘OUTPUT’ was not declared in this scope
    C:\Users\Mike\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:73: error: ‘pinMode’ was not declared in this scope
    C:\Users\Mike\Documents\Arduino\libraries\PWMServo\PWMServo.cpp: In member function ‘void PWMServo::detach()’:
    C:\Users\Mike\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:95: error: ‘INPUT’ was not declared in this scope
    C:\Users\Mike\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:95: error: ‘pinMode’ was not declared in this scope
    C:\Users\Mike\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:101: error: ‘INPUT’ was not declared in this scope
    C:\Users\Mike\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:101: error: ‘pinMode’ was not declared in this scope
    C:\Users\Mike\Documents\Arduino\libraries\PWMServo\PWMServo.cpp: In member function ‘void PWMServo::write(int)’:
    C:\Users\Mike\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:118: error: ‘clockCyclesPerMicrosecond’ was not declared in this scope

    Any suggestions?


  20. Mikal

    9 years ago

    @F6AGV, fantastic. Ballooning is FUN!


  21. Mikal

    9 years ago

    @Touchstone, Try rebuilding with a fresh copy of PWMServo and a new version of Arduino. I think there is some kind of version mismatch here.


  22. Michael

    9 years ago

    I am trying to use this with an Arduino Mega and AdaFruit Motorshield v.2 but do not seem to get it working. I am attaching 2 servos to pin 9 and 10 or 11 and 12 but have no response.

    Is there anything I am missing out ?


  23. Paul

    9 years ago

    With the PWMServo_v2 library a simple addition allows it to work nicely with the ATTiny84. Just add the following to PWMServo.h :

    #elif defined(__AVR_ATtiny84__)
    #define SERVO_PIN_A 6
    #define SERVO_PIN_B 5


  24. Torsten

    9 years ago

    Hello, I have the error how Touchstone:

    This report would have more information with
    “Show verbose output during compilation”
    enabled in File > Preferences.
    Arduino: 1.0.6 (Windows 7), Board: “Arduino Uno”
    C:\Users\myuser\Documents\Arduino\libraries\PWMServo\PWMServo.cpp: In static member function ‘static void PWMServo::seizeTimer1()’:
    C:\Users\myuser\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:40: error: ‘clockCyclesPerMicrosecond’ was not declared in this scope
    C:\Users\myuser\Documents\Arduino\libraries\PWMServo\PWMServo.cpp: In member function ‘uint8_t PWMServo::attach(int, int, int)’:
    C:\Users\myuser\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:72: error: ‘LOW’ was not declared in this scope
    C:\Users\myuser\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:72: error: ‘digitalWrite’ was not declared in this scope
    C:\Users\myuser\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:73: error: ‘OUTPUT’ was not declared in this scope
    C:\Users\myuser\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:73: error: ‘pinMode’ was not declared in this scope
    C:\Users\myuser\Documents\Arduino\libraries\PWMServo\PWMServo.cpp: In member function ‘void PWMServo::detach()’:
    C:\Users\myuser\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:95: error: ‘INPUT’ was not declared in this scope
    C:\Users\myuser\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:95: error: ‘pinMode’ was not declared in this scope
    C:\Users\myuser\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:101: error: ‘INPUT’ was not declared in this scope
    C:\Users\myuser\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:101: error: ‘pinMode’ was not declared in this scope
    C:\Users\myuser\Documents\Arduino\libraries\PWMServo\PWMServo.cpp: In member function ‘void PWMServo::write(int)’:
    C:\Users\myuser\Documents\Arduino\libraries\PWMServo\PWMServo.cpp:118: error: ‘clockCyclesPerMicrosecond’ was not declared in this scope

    I use the newest version of PWMServo.

    Please help.

    Regards Torsten


  25. Mikal

    9 years ago

    @Paul, hey, thanks!


  26. Mikal

    9 years ago

    @Torsten, is your library installed correctly? That compiles just fine in Arduino 1.0.6 on my Windows 7 box.


  27. Titus

    9 years ago

    After a few years of being idle, I am back on working on my own Reverse Geocache. However, Arduino has changed a lot since than and I have upgraded to a PC running Windows 8.1. I was working with Arduino 18 or so back then on a XP machine. I had trouble with servo stability.

    Starting over with: reverse_geocache_sample_for_rev_2_shield.ino
    Sample Arduino Puzzle Box sketch Written by Mikal Hart and downloaded from Sundial.

    I downloaded the Version 2 PWMServo Library from this site and when I attempt to compile my sketch it is looking for a wiring.h file. apparently from searching the Internet, things have changed since this library was created.

    Exact error:

    Arduino: 1.6.1 (Windows 8.1), Board: “Arduino Uno”

    C:\Program Files (x86)\Arduino\libraries\PWMServo\PWMServo.cpp:2:20: fatal error: wiring.h: No such file or directory

    #include
    ^
    compilation terminated.

    Error compiling.

    =====

    Where do I go from here?

    Titus


  28. Titus

    9 years ago

    Never mind on my post a couple of days ago. For some reason I had the wrong version of PWMServo installed. Went through it again and the sketch now compiles.


  29. Jason

    8 years ago

    Thank you. Thank you. Thank you.


  30. Mikal

    8 years ago

    :) Thanks @Jason


  31. Alonso

    8 years ago

    I am new at this. I followed all the instructions to the best of my ability, but when it came down to downloading the sketch into the GeoCache box, the following message displayed:

    Arduino: 1.6.4 (Windows 8.1), Board: “Arduino Uno”

    reverse_geocache_sample_for_rev_2_shield.ino:43:22: fatal error: PWMServo.h: No such file or directory
    compilation terminated.
    Error compiling.

    This report would have more information with
    “Show verbose output during compilation”
    enabled in File > Preferences.


  32. Mikal

    8 years ago

    @Alonso, that error indicates that the library has not been installed–or at least not installed correctly.


  33. Fred

    8 years ago

    I have been trying to use the PWMServo (ver 2) on an ATtiny84. I’ve made the suggested changes to PWMServo_v2 for the servo pins but I get no servo movement. Compiles fine. I put a LED on/off at the end of the sweeps example and that seems to indicate code is running. I’ve tried hooking servo to all pins just in case my Attiny core is defining pins differently but no change. Incidentally, the code works just fine on my UNO.l


  34. Mikal

    8 years ago

    @Fred, I’m not sure that PWMServo supports ATtiny84. It makes some very specific assumptions about the processor that I think are not true.


  35. Marius

    7 years ago

    The Servo.Attach function is causing the servo to move for about 30°.
    For the standard Servo.h library I’ve found a solution in the www on how to prevent the servo from a first move (using it for a locking mechanism – and 30 degrees are sufficient to unlock)
    Tried as well:
    servoblau.attach(9, 400, 2400);

    According to h-file it should do
    uint8_t attach(int pinArg, int min, int max);
    // attach to a pin, sets pinMode, returns 0 on failure, won’t
    // position the servo until a subsequent write() happens
    // Only works for 9 and 10.

    Thought the problem might be:
    uint8_t PWMServo::attach(int pinArg, int min, int max)
    {
    //Serial.printf(“attach, pin=%d, min=%d, max=%d\n”, pinArg, min, max);
    if (pinArg = NUM_DIGITAL_PINS) return 0;
    if (!digitalPinHasPWM(pinArg)) return 0;
    pin = pinArg;
    analogWriteFrequency(pin, 50); // default movement????


  36. vakhrymchuk

    6 years ago

    I implemented writeMicroseconds method for PWMServo: https://github.com/vakhrymchuk/PWMServo

1 Trackbacks For This Post
  1. My Proposal Box, Part 3: Software

    [...] the Arduino IDE installed already, click here to download it. You will also need to download the PWMServo library (version 2) and the TinyGPS library written by Mikal Hart. While you are at his site, thank him for [...]

Leave a Reply