Servo problems
Dave Haldane
Posts: 2
I'm incredibly new to the spin language, but I've already gotten myself in deep: I've got 2 weeks to get an r/c project working.
Anyways, after slapping the chip in my PDB, I decided to write a bit of servo code, to see if it works. I've got experience in BS2 programming, but I was having trouble getting the library to work for me, so decided I'd give it a whack just using some basic Spin language.
Here's the code:
The result of the code was the servo bouncing off one limit until *bad click* (It didn't take much bouncing). I tried a couple variations, but couldn't ever manage to get the servo to behave like I meant it to (moving from one limit to the other)
When I changed the pause time to 2 seconds, I managed to get the thing to move through 90 degrees of its sweep, not the full 180 I expected.
So I'm taking the servo apart to repair it, and I hope maybe someone out there can help my in the meantime.
Ah, the equipment
Professional development board: Pin 17 wired to servo output 0
http://www.servocity.com/html/hs-635hb_high_torque.html on servo output 0
Any help at all would be appreciated. I wouldn't be surprised if I was implementing PWM incorrectly, mis-treating the servo, or performing various other faux-pas... I'm rather new to this.
Anyways, after slapping the chip in my PDB, I decided to write a bit of servo code, to see if it works. I've got experience in BS2 programming, but I was having trouble getting the library to work for me, so decided I'd give it a whack just using some basic Spin language.
Here's the code:
{{PWM_test.spin}} CON pwidth_high = 28_800 '180 degree pulse time (2400 uSec) pwidth_low = 7_200 '0 degree pulse time (600 uSec) duty = 240_000 '20ms between pulses pause = 6_000_000 ' .5 Sec pause pin = 17 'PWM signal pin High = 1 'High constant Low = 0 'Low constant Out = %1 'Output constant PUB Main dira[noparse][[/noparse]pin] := Out 'Set pin 17 to Output repeat repeat 5 'repeat position signal 5 times outa[noparse][[/noparse]pin] := High 'Set output pin high waitcnt(cnt + pwidth_low) 'Wait for low-end pulsewidth outa[noparse][[/noparse]pin] := Low 'Turn off output pin waitcnt(cnt + duty) 'wait 20ms before repeating signal waitcnt(cnt + pause) 'wait half a second repeat 5 'repeat position signal 5 times outa[noparse][[/noparse]pin] := High 'set output pin to high waitcnt(cnt + pwidth_high) 'send long pulsewidth outa[noparse][[/noparse]pin] := Low 'turn off pin waitcnt(cnt + duty) 'wait 20ms before repeat waitcnt(cnt + pause) 'wait .5 Sec before repeat
The result of the code was the servo bouncing off one limit until *bad click* (It didn't take much bouncing). I tried a couple variations, but couldn't ever manage to get the servo to behave like I meant it to (moving from one limit to the other)
When I changed the pause time to 2 seconds, I managed to get the thing to move through 90 degrees of its sweep, not the full 180 I expected.
So I'm taking the servo apart to repair it, and I hope maybe someone out there can help my in the meantime.
Ah, the equipment
Professional development board: Pin 17 wired to servo output 0
http://www.servocity.com/html/hs-635hb_high_torque.html on servo output 0
Any help at all would be appreciated. I wouldn't be surprised if I was implementing PWM incorrectly, mis-treating the servo, or performing various other faux-pas... I'm rather new to this.
Comments
Servos require constant pulses at 50hz to make them hold. During your pause you aren't sending anything, so if your servo hasn't gotten into position, it'll just stop because it's no longer being told to. If the servo has a relatively slow response time, 5 cycles might not be enough time for a full sweep.
If you're doing this as a programming exercise, great - If not, you're probably better off using the Servo32 object that comes with the Prop libraries. It'll drive up to 32 servos with 1uS resolution, runs on its own cog, is written in ASM, etc. It would probably save you a good deal of time. [noparse]:)[/noparse]
Jason
Yesterday I·posted a reply to the "Using a cog to control a motor" thread and uploaded some programs under the name "RC_Servo_Control" to the Propeller object exchange site that show you some easy ways to control RC servomotors with the Propeller. As Jason said, you should not use the internal oscillator when you need precise timing. I recommend using an 80MHz system clock (the maximum). The professional development board has a 5MHz crystal, so you just have to add the following two lines·to the top of your code to use this external crystal and·get the phase locked loop to multiply its frequency by 16 times to give you 80Mhz.
Also, FYI, because of the way the Propeller executes Spin instructions, you should always add the system counter value (cnt) last (on the right)·when using·the waitcnt instruction (e.g., use "waitcnt(pwidth_low+cnt)") . Otherwise, the cnt value will continue increase as the other value is processed and added,·which will result in·the timing·being off.
The good news is that if you·were using·a Parallax/Futaba Standard Servo with a 5V power supply, then based on my experience, I doubt that you could have done·any serious internal damage to·it with your previous attempts. When you take it apart, you may notice that the white plastic tab on the output shaft (under the servo's horn) may have sheared off a plastic gear tooth. The servo should still work okay though for most applications. If it doesn't work with my demo programs, then you may have burnt out a coil in the DC motor's rotor armature (by·passing too much current through it when the motor was stalled). If this is the case, you'll need a new servomotor.
Check out my post on·this thread...
·http://forums.parallax.com/showthread.php?p=763415
-Gavitron
Thanks a lot for the help. I only lost one servo in a big way to the clock issue. Two others got grumpy, but they're mostly repaired out of parts of the first one (heh heh, frankenservo).
Anyways, the clock change and using the servo32 library helped a lot. Here's the test code I ended up writing.
Thanks everyone!