Go Down

Topic: Help with PWM for controlling servos and speed con (Read 75102 times) previous topic - next topic


Jan 21, 2009, 10:10 pm Last Edit: Jan 21, 2009, 10:13 pm by mem Reason: 1
This question has been asked so many times it really needs a sticky reply.

You should not use the arduino analogWrite PWM function to drive a hobby servo. They do not use PWM and could damage a servo or speed controller. Its confusing because many references do incorrectly use the term PWM in articles about servos.  But hobby servos and speed controllers expect different pulse timings from that provided by analogWrite.  

When controlling a servo, typically the on time of the pulse will be varied from around 1 millisecond to 2 milliseconds with the off time around 20 milliseconds.
   +---+                +---+
   |   |                |   |
   |   |                |   |
   |   |                |   |
---+   +----------------+   +------
 -->   <--1 ms
   <-------- 20 ms ---->

   +------+            +------+
   |      |            |      |
   |      |            |      |
   |      |            |      |
---+      +------------+      +------
 -->      <--2 ms
   <------- 20 ms ----->
This is called Pulse Position Modulation and is not the same as PWM as used in the Arduino analogWrite. PWM (Pulse Width Modulation) varies the ratio of on time to off time to vary the overall signal level and are not suitable for driving a hobby servo.

There are many Arduino libraries that are suitable for driving servos and speed controllers - here are a few of the references:

The servo library included in the Arduino download - can control one or two servos on pins 9 and 10: http://www.arduino.cc/en/Reference/Servo

A servo library that uses timer2 to control up to 8 servos:

A software servo library that can control many servos but a refresh function needs to be called every 20ms or so: http://www.arduino.cc/playground/ComponentLib/Servo

An external board that controls up to 8 servos using serial commands: http://www.pololu.com/catalog/product/207

An external board with hardware servo control and an arduino compatible processor: http://www.sparkfun.com/commerce/product_info.php?products_id=8785


Hello mem,

ServoTimer2 is a good library for controlling 8 servos, however one servo uses one IO pin, more servos may run out of pins.
I'm wondering how to controlling multi-channel servos with shift register 74HC595, just like SSC-32 at http://www.lynxmotion.com/Product.aspx?productID=395&CategoryID=52.
I saw the Description of SSC-32 Operation here:http://www.lynxmotion.com/images/html/proj078a.htm
could you help how to use an ISR to handle pulse outputs and received characters from the UART.


I am just finishing off a variation of my servo timer library to run up to 32 servos on the mega board: http://arduino.cc/en/Main/ArduinoBoardMega

The mega board has 54 i/o pins and four 16 bit timers so it can easily run 32 servos.  The Arduino mega is cheaper than the cost of an SSC-32 and a regular Arduino board.

I will post the new library when I have completed testing.


Mar 28, 2009, 04:19 pm Last Edit: Mar 28, 2009, 04:20 pm by boomii Reason: 1
Yes, the new Mega board is really a exciting board.  And very glad to hear that you also finish a servo timer library for it.
Maybe later I will get one mega board, but currently I still want to use a Atmega168 Arduino board with 74HC595 to control servos for Synchronized, or "Group" moves just like the SSC-32.
I tried your ServoTimer2 library, but I feel the servos are not Synchronized, are they?


Mar 28, 2009, 06:11 pm Last Edit: Mar 28, 2009, 06:29 pm by mem Reason: 1
I tried your ServoTimer2 library, but I feel the servos are not Synchronized, are they?

I implement my servo code to pulse each servo sequentially. I am surprised that you could detect any difference in performance between this and implementations that pulse all the servos at the same time. Is the difference something you have seen yourself or have you read about this somewhere?


Mar 29, 2009, 08:35 am Last Edit: Mar 29, 2009, 08:36 am by boomii Reason: 1
Yes, you are right. It seems only microseconds from servo Channel 1 to 8, even 32 channels should also not be detected.

