Shop OBEX P1 Docs P2 Docs Learn Events
Propeller Servo Controller Code — Parallax Forums

Propeller Servo Controller Code

ajwardajward Posts: 1,130
edited 2014-08-24 12:14 in General Discussion
Hey All...

I have a question concerning the code that resides in the Prop Servo Controller. If I understand correctly, the enabled servos are initialized (centered) in this section of code:
''Initialize Loop ------------------------------------------------------------------


     repeat temp from 0 to 15   '' Initialize ALL servos to center position that are Enabled on Startup
       If ((Enabled & |<temp)>>temp) == 0               '' Check if servo is enabled on startup
          PW := 750                                     '' Set default Servo Width value
          If LoadDetect == 1                            '' Check if pre-defined Servo position has been selected
             PW_highbyte := EEPROM.RandomRead(ServoCh0+(temp<<1)+0)             '' Load pre-defined HIGH BYTE
             PW_lowbyte  := EEPROM.RandomRead(ServoCh0+(temp<<1)+1)             '' Load pre-defined LOW BYTE
             if PW < 250 or PW > 1250                   '' Check if pre-defined Servo position is within valid range 
                PW := 750                               '' ...If not default to center position
          Servo.Set(temp,PW<<1)                         '' Initialize servo position                    



The initialization works, but for my application (my biped Wally) it happens just too quickly.
https://www.youtube.com/watch?v=gXV6dJJyQ4o
It is certainly impressive to see a "pile" of servos and metal parts snap to attention, but it ofter results in Wally falling over which lessens the impressiveness. :-)
I'd like to slow down the process, but I'm not sure how to slowly bring the hip and knee servos to the center position (~750) from different starting positions. The goal would be to have him in a squatting position and slowly stand erect.

Any guidance would be greatly appreciated!

Amanda

Comments

  • PublisonPublison Posts: 12,366
    edited 2014-08-24 09:20
    Amanda,

    I would try to use the Start Up Mode to set the servos to the idle position (flat):
    EDD – Startup Servo Mode Syntax: “!SCEDD” <mode> <CR> 
    Reply: “DL” <mode> 
    This command sets whether the PSCU centers all servo channels on startup (mode 0) or uses custom 
    startup positions stored in EEPROM (mode 1). In mode 1 you can set a custom startup position for each 
    servo channel using the default position command below. To set the Startup Servo Mode, the following 
    must be sent to the PSCU: “!SCEDD” followed by a byte value of 0 for default (center) or 1 for custom 
    and finally a carriage return ($0D). The following code can be used to set the startup servo mode to 1 
    using a BASIC Stamp 2. 
    ' {$STAMP BS2} 
    ' {$PBASIC 2.5} 
    Sdat PIN 15 ' Serial Data I/O Pin 
    Baud CON 396 ' Constant For 2400 Baud 
    buff VAR Byte(3) ' Temporary Variable (Array) 
    SetPort: 
     DEBUG "Setting Startup Servo Mode...", CR 
     SEROUT Sdat, Baud+$8000, ["!SCPSS", 1, CR] 
     SERIN Sdat, Baud,500, SetPort, [STR buff\3] 
     DEBUG "Startup Mode: ", buff(0), buff(1), DEC1 buff(2), CR 
     DEBUG "Please reset PSCU or cycle power now." 
     STOP 
    Note: The PSCU must be reset after this command is sent or power must be cycled to activate the 
    change. 
    
    

    Then use the Position Command in you main program :
    Position Command – Set Position of a Servo Channel Syntax: “!SC” <channel> <ramp speed> <lowbyte> <highbyte> <CR> 
    Reply: None 
    To move a servo to a location you must write a position command to the PSCU. Each position command 
    is comprised of the preamble, the channel, the ramp speed, lowbyte/highbyte of the pulse width in 2 µs 
    increments and a carriage return ($0D). The preamble is “!SC”. The channel is a byte value from 0 – 15 
    (16 – 31 if this is the second unit in a network). The ramp speed is a byte value from 0 – 63 that 
    controls the speed the servo moves to its new position. 
    ' {$STAMP BS2} 
    ' {$PBASIC 2.5} 
    ch VAR Byte 
    pw VAR Word 
    ra VAR Byte 
    Sdat CON 15 
    baud CON 396 
    ra = 7 
    ch = 11 
    DO 
     pw = 1100 
     SEROUT Sdat, Baud+$8000,["!SC", ch, ra, pw.LOWBYTE, pw.HIGHBYTE, CR] 
     PAUSE 1000 
     pw = 300 
     SEROUT Sdat, Baud+$8000,["!SC", ch, ra, pw.LOWBYTE, pw.HIGHBYTE, CR] 
     PAUSE 1000 
    LOOP
    

    to set the centering using the ramp speed function, with 63 being the slowest ramping.

    Maybe Beau will chime in as he is the servo guru.

    Jim
  • bte2bte2 Posts: 154
    edited 2014-08-24 11:04
    Can't be done because there is no MCU feedback of the servo's position. The servo will snap to center as fast as possible as soon as it gets the pulses.

    The only way I can see doing it is to ensure that the servos are already close to center when you turn on the power.
  • ercoerco Posts: 20,256
    edited 2014-08-24 11:58
    +1. Possibly try to always power down the bot (and power up) in a stable home configuration, be it standing, sitting, or lying down
  • PublisonPublison Posts: 12,366
    edited 2014-08-24 12:09
    bte2 wrote: »
    Can't be done because there is no MCU feedback of the servo's position. The servo will snap to center as fast as possible as soon as it gets the pulses.

    The only way I can see doing it is to ensure that the servos are already close to center when you turn on the power.

    If you pre-program the firmware with the !SCEDD command for the servos involved, That servo position would be saved into the upper EEPROM. On the next startup, the servos would not move, ( if programmed to the resting pulse, say 1000 for "lay down".

    Then the servo.ramp command could be issued from the top object, (or BS2) to bring those servos up with the "delay"
  • PublisonPublison Posts: 12,366
    edited 2014-08-24 12:14
    bte2 wrote: »
    Can't be done because there is no MCU feedback of the servo's position. The servo will snap to center as fast as possible as soon as it gets the pulses.

    The only way I can see doing it is to ensure that the servos are already close to center when you turn on the power.

    There are provisions in the servo.spin code for saving starting positions in the upper EEPROM. They don'y have to be center.
Sign In or Register to comment.