Servo Control. Again?
SRLM
Posts: 5,045
I might not be looking in the right place, but I haven't found any simple servo control routines. The Obex stuff has either assembly or a bunch of extra features (ramping, position feedback, etc.) and I couldn't find what I'm looking for on the forums or the PE labs, so I set out to modify some code that I found. Its from the TestDualPWM (Project 2).spin·file from the counters lab.
I took out my trusty Parallax oscilloscope, and found that to change the pulse width I need to change the first constant in the repeat loop. Thats the pulse width in us. What I'm wondering is, why? Also, what is tC, tHa, and t?
Finally, is there a simpler way without the loop? I think there must be, but what? PhiPi posted this snippet of code here, but it may be even more confusing than the previous.
PUB TestPwm | tc, tHa, t, us ' <- Add us us := clkfreq/1_000_000 ' <- Add ctra[noparse][[/noparse]30..26] := %00100 ' Counters A and B → NCO single-ended ctra[noparse][[/noparse]8..0] := 13 ' Set pins for counters to control frqa := 1 ' Add 1 to phs with each clock tick dira[noparse][[/noparse]13] := 1 ' Set I/O pins to output tC := 20_000 * us ' <- Change Set up cycle time tHa := 700 * us ' <- Change Set up high times t := cnt ' Mark current time. repeat tHa from (1200 * us) to (2200 * us) ' <- Change Repeat PWM signal ' First pair of pulses ctra[noparse][[/noparse]8..0] := 13 ' Set pins for counters to control phsa := -tHa ' Define and start the A pulse waitcnt(2200 * us + cnt) ' Wait for pulses to finish ' Wait for 20 ms cycle to complete before repeating loop t += tC ' Calculate next cycle repeat waitcnt(t) ' Wait for next cycle
I took out my trusty Parallax oscilloscope, and found that to change the pulse width I need to change the first constant in the repeat loop. Thats the pulse width in us. What I'm wondering is, why? Also, what is tC, tHa, and t?
Finally, is there a simpler way without the loop? I think there must be, but what? PhiPi posted this snippet of code here, but it may be even more confusing than the previous.
dira[noparse][[/noparse]EscPin]~~ Time0 = clk repeat 50 waitcnt(Time0 += clkfreq / 50) outa[noparse][[/noparse]EscPin]~~ waitcnt(Time0 + Pulse * clkfreq / 1_000_000) outa[noparse][[/noparse]EscPin]~
Comments
swingServoPin is a long that is set to 13 (my pin for servo). swingServo is the length (put to 750 for testing) of the pulse in ms. Yet my scope still shows a flat line, even though I know that it is running the function (courtesy of the debug). It can't get much simpler, yet here I am.
The repeat is there because the original routine was written for 3 servos. You're only using a single servo.
Remove the repeat (and the indenting that goes with it). Also remove the debug statement.
The servo pulse width is in microseconds. You should use 1500 for testing.
Anyway, here's the code that I think I'll end up with.
For the moment, I have it sending out pulses (defined earlier: 1700, 1500, 1500) to pins, then waiting for the remaining time to make it 20 ms between pulses. I also moved the uS definition to global. For my final program, I'll only repeat this loop two or three times.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.