Shop OBEX P1 Docs P2 Docs Learn Events
Giving out pulses using propeller chip — Parallax Forums

Giving out pulses using propeller chip

prabhatprabhat Posts: 4
edited 2010-08-05 17:23 in Propeller 1
Hi,
I am trying to program a robot with servos on its joints which are controlled by a propeller. Its a HS 422 servo. It has a neutral at 1.5ms pulse. I am trying to give this pulse using the clkfreq and waitcnt but never getting it right. The servo who run to an extreme and hit a mechanical limit. I am not really sure if the pulses i am giving are of the right duration. 1.5ms every 20ms. the following is the code I used. Please help

CON
_clkmode = xtal1 + pll16x ' Feedback and PLL multiplier
_xinfreq = 5_000_000
Led = 1

PUB LedOnOff

dira[noparse][[/noparse]Led] := 1

repeat
outa[noparse][[/noparse]Led] := 1
waitcnt(clkfreq/667 + cnt)
outa[noparse][[/noparse]Led] := 0
waitcnt(clkfreq/50 + cnt)

Is there a problem with the code? I tried the servo with Basic stamp and that works fine.
Thank you in advance
Prabhat

Comments

  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-08-04 20:02
    I wrote the attached program a couple months ago. It actually launches another Spin cog that serves as an 8-channel servo driver. As the whole thing is coded in Spin you might find it helpful.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA

    Post Edited (JonnyMac) : 8/4/2010 8:14:29 PM GMT
  • JavalinJavalin Posts: 892
    edited 2010-08-04 20:04
    have you looked at the servo objects in the OBEX? http://obex.parallax.com

    It does look like your code is wrong.· Maybe :
    us := clkfreq / 1_000_000   ' micro-seconds
    ms := clkfreq / 1_000       ' milliseconds
     
    twenty_ms := ms * 20        ' so we don't have to count each time
    one_pt_five_ms := us * 1500
     
    repeat
        outa[noparse][[/noparse]Led] := 1
        waitcnt(one_pt_five_ms + cnt)
        outa[noparse][[/noparse]Led] := 0
        waitcnt(twenty_ms + cnt)
    

    Might be a simple way to do it.· Note the indentation!

    edit - or this is a better way, as it provides a syncronised 1.5ms pulse - i.e. it begins every 20ms, rather than every 21.5ms as in previous loop.· (look at page 220 in the propeller manual)

    VAR
        long    syncDelay
        long    ms, us
     
    PUB Start
     
        us := clkfreq / 1_000_000     ' micro-seconds
        ms := clkfreq / 1_000         ' milliseconds
     
        twenty_ms := ms * 20          ' so we don't have to count each time
        one_pt_five_ms := us * 1500   '
     
        dira[noparse][[/noparse]Led]~~                   ' set to output
        syncDelay := cnt              ' setup syncronised delays
     
        repeat
            outa[noparse][[/noparse]Led] := 1
            waitcnt(one_pt_five_ms + cnt)     ' wait for 1.5ms
            outa[noparse][[/noparse]Led] := 0
            waitcnt(syncDelay += twenty_ms)   ' wait for the remainer of the 20ms
    
    


    James

    Post Edited (Javalin) : 8/4/2010 8:25:03 PM GMT
  • prabhatprabhat Posts: 4
    edited 2010-08-04 20:34
    I tried both the codes.. But surprisingly the same thing keeps happening. its driving me nuts because I am sure the mistake is something very fundamental. My servo would also wind up at one extreme and in fact pushing to go past it.
  • JavalinJavalin Posts: 892
    edited 2010-08-04 20:39
    what crystal and hardware board are you using?

    james
  • prabhatprabhat Posts: 4
    edited 2010-08-04 20:42
    I am using the prop stick usb platform. It has a 5 Mhz built in crystal
  • W9GFOW9GFO Posts: 4,010
    edited 2010-08-05 01:30
    Are you sure that you have the servo hooked up correctly?

    waitcnt((clkfreq/1_000_000) * 1500 + cnt) is easier to understand (in my opinion) and will work at any _clkmode or _xinfreq without modification.

    Rich H

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    The Simple Servo Tester, a kit from Gadget Gangster.
  • JavalinJavalin Posts: 892
    edited 2010-08-05 08:09
    >waitcnt((clkfreq/1_000_000) * 1500 + cnt)
    but requires the delay to be calculated each and every time you run the line.
    >will work at any _clkmode or _xinfreq without modification.
    so will mine.

    I'll run up the code on my dev board tonight & put the o'scope to work on it.

    Cheers,

    James
  • JavalinJavalin Posts: 892
    edited 2010-08-05 17:23
    Code from the second example posted works fine - full code·as run on my·prop-demo-board·is:
    CON
        _clkmode                = xtal1 + pll16x
        _xinfreq                = 5_000_000
        LED                     = 5
    VAR
        long    syncDelay
        long    ms, us
        long    twenty_ms, one_pt_five_ms
     
    PUB Start
     
        us := clkfreq / 1_000_000     ' micro-seconds (so we don't calc each time)
        ms := clkfreq / 1_000         ' milliseconds
     
        twenty_ms := ms * 20          ' so we don't have to calculate each time
        one_pt_five_ms := us * 1500   '
     
        dira[noparse][[/noparse]Led]~~                   ' set to output
        syncDelay := cnt              ' setup syncronised delays
     
        repeat
            outa[noparse][[/noparse]Led] := 1
            waitcnt(one_pt_five_ms + cnt)     ' wait for 1.5ms
            outa[noparse][[/noparse]Led] := 0
            waitcnt(syncDelay += twenty_ms)   ' wait for the remainer of the 20ms
    

    Attachments to this post show the 1.5ms pulse (1ms per division) and the 20ms gap between the pulses (5ms per div).

    Cheers,

    James
    800 x 600 - 86K
    800 x 600 - 86K
Sign In or Register to comment.