Author Topic: Accurate servo control - "Phase and Frequency Correct PWM mode" (ATmega8)  (Read 21529 times)

0 Members and 1 Guest are viewing this topic.

Offline cybcodeTopic starter

  • Jr. Member
  • **
  • Posts: 18
  • Helpful? 0
Hi,

I've just discovered "Phase and Frequency Correct PWM mode" and I'd like to share it with those who don't already know it. I've searched the forums and I don't think this has been posted before.
If I understood correctly, it's the best way to control 1 or 2 servos. It's much more precise than delay_cycles and more comfortable because it doesn't take any CPU time.

This is what you have to do (will work only with ATmega8 running at 1MHz):

1. Call the following setup function before entering the main loop (before the while(1) in main()):

Code: [Select]
void run_servos_pwm()
{
// Set PB1 and PB2 as outputs
DDRB |= (1 << 1) | (1 << 2);

// Ask for 50Hz (20ms) PWM signal (ms count should be halved)
ICR1 = 20000/2 ;

// Center both servos
OCR1A = 1500/2 ;
OCR1B = 1500/2 ;

// Ask for non-inverted PWM on OC1A and OC1B
TCCR1A = (1 << COM1A1) | (1 << COM1B1);

// Configure timer 1 for Phase and Frequency Correct PWM mode, with no prescaling
TCCR1B = (1 << WGM13) | (1 << CS10);
}

2. When you want to set a servo's position/speed somewhere in the main loop, use the following macros, instead of servo_left() and servo_right():

Code: [Select]
#define SERVO_PWM_LEFT(_us)    OCR1A=_us/2
#define SERVO_PWM_RIGHT(_us)   OCR1B=_us/2

(the valid range for the PWM signal's width is 900us to 2100us with 1500us at the center, according to Hitec's documentation)

or just do

Code: [Select]
OCR1A = integer_between_450_and_1050 ; //for the left servo
OCR1B = integer_between_450_and_1050 ; //for the right servo

3. Instead of connecting the signal wires of the servos to pins 2 and 3, connect the left one to pin 15 (PB1, bottom right) and the right one to pin 16 (PB2, right above PB1).

My servos move much more smoothly this way, and the resolution is much better (450-1050 instead of 21-49). This should be particularly useful if you use fuzzy logic to set the positions/speeds.

Note: setting OCR1A and OCR1B takes no CPU time, unlike servo_left() and servo_right(). This may affect your program's timing.

Here's a page that helped me understand this stuff:
http://mil.ufl.edu/~achamber/servoPWMfaq.html
« Last Edit: August 25, 2007, 06:17:02 PM by cybcode »

Offline reefat

  • Full Member
  • ***
  • Posts: 61
  • Helpful? 0
    • Reefat's Robotics Blog
Re: Accurate servo control - "Phase and Frequency Correct PWM mode" (ATmega8)
« Reply #1 on: September 07, 2008, 11:11:55 AM »
I just used your code and is working fine with 4MHz Crystal too. Even if I take the Cryatal out, it works. I used 900 for left and 2100 for right rotation.

Got a quick question for you. I have a Continuous Rotations servo. How can I use this piece of code to drive that servo? What part should I modify?

Offline Strikeskids

  • Jr. Member
  • **
  • Posts: 19
  • Helpful? 0
    • Strikeskids
Just use 1500 +- 200 (forwards, backwards) as the _us in the code.
Don't take life seriously
Nobody gets out alive anyway.

Offline SmAsH

  • Supreme Robot
  • *****
  • Posts: 3,959
  • Helpful? 75
  • SoR's Locale Electronics Nut.
This topic was dead...
and besides, the standard for servos is 1000, 1500 and 2000
Howdy

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,165
  • Helpful? 111
    • Webbot stuff
I've covered most of this in my PWM tutorial at http://www.societyofrobots.com/member_tutorials/node/228

Incidentally: Phase and Frequency Correct mode is really aimed at DC motors and, although it will still work fine, you can also use Fast PWM mode for servos.
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline Razor Concepts

  • Supreme Robot
  • *****
  • Posts: 1,856
  • Helpful? 53
    • RazorConcepts
Just a question for webbot - what else would need to be changed if it is running at 16mhz?

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,165
  • Helpful? 111
    • Webbot stuff
Do you mean for my member tutorial - or for the code originally posted on this thread?
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline Razor Concepts

  • Supreme Robot
  • *****
  • Posts: 1,856
  • Helpful? 53
    • RazorConcepts
For your member tutorial. I put ICR1 as 39999 and kept the 8mhz prescaler(cs11). Flashed it on my roboduino board but no luck... probably some stupid mistake somewhere.

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,165
  • Helpful? 111
    • Webbot stuff
Its exactly for this kinda scenario that I created my library - (see my signature) - rather than having to come up with different code for different platforms, CPU speed etc etc I created a lib where you could say 'I got a servo on pin xx - please control it with PWM' - and it just does it.

But hey ho - back to the details....

Send me your code and I'll have a look. Roboduino=ATMega168 and F_CPU=16Mhz, right?
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline Razor Concepts

  • Supreme Robot
  • *****
  • Posts: 1,856
  • Helpful? 53
    • RazorConcepts
Yup. Here is the code below.

Offline Chendro

  • Beginner
  • *
  • Posts: 1
  • Helpful? 0
Re: Accurate servo control - "Phase and Frequency Correct PWM mode" (ATmega8)
« Reply #10 on: October 01, 2009, 04:14:28 PM »

Incidentally: Phase and Frequency Correct mode is really aimed at DC motors and, although it will still work fine, you can also use Fast PWM mode for servos.


Phase and frequency correct mode is indeed used for DC motors, but it can also be used for many other applications that require PWM. As far as I know, the main advantage of the phase and frequency corrected PWM is the fact that the pulses are always positioned in the middle of the period. Therefore the signal will be more symmetric, which results in less harmonic distortion in the device you are driving (like a DC motor or some voltage converter coil). For a DC motor this means a decrease in torque ripple, fewer losses due to eddy currents and less stress on the motor magnets (if it has any).

When you are a hobbyist, this might not be the most useful or necessary thing to consider using, but for some more advances control it could be something to look in to. And of course, you can also use it to control servos but they will not benefit from the 'positioned' pulse.

Offline RoboGeek

  • Jr. Member
  • **
  • Posts: 11
  • Helpful? 0
Re: Accurate servo control - "Phase and Frequency Correct PWM mode" (ATmega8)
« Reply #11 on: October 02, 2009, 10:27:43 PM »
Correct, there is no benefit using that mode with RC servos. The analog servo's internal driver chip uses sample and hold based on the HI pulse width only. They are specifically designed to completely tolerant to phasing, to LO period and to frequency, provided the LO period is less than the timeout period.

I did testing of Hitec and Futaba analog servos deliberately introducing large period and frequency errors( +/- 10% and worse) including random jitter per pulse, and it made no noticable difference to servo performance.

The only thing you need to get right is the period of the HI pulse, and to send pulses often enough so it doesn't shut down.

 


Get Your Ad Here

data_list