0
\$\begingroup\$

This question already has an answer here:

For reference im using an AVR Atmega 328p, and the servo specs i'll be using says this:

  • Pulse Cycle: 20 ms (I assume this means the "period")
  • Pulse Width: 600-2400 µs

So from my understanding, using fast PWM and lets say a 1Mhz clock. I make the Width by setting 2 values. One when it reaches TOP-whatever width (lets pretend 1800 ms, I think people use ICR1 for this) and then the top (I think they usually use OCR1A here).

So the time between ICR1 and OCR1A (Which is the top) is where I turn the "Pin" to the Servo on correct? And then it turns off when OCR1A ends

IE: Turn on when it reaches ICR1, turn off when it reaches OCR1A. If I want a width of 1.8 ms i'd need to make that 1800 steps correct? Since 1800 "ticks" would be 1.8ms (If Im understanding my units correct)

The pulse cycle is where I get confused. That would just be the "TOP" value right? IE: if I need a 20ms pulse cycle. and every tick at 1MHz is 1/1000 of a milliseconds, so to do 20ms pulse cycle, ill need 20000 ticks. because every tick is 1/1000 of a ms

Am I thinking of this correctly? I think the "Ticks" with the CPU Frequency and then trying to get that figured out with cycles and widths is just sort of throwing me for a loop.

\$\endgroup\$

marked as duplicate by Kurt E. Clothier, Elliot Alderson, Dwayne Reid, RoyC, Bimpelrekkie Dec 18 '18 at 9:21

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1
\$\begingroup\$

Pulse Cycle: 20 ms (I assume this means the "period")

Yes, that's correct. You need to send 1 pulse every 20ms.

Pulse Width: 600-2400 µs

This is more or less also correct although I would note that most RC parts are designed to operate between 1000 and 2000 uS.

What you'll want to do is create a timer that overflows every 20ms. This can be a software or hardware timer.

Then, every time the timer overflows turn the output ON.

Map the timer ticks into uS, and turn the output OFF once the correct number of uS have elapsed. For example, if your timer ticks 2000 times per 20ms, and you want a pulse of 1500uS, then you turn the output off after 150 ticks.

The resulting signal looks like this (note that the angles will vary depending on the servo):

Servo signal image

Most micros will have a PWM timer mode that can do all of this automatically. Take a look at the atmega 328p datasheet, section 16.9.3 "Fast PWM Mode":

The counter counts from BOTTOM to TOP then restarts from BOTTOM. In non-inverting Compare Output mode, the Output Compare (OC1x) is cleared on the compare match between TCNT1 and OCR1x, and set at BOTTOM. In inverting Compare Output mode out put is set on compare match and cleared at BOTTOM.

BOTTOM according to the datasheet just means 0. ..I don't know why they don't just say that. So anyway, what you need to do is set TOP and the timer pre-scaler so that the period is 20ms. Then you need to set OCR1x, to an appropriate fraction of that to get your desired output pulse length. You'll want to use non-inverting compare mode.

Edit: Changed "OC1x" to "OCR1x" in this paragraph. That was a typo, sorry.

There are online calculators that can help you figure out the values for TOP, and the timer pre-scaler.

\$\endgroup\$
  • \$\begingroup\$ This makes more sense, it's just a bit to wrap your head around. I think mechanically it's also confusing to think about. I think my confusion also arose because I was thinking "Why can't I just make it where the TOP is whats needed for the pulse width...but that wouldn't deal with the period length". \$\endgroup\$ – msmith1114 Nov 14 '18 at 20:13

Not the answer you're looking for? Browse other questions tagged or ask your own question.