July 01, 2010 by Ralphxyz 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, Ralph 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!! Rick 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! Humberto 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. Ralph 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. Ralph Ralph, It could be any angle and not just fixed values. Please have a look at this example. The angle could be even 135 degrees. Regards, Raja 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. Rick 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 Ralph