View Full Version : PropBasic Counters & Servos
10-25-2011, 02:24 AM
i am trying to emulate JonnyMacs neat way of driving multiple servos with the system counter (jm_servo8_adv.spin) in PropBasic. Here is what i came up with so far, and it "kind of" works, but there is no real tourqe on the servo turn, and it chatters like a mofo when it gets to the target location.
i suspect my math for the timing is off, does anything see anything wrong with this?
thanks in advance!
10-25-2011, 03:06 AM
Which version of the compiler are you using? With 1.14 stuff like 2500 * us001 gets mistranslated. BTW, us001 should be 80 not 5 for your setup. The code generated is (us001 == 80):
mov tmp,_2500 ' tmp = 2500 * us001
This basically messes up your timing.
10-25-2011, 03:19 AM
thanks for the heads up kuroneko, ill try that when i get back to the the compiler. im using v1.25
10-25-2011, 03:25 AM
Do you have a link for 1.25?
10-25-2011, 03:38 AM
from this post:
10-25-2011, 03:57 AM
Thanks, but that doesn't generate any output for me (1.14 generates 2 SPIN files). I tried two different machines (XP and Vista, JPN) and both come up empty. Anyway, if you can find a way to inspect the generated code have a look at the 2500 * us001 line.
10-25-2011, 04:18 AM
odd, are you using bst? i don't think this version will work as it doesn't have the hooks, its straight from Bean. ive been using viewport and cedit to compile with this version.
10-25-2011, 04:23 AM
odd, are you using bst?
Initially I used it from the command line (which works for the 1.14 release). Then I tried bst and it died (as expected). Maybe it's tied to viewport in a way and requires a specific environment. Beats me.
So in order to check if the same bug is still present you could multiply by 80 manually (*5*16):
tmp = pos << 2 ' *4
tmp = tmp + pos ' *5
tmp = tmp << 4 ' *80
And the other location could just load 200000 (2500*80) directly.
10-25-2011, 04:39 AM
ha i just realized i based all my math on 5mhz instead of 80, i guess i just had the crystal value stuck in my head! still playing around so far.
here is what is generated:
mov tmp,_2500 ' tmp = 2500 * us001
10-25-2011, 05:24 AM
Just remembered something re: multiply with constants (outstanding bug). When you move us001 into a variable first then it should generate proper multiply code, e.g.
tmp = us001
tmp = pos * tmp
10-25-2011, 07:28 PM
got the task timing all the servos now! il post up the rest once i have time to get the subs done, thanks!
' ----- TASK Variables (LONG only) ------------------------------------
us001 con 80 '5 '80_000_000 / 1_000_000 tick per microsecond
so con 18 'servo offset start at pin 18
idx var long
outpin var long
slot var long
pos var long
tgt var long
dlt var long
tmp VAR long
' ----- SUB and FUNC Definitions ---------------------------------------
'(2^32)/clkfreq = 4294967296/80_000_000 = 53.6870912
'clkfreq=80_000_000 53.6870912 * 65536 = 3518437.2088832
frqa = 1 'preset for counter
phsa = 0
slot = cnt
for idx = 0 to 7
rdlong position(idx), pos 'get chanel position value
rdlong target(idx), tgt 'get channel target value
rdlong delta(idx), dlt 'get speed value
outpin = idx + so 'set servo pin via offset
COUNTERA 32,outpin 'start counter
tmp = pos * us001
phsa = -tmp
if pos < tgt then 'is pos less the taget pos?
pos = pos + dlt
pos = pos max tgt
elseif pos > tgt then
pos = pos - dlt
pos = pos min tgt
tmp = 2500 * us001 'slot timing
slot = slot + tmp
WAITCNT slot 'wait for slot to finish
ctra = 0
wrlong position(idx), pos 'put channel poition value
goto srvmain 'loop
11-12-2011, 05:29 PM
here is what i ended up with. it seems to work rather well except for one bug i can't seem to figure out.
if you the first set_servo you use has a speed other then 0, the servo will swing all the way to the srvmin pos at full speed, then will turn to the requested position at the requested speed. i got around it by just initiating all the servos with no speed control when i start the program.
special thanks to bean, jonnymac, and parallax.
if ya make it better please share!