View Single Post
  #13   Spotlight this post!  
Unread 21-01-2007, 16:31
Kevin Watson's Avatar
Kevin Watson Kevin Watson is offline
La Caņada High School
FRC #2429
Team Role: Mentor
 
Join Date: Jan 2002
Rookie Year: 2001
Location: La Caņada, California
Posts: 1,335
Kevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond repute
Re: PWM 13-16 Replacement Code

IMHO, one of the nice things about this software is the ability to define how the PWM range of 0-255 maps to the servo position range. So for fun, I decided that I'd like to wring-out as much pointing accuracy from my camera's tilt mechanism by mapping the entire 0-255 PWM range to the more useful 0 to 90 degree tilt range. These are the steps I took:

1) Moved the tilt PWM from PWM output 2 to 16. This is necessary because PWM() can only contol PWM outputs 13 through 16.

2) The first piece of information I needed was to find the PWM pulse width that caused the servo to rotate the camera to the 90 degree position. Using the camera software's interactive PWM adjustment menu to command the tilt mechanism to rotate the lens up, I found that the default gain of 5.0 us per PWM step wasn't high enough to rotate the camera to the 90 degree position. I opened up pwm.h and increased to gain on PWM output 16 to a value of 70 for a pulse step size of 7.0 us. I re-compiled and downloaded the code to the RC and found that I could command the servo to 90 degrees with a PWM value of 254. Using the inverse of the algorithm from PWM(), I calculated that PWM() was sending a PWM pulse width of 2.389 ms.

3) Using the same technique described above, I determined the pulse width I needed to send for 0 degrees to be 1.479 ms.

4) I then calculated the pulse width range that I needed to cover by subtracting the result of #2 from #3 for a range of 0.910 ms.

5) To calculate the gain, I just divided the pulse range needed by the available PWM range of 256 for a gain of 36 or 3.6 us per PWM step. This is the gain value that is needed to limit the range of servo motion to 90 degrees.

6) I now needed to calculate a new center point for the servo. If I leave it at 1.5 ms, the servo will rotate through a 90 degree range, but it will be -45 degrees to 45 degrees. I needed to change the center point to +45 degrees so the servo will rotate from 0 to 90 degrees. To calculate the new center point, I just divided the range (from #4) by 2 and added that to the 0 degree pulse width (from #3) for a value of 19340 (or 1.934 ms).

7) Plugging the values from #5 and #6 into pwm.h, re-compiling, loading the RC, and then testing, I found the range to be the desired 0 to 90 degree range!

8) I then changed the PWM value to angle code in terminal.c from:

printf("Tilt Angle (degrees) = %d\r\n", (((int)TILT_SERVO - 144) * 25)/50);

to:

printf("Tilt Angle (degrees) = %d\r\n", ((int)TILT_SERVO * 90)/250);

9) The tilt gain was then changed from 8 to 4 for faster tracking.

10) Because I now have better pointing ability, I was also able to change the TILT_ALLOWABLE_ERROR_DEFAULT value to 3 pixels.

11) Finally, I changed the min tilt PWM value to 0, the maximum to 250 (255 is a degree or two past 90), adjusted the mid-point to 50.

This new found pointing accuracy might come in handy if you're using the green tracking light for navigation.

-Kevin
__________________
Kevin Watson
Engineer at stealth-mode startup
http://kevin.org