I am not very familar with how to use ISR, have read your code again and again. try to replace digitalWrite() with shiftOut() of your ISR code to pluse the 74HC595 outputs to control muti-chanel servos, not sure is it a right method?


A new library called   MegaServo has been added to the plaground. This has many advantages over ServoTimer2, it allows an Arduino board to control one to twelve RC (hobby) servo motors on any digital pin on a standard Arduino board or up to 48 servos on an Arduino Mega. The library is a superset of the Arduino servo library. It can be used just like that library and has the following additional features:
- Controls up to 48 servos (Arduino Mega only, other boards support up to 12 servos)
- Any digital pin can be used with any servo
- Pulse widths can be written and read in degrees or microseconds.

MegaServo does use timer1 on a standard Arduino board so you may still need to use ServoTimer2 if you need timer1 for other functions (such as the  servo decode library)


Jul 07, 2009, 08:08 pm Last Edit: Jul 07, 2009, 08:10 pm by junkiedogg Reason: 1
Would it be possible to .. send the data to generated from MegaServo or that to be sent to one of the servo controller boards from Polulu, to an RF module or maybe an Xbee module. Then to decode this data at the other end to control the Servos?

Like this

Arduino -> (signal for polulu board) -> xbee -----------
--------------- xbee -> arduino -> polulu board -> servos

Easier R/C ?


Jul 07, 2009, 08:31 pm Last Edit: Jul 07, 2009, 08:35 pm by mem Reason: 1
junkiedogg, your question probably deserves a new thread. What you want to do is possible but how best to do it depends on your application.

This thread is here to help people that are confused by  terms like PWM, and are not sure how this relates to servos and analogWrite.

Why not start a new thread with a title that communicates what kind of help you are looking for.
Perhaps something like:  help wanted controlling polulu board wirelessly through xbee

Or of the pololu is not an essential part of your application:  help wanted controlling servos wirelessly through xbee.

In the thread you can say more about what you want to build.


Hello guys,

I have two motors and I bought two speed controller boards:( http://secure.oatleyelectronics.com/files/K243notes.pdf ).   How can I make my arduino control the speed and direction of my DC motor using this controller I bought? What libraries do you suggest?
Your reply would be greatly appreciated



Aug 09, 2010, 09:02 am Last Edit: Aug 09, 2010, 09:04 am by mem Reason: 1
Hi Erac,
The Servo library that comes with Arduino should drive that controller. The document linked in your post doesn't explicitly say, but values written to the servo library should increase or decrease motor speed as the values deviate from 90.

You can test it with the knob example sketch for the servo library. Connect the motor as per the information in the doc you linked. Connect the SIG line to Arduino pin 9 and the Ground line to arduino Gnd. If you connect a variable resistor (There is an online tutorial for this if you need help) you should be able to adjust the speed by adjusting the resistor.

If you add a serial.print statement in the sketch to display the value being  written to the servo you can confirm the association between the values and motor speed.

Have fun!


Thanks mem!

I will do it and updated you.  Why is have to be on pin 9 of the arduino?



The example sketch uses pin 9 but you can change it to any unused digital pin if you want. The current Servo library can work with any digital pin.


Thanks, mem

You said that: " If you connect a variable resistor (There is an online tutorial for this if you need help) you should be able to adjust the speed by adjusting the resistor."

So I still need a potentiometer to adjust the speed? What if I want it all done by my arduino through PPM.. What do you suggest..

I should NOT use analalog.write correct?

My application: K243 motor controller attached to arduino so that arduino with 1-2ms pulses control the motor through the K243. In a way mimmcing RC servo signals.



Sep 03, 2010, 08:17 am Last Edit: Sep 03, 2010, 08:20 am by mpeuser Reason: 1
(a) No - it's an example, duh!
(b) Yes - the pulses are digital.
(c) Yes -  But I should say "generate" not "mimic"

Go Up