Shop OBEX P1 Docs P2 Docs Learn Events
Servo32_v5 - OBEX updated — Parallax Forums

Servo32_v5 - OBEX updated

Beau SchwabeBeau Schwabe Posts: 6,568
edited 2009-05-16 03:33 in Propeller 1
The Servo32 object has been updated in the OBEX.·
·
- The latest version (Servo32_v4) (Servo32_v5) allows you to enable or disable a Servo Channel by simply providing a pulse width that's out of range of the preset limits.· Currently expanded to a range covering 500us to 2500us
·
- This version also does not require you to preset the servo position prior to starting the object although this newer version remains completely backwards compatible so the older preset method will still work.
·


http://obex.parallax.com/objects/51/


·

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe

IC Layout Engineer
Parallax, Inc.

Post Edited (Beau Schwabe (Parallax)) : 5/13/2009 5:45:09 AM GMT

Comments

  • simonlsimonl Posts: 866
    edited 2009-05-03 15:11
    @Beau: It's great to see that such a useful object still gets maintenance releases - thanks.

    The inclusion of the greater pulse range may be useful for those who'd not spotted how to do that themselves - but people need to be careful they don't "over-drive" their servos.

    As for the enable/disable addition; I'm not sure what to make of that - is there a specific reason for its inclusion? It leaves me a little concerned though: if this object's being used in a mobile 'bot - especially an airborne one - I worry that a channel may become disabled on receipt of a "glitched" pulse.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheers,
    Simon

    www.norfolkhelicopterclub.com

    “Before you criticize someone, you should walk a mile in their shoes. That way when you criticize them, you are a mile away from them and you have their shoes.” - Jack Handey.
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-05-03 19:03
    simonl,

    There is an ulterior motive as to why this feature was added, and the elimination of the preset requirement was completely serendipitous as a result. · For normal operations there should be no difference or changes necessary in the way·that you use your code.· As far as a channel becoming disabled as a result of a glitched pulse, just call the routine with....

    Set(Pin, 500 #> Width <# 2500)
    
    



    ...and it will never become disabled.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 5/3/2009 7:08:49 PM GMT
  • simonlsimonl Posts: 866
    edited 2009-05-04 19:23
    Now you're just teasing - LOL.

    Cool fix - I like that smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheers,
    Simon

    www.norfolkhelicopterclub.com

    “Before you criticize someone, you should walk a mile in their shoes. That way when you criticize them, you are a mile away from them and you have their shoes.” - Jack Handey.
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-05-13 05:38
    Here is the latest update for Servo32 ... Still 100% backwards compatable with existing code, but there are some enhancements with the latest version.

    Servo32v5
    - The pulse-width range has been extended to cover 500us to 2500us servo pulses
    - Ability to Enable or Disable a servo Channel.·
    · The way to do this is to specify a pulse-width value that is out of range.
    - Eliminated then requirement to pre-set the servo position, although this method still works for compatability.
    - Added background servo ramping. This requires a second COG if used and is optional within the object.

    Note: Ramping requires another COG If ramping is not started (optional) then 'SetRamp' commands within the
          program are simply ignored
         
    Note: At ANY time, the 'Set' command overides the servo position.  To 'Ramp' from the current position to the
          next position, you must use the 'SetRamp' command
    

    Commands:
    Set(Pin,Width)           - Pin ranges from   0-31
                             - Width ranges from 500-2500 ; anything outside of this range will make the pin an INPUT
     
    SetRamp(Pin,Width,Delay) - Pin ranges from   0-31
                             - Width ranges from 500-2500 ; anything outside of this range will make the pin an INPUT
                             - Delay is in 20ms increments but can be manually adjusted within the Servo32v5 object to
                               other values.
     
    ------------------------------------------------------------------------------------------------------------------------
     
    Example:
     
    SERVO.Start                'Start Servo handler
    SERVO.Ramp                 'Start Background Ramping
    SERVO.Set(0,500)           'Move Servo on Pin0 to furthest clockwise position
    SERVO.SetRamp(0,2500,3000) 'Pan Servo on Pin0 to furthest counter clockwise position
                               '  This will take approximately 1 minute
                               ' 
                               ' A delay value of 50   = 1 second
                               ' A delay value of 3000 = 1 minute 
                               '  
    waitcnt(clkfreq*30+cnt)    'wait for 30 seconds  <--- Split this up because 80MHz x 60 will overflow the counter and          
    waitcnt(clkfreq*30+cnt)    'wait for 30 seconds       the routine will finish in about 7 seconds
     
    SERVO.Set(0,1500)          'Force Servo on Pin0 to Center
                                        
    




    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 5/13/2009 6:15:44 AM GMT
  • W9GFOW9GFO Posts: 4,010
    edited 2009-05-13 05:50
    Awesome! I've been working on some code for testing servos. I think that ramp you added just save me a lot of headaches.

    Thanks!

    Rich H
  • JonnyMacJonnyMac Posts: 9,195
    edited 2009-05-13 05:51
    New PSC going to be Propeller based?....
  • W9GFOW9GFO Posts: 4,010
    edited 2009-05-13 05:58
    Ok so it is really only a "Ramp" when used with continuous rotation servos where the speed of rotation will increase with time. In a standard servo the "Ramp" sets the time to move to the new position, at a constant speed.
    Is this correct?

    If so, that's exactly what I need.

    Rich H
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-05-13 06:07
    JonnyMac,

    "New PSC going to be Propeller based?" - Your in the right ball park



    W9GFO

    "In a standard servo the "Ramp" sets the time to move to the new position, at a constant speed." - Yes, that is correct

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • Joel RosenzweigJoel Rosenzweig Posts: 52
    edited 2009-05-13 19:15
    Beau,

    There are RC servos from JR on the market now that claim to have 12 bit resolution.· I haven't bench tested one yet, but I'll take them at face value for the moment.· Given that your library·handles nearly full 11-bit resolution, do you have any plans to upgrade the library to support 12-bit output?· I wasn't sure if the architecture you have chosen had enough headroom to provide 12-bit resolution -- perhaps that's why you settled on 11 bit?

    Thanks for authoring this library.· I rolled my own originally, but I looked at your source code last week to take a peek, and it looks very nice.· I plan on giving it a whirl in a project soon.

    Joel-
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-05-13 20:44
    Joel Rosenzweig,

    The actual resolution of the Servo32 has the ability to adjust the pulse-width in 1us increments ... that part of the code is about as tight as it can get.

    The delta or span from 500us to 2500us is just to accommodate the servo that Parallax sells. The lower limit I think is actually about 300us, while the upper limit (I think) is about 4000us making a span of 3700us but I'm not sure that I would call that resolution. I haven't looked at any of JR's claims.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • Joel RosenzweigJoel Rosenzweig Posts: 52
    edited 2009-05-13 21:23
    Hi Beau,

    I'm referring to the resolution with which software can configure the width of the pulse, not the maximum size of the pulse. Using integers from 500 to 2500 has a dynamic range of 2000 units, which corresponds nicely to 1us per unit. This is nearly 11-bits of range (had it been 2048 discreet values then I'd say it had exactly 11 bit resolution). Therefore, to maximize the use of the 12-bit capable servos, it would need software that can generate pulse widths that are described by a range of value from 0 to 4095 + whatever offset if any you choose. In the 12-bit case, 1 unit would equal 0.5us.

    Since you said that the part of the code that generates the pulse is about as tight as it can get, then that answers the question. There code doesn't execute fast enough to offer improved timing resolution. Certainly the Prop can generate pulses with higher resolution than this, but apparently not when trying to drive 32 of them in blocks of 8.

    Thanks for the reply!
    Joel-
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-05-14 16:09
    Joel Rosenzweig,

    That's correct, in order to knock down the 1us to within the range you are suggesting, the PASM would need to be re-written to handle groups of 4 servo's instead of 8 servo's, but doing so would not allow enough processing overhead at 20ms intervals..... 20ms / 8 zones = 2.5ms which would be the upper limit with no overhead for a Parallax servo signal .... at 25ms you would have 3.125ms or 625us of overhead if that would be acceptable. 25ms / 8 zones = 3.125ms

    I don't have any plans to re-write that portion of the servo controller but it certainly can be done if the servo can accept a slightly longer period between servo pulse updates. Most can, so this should not be a problem.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • W9GFOW9GFO Posts: 4,010
    edited 2009-05-14 16:32
    Suppose I only need to control a total of eight servos but want .5 uS resolution at a variable (as low as 3 mS) frame rate. Could the code be modified without too much difficulty?

    Rich H
  • JasonDorieJasonDorie Posts: 1,930
    edited 2009-05-14 20:33
    You could very easily modify the code to handle 4 groups of 4 servos at double the resolution, then just run two copies of it (two cogs) to control all 32 servos.

    I needed a version that would update 8 outputs at 5ms intervals, and it was a pretty trivial change.

    Jason
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-05-15 05:16
    JasonDorie,

    Yes, that would be another way of doing it... splitting it into multiple cogs. If you look at the servo32 PASM, you would focus on the section labeled "ZoneLoop" that's part of the Tight Servo code. As it is there are 8 servo's that are processed here. It takes 80 Clocks at 80MHz to process 8 servos here, which is where the 1us resolution comes from. Cutting the number of servo's in half reduces the number of clocks down to 48 Clocks... you could get this down to 44 Clocks by removing the nop instruction... so not quite 0.5us but rather 0.55us resolution. This small difference is due to a tiny amount of overhead to keep the loop running.

    Another thing to consider, Now you have the groups reduced so your only using the lower 4 servos for each group. You need to have some sort of mechanism that tells the second cog that you are interested in the upper 4 servos.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • W9GFOW9GFO Posts: 4,010
    edited 2009-05-15 20:21
    I'm having a problem getting the Ramp to work accurately. I am trying to make the servo sweep between two positions continuously.

    In the following code I have to add "9" (for a 2 S delay) to the delay otherwise the servo reaches it's endpoint early. When the delay is increased the amount it reaches it's endpoint early also increases. If the "9" is not added the servo pauses briefly before going the other direction. At a 10 second delay, it actually takes about nine seconds to reach the end with a 1 second pause before changing direction.

    Would it have anything to do with updating servo.SetRamp every 20 mS?

    CON
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
      Servo_Pin  = 10                                        ' I/O Pin on ProtoBot For PING))) servo
    
    
    OBJ
    
      servo      : "Servo32v5"
    
    
    PUB Init
    
      servo.start
      servo.ramp
      main
    
    PUB Main | TimeBase, time, hiEnd, loEnd, i
    
    
        hiEnd := 2419
        loEnd := 623
        time := 2
    
        Servo.Set(Servo_Pin, loEnd)
        waitcnt(clkfreq + cnt)
    
        i := time * 50              '500                                    ' number of times through loop - sweep time * 50 hz
    
        TimeBase := 1_000 + cnt
        repeat
    
          repeat i
            waitcnt (TimeBase += clkfreq/50)
            servo.SetRamp(Servo_Pin, hiEnd, i + 9)
    
          repeat i
            waitcnt (TimeBase += clkfreq/50)
            servo.SetRamp(Servo_Pin, loEnd, i + 9)            
    
    



    Rich H

    Post Edited (W9GFO) : 5/15/2009 8:34:09 PM GMT
  • W9GFOW9GFO Posts: 4,010
    edited 2009-05-15 21:00
    I changed the loop so that servo.SetRamp is only called when necessary but I couldn't see any difference in the way the program runs.

        repeat
    
          servo.SetRamp(Servo_Pin, hiEnd, i)
          repeat i
             waitcnt (TimeBase += clkfreq/50)
    
          servo.SetRamp(Servo_Pin, loEnd, i)
          repeat i
            waitcnt (TimeBase += clkfreq/50)  
    
    


    Rich H
  • W9GFOW9GFO Posts: 4,010
    edited 2009-05-15 23:21
    I've discovered that when using Servo32v5_RampDemo.spin the transit time only matches the set delay time of 1 minute if the widths are not changed. I was expecting the increments to scale accordingly to fit the alloted time as the width was modified.

    Thinking a bit... I guess since SetRamp(Pin, Width, delay) has no knowledge of the current servo position - it can't know how much to change the pulse width every 20 mS so that it fills the desired sweep of the servo. It appears that 'delay' is used to calculated the change in uS based upon a full sweep of 500 uS to 2500 uS. So when the desired sweep is less - it still moves at the speed of a full sweep but finishing earlier that the specified 'delay'.

    Rich H

    Post Edited (W9GFO) : 5/15/2009 11:32:57 PM GMT
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-05-16 01:12
    W9GFO,

    Yes, the time is based on the full sweep time from 500us to 2500us .... or a Delta of 2000us

    Since your Delta is 1796us , you should adjust your calculations by 0.898% ... <--- 1796us / 2000us = 0.898

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • W9GFOW9GFO Posts: 4,010
    edited 2009-05-16 03:25
    Thanks Beau,

    That was helpful. Although the solution required 2000/delta. smile.gif

    Here is my code which is working and is accurate timing wise as far as I can tell;
    PUB Main | TimeBase, time, hiEnd, loEnd, i, delay
    
    
        hiEnd := 600
        loEnd := 2200
        time := 10
    
        Servo.Set(Servo_Pin, loEnd)
        waitcnt(clkfreq + cnt)
    
        i := time * 50                                             ' number of times through loop - sweep time * 50 hz
    
        delay := (i * (2_000_000 / ||(hiEnd - loEnd)))/ 1_000      ' time x (2000/delta) extra zeros to avoid using float math
    
        TimeBase := 1_000 + cnt
    
        repeat
    
          servo.SetRamp(Servo_Pin, hiEnd, delay)
          repeat i
             waitcnt (TimeBase += clkfreq/50)
    
          servo.SetRamp(Servo_Pin, loEnd, delay)
          repeat i
            waitcnt (TimeBase += clkfreq/50)
    
    



    Rich H
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-05-16 03:33
    Glad that worked for you

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
Sign In or Register to comment.