NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Support Forum » Servo Squirter PWM code and PWM code questions in general

July 01, 2010
by Ralphxyz
Ralphxyz's Avatar

At the start of the Servo Squirter Tutorial Humberto (once he stops causing mayhem) draws a horizontal line and says:

"hobby servos typically have a 180˚ range. When you send it a 1 mili second pulse it points in one direction

when you send it 2 milli second pulse it will point in the other direction

when you send it 1.5 milli second pulses it will point right in the middle" please pardon my paraphrase.

Where in the code is 1, 2 or 1.5 milli second set?

It looks to me like 20ms is set not 1, 2 or 1.5. and that 20ms is actually the elapse time of the trip from 0 to Top.

Not the pulse width for direction.

I think the little commented table with 1, 2, 1.5 and 20ms values is misleading.

#define PWM_MIN 1300
#define PWM_MAX 4450
#define PWM_START 2765

Seems to be what sets the direction with uint16_t pos = PWM_START;.

So what about the 1, 2 and 1.5 mile second pulses for servo control?

Of course I do not at the moment have a servo and am using a LED to brighten and dim.

As I can turn the LED off with PWM_MIN = 0000 it really is acting like voltage control

but that is not how a servo works so that just adds to my confusion.

Looking at pwm_set(pos); I see how the PWM_MIN, PWM_MAX and PWM_START values are set

but I just do not see a 1, 2 or 1.5 millisecond pulse.

Thanks for the help,


July 02, 2010
by Rick_S
Rick_S's Avatar

If you look at that code a bit closer, you'll see comments describing what's going on. Reviewing the data sheet along side may help clarify.

Based on my limited knowledge however this is the way I read it.

In the function pwm_init(), the micro-controller is set to use non inverting fast PWM mode.

CS11 is set to 1 which sets the pre-scaling to clock divided by 8 Where OCR1A (Output Control Register 1A) is Set to roll over every 20ms

The formula is desired interval/(1second/(Crystal speed/prescaler))

Or in this case, .02 / (1/(14745600/8))=36864

This estaplishes the maximum duration for the PWM pulse.

Then you set OCR1B to the fraction of time you want the pulse high vs low. In this case, they were looking for a 1 to 2 ms on pulse. To determine this just divide the desired pulse length (1.5ms for example) by the total duration (20ms) and multiply by the value in OCR1A 1.5/20=.075*36864=2764.8.

So if OCR1B is set to 2764.8, the PWM Pulse will be on for 1.5ms off for 18.5ms. Following the examples, if OCR1B is set for 3686.4, the pulse would be on for 2ms off for 18.

Hope that helped clear it up a bit and didn't just add to the confusion.... And hopefully I got it right :D

Any corrections or clarifications would be welcomed!!


July 02, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Ralph,

Thanks for the great explanation Rick. I think the key part to understand here is that to control a servo you need to send a pulse that is somewhere between 1 and 2 milliseconds (to set the position), but you need to only send that about once every 20 milliseconds. Most servos are actually quite forgiving about the period.

So in our code OCR1A is set to be the TOP value of the timer/counter after which it rolls back over to 0 (every 20 milliseconds). The PWM pin will be set high at 0, and stay high until it reaches the value in OCR1B, which when is set somewhere between PWM_MIN and PWM_MAX will be somewhere between 1 and 2 milliseconds.

Hope that clears it up!


July 02, 2010
by Ralphxyz
Ralphxyz's Avatar

Rick thank you, that is such a explicit answer. Now I have to work it through to see if you are correct.

With answers like that I have no excuse to not know exactly what is going on.

Can't wait for my servos to get here so I can actually see them in action.

I am also working through mongo's two servos code as I am sure I will want more than just one.


July 02, 2010
by Ralphxyz
Ralphxyz's Avatar

Humberto, when you say "I think the key part to understand here is that to control a servo you need to send a pulse that is somewhere between 1 and 2 milliseconds (to set the position)," that means the servo position value wil NOT necessarily be 1, 1.5 or 2 but that it can/could be "somewhere in between.

In other words using your 180˚ line from the tutorial Servo left is 1 to <1.5 and Servo right is >1.5 to 2 with center = 1.5.

Thats makes Ricks explanation of the math make sense. I was thinking that the direction values 1 and 2 were hard values, that a direction could only be set by a 1 or a 2 but you are saying a 1.345 would be left as a 1.745 would be right.

If this is so then it makes sense otherwise I am still lost.


July 02, 2010
by rajabalu21
rajabalu21's Avatar


It could be any angle and not just fixed values.

Please have a look at this example. The angle could be even 135 degrees.



July 03, 2010
by Rick_S
Rick_S's Avatar

Yes Ralph, you are on the right track. Also, depending on your servo, you may get even more left/right movement. Once you get the servo and have it connected, it'll illustrate better what those variables do. Sounds like you've pretty much gotten there though.


July 03, 2010
by Ralphxyz
Ralphxyz's Avatar

Raja, thank you so much!!

Duh, sometimes I get thinking so much about these questions I forget to think.

I was stuck on hard left, hard right and center and never considered "angles".

Of course I could blame my lack of perception on the fact I do not have a servo or ever played around with one, but I really should have seen angles.

Rick, yup your math works :-) thanks again for the great explanation and again thanks to Humberto and Raja.

So here is another suggestion for a nerdkit grab bag, throw in a couple of servos. I would have bought one a long time ago


Post a Reply

Please log in to post a reply.

Did you know that you can control multiple LEDs from one microcontroller output? Learn more...