![]() |
PWM 13-16 Replacement Code
For those who are using interrupts and don't like the jittery PWM outputs on channels 13 through 16, I've written replacement code for IFI's Generate_Pwms() function that uses the built-in CCP hardware to generate super accurate PWM pulses. The code also allows you to set the neutral point and gain for each output channel, giving you complete control of your servos and motors. As an example, this code allows you to map the entire 0-255 PWM range into a small fraction of the normal travel of a servo arm, which would come in handy if you wanted to make a more accurate range calculation to the green light.
I'd like to do a quick beta test to find any bugs or documentation problems before posting it to my web page. If you're interested in helping out, you can download the code here: http://kevin.org/frc/frc_pwm.zip. If you find any problems with code or documentation, please leave a message here. -Kevin Edit: Changed link to point to released code. |
Re: PWM 13-16 Replacement Code Beta Test
Quote:
|
Re: PWM 13-16 Replacement Code Beta Test
So how exactly would this effect the servos controlling the camera? Would it make them move smoother, more accurate?
Looks cool |
Re: PWM 13-16 Replacement Code Beta Test
Is there any reason that you couldn't use "int"s to store your motor speeds and have a greater range of values with the higher precision obtained by using the CCP (that is, instead of using the gain and center #defines)? I looked through the code and don't see why this wouldn't work, what i mean is something like this as a change to the PWM() function:
Code:
void PWM(unsigned int pwm_13, unsigned int pwm_14, unsigned int pwm_15, unsigned int pwm_16) |
Re: PWM 13-16 Replacement Code Beta Test
Quote:
-Kevin |
Re: PWM 13-16 Replacement Code Beta Test
Quote:
Quote:
-Kevin |
Re: PWM 13-16 Replacement Code Beta Test
Looks great. I'll use it tomorrow and post back with results.
|
Re: PWM 13-16 Replacement Code Beta Test
Hey Kevin? Does your code leave a pause between pulses sent from the CCP module? After looking at your code I did not see anything to indicate this. The reason I ask is because I have noticed that when continuous pulses are sent to a servo using the CCP module, the servo exhibits jitter. I have found that a 2ms delay or greater between pulses will stop this behavior. Have you encountered similar behavior?
|
Re: PWM 13-16 Replacement Code Beta Test
Quote:
-Kevin |
Re: PWM 13-16 Replacement Code Beta Test
Quote:
|
Re: PWM 13-16 Replacement Code Beta Test
Quote:
|
Re: PWM 13-16 Replacement Code Beta Test
Quote:
I've already enumerated some other advantages above. Quote:
For grins, I used digital servos (not FRC legal) with my code and after modifying tracking.c a bit, I can find a green light and start tracking in somewhere between one and two seconds, without the software having any a priori knowledge of where the light is located. I suspect nearly the same level of performance can be had with the HS322HD servos. -Kevin |
Re: PWM 13-16 Replacement Code Beta Test
Kevin,
I would expect that the code should work fine. We (1126) used my version throughout the 2006 season without any issues. Your increase in gain from 40 to 50 is probably a good idea, as we found one of the Victors did not quite go to maximum at the high end (2 msec) without recalibration. The additional 25% on range should easily eliminate this potential problem. You may want to think about modifying your "temp_pwm_xx" calculation so it doesn't require the signed int multiplication. This adds a fair amount of execution time to the routine (relative to how quick it could execute, not to overall processor usage which is extremely minor). It also requires the use of the MATH_DATA section so if someone ever wanted to use the routine from within an interrupt (why? I don't know, but I never rule anything out), they would need to save that data section. I do like the addition of the CENTER & GAIN options it allows for much more flexibility. Mike |
Re: PWM 13-16 Replacement Code Beta Test
So... is the legality of this confirmed?
-Adam |
Re: PWM 13-16 Replacement Code Beta Test
Quote:
I used the signed int so that I don't have to worry about underflow when the subtraction takes place. I'll have another look to see if I can move the terms around to get rid of the int. -Kevin |
Re: PWM 13-16 Replacement Code Beta Test
Quote:
-Kevin |
Re: PWM 13-16 Replacement Code Beta Test
Quote:
Also, how did you get around the interrupt-glitch thing? I'm missing something obvious when I look at the code... |
Re: PWM 13-16 Replacement Code Beta Test
Quote:
|
Re: PWM 13-16 Replacement Code Beta Test
Quote:
|
Re: PWM 13-16 Replacement Code Beta Test
Quote:
Edit: Actually, Dave's explanation may be closer to the truth. If the master is capable of generating the PWM output, why do we have the Generate_Pwms() kludge to deal with. Still, the 1.5 ms PWM neutral pulse needs to get generated for safety reasons. If not the master, who? Quote:
-Kevin |
Re: PWM 13-16 Replacement Code Beta Test
Quote:
|
Re: PWM 13-16 Replacement Code Beta Test
Quote:
-Kevin |
Re: PWM 13-16 Replacement Code Beta Test
Quote:
|
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 |
Re: PWM 13-16 Replacement Code
Using the Bells & Whistles camera code, PMWs 13-16 twitch for a moment when data is stored to EEPROM. I can work around it easily, but it's definitely undesired operation.
|
Re: PWM 13-16 Replacement Code
Quote:
-Kevin |
Re: PWM 13-16 Replacement Code
Can I now use the alltimers library and PWMs 13-16 at the same time?
Thanks in advance, Robinson |
Re: PWM 13-16 Replacement Code
Quote:
-Kevin |
Re: PWM 13-16 Replacement Code
Is this feature included in the default 2007 code?
|
Re: PWM 13-16 Replacement Code
It's included in Kevin's camera codes at http://kevin.org/frc/
But it's not in the one you download at IFI (that still uses the old Generate_Pwms() function). |
Re: PWM 13-16 Replacement Code
Quote:
This is great Kevin, but I have always wondered why no one appears to be using the difference of the centroid from the CMUCAM centre pixel to compute angle-to-the-target (azimuth and elevation) instantaneously, rather than 'wasting time' moving the servos until the target is centred and THEN reading out the servo angle. In my scenario - position the camera to a known azimuth and elevation and leave it there. As long as the target is detected by the camera, calculate the offset in pixels between the centroid coordinate and the centre pixel of the camera raster image. By experiment, calibrate the angle that this difference represents on your camera. It doesn't eliminate the need for the pan/tilt servos - because the CMUCAM field of view is only a few tens of degrees - but it should be possible to add this optically-calculated angle to the current servo angles to get an angle relative to the robot itself. Your adjustments to map PWM values to 0-90 degrees would make this a snap. Of course, this method would be useless while the servos are in motion as their precise angle would be unknown until they came to a full stop, although it could be estimated based on servo characteristics. Am I missing something here? |
Re: PWM 13-16 Replacement Code
Quote:
|
| All times are GMT -5. The time now is 20:52. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi