Shop OBEX P1 Docs P2 Docs Learn Events
SX Servo Controller: Group Moves, Timed Ramping, LED Multiplexer, PWM -- wiring — Parallax Forums

SX Servo Controller: Group Moves, Timed Ramping, LED Multiplexer, PWM -- wiring

ZootZoot Posts: 2,227
edited 2008-01-07 16:38 in General Discussion
I've just finished some code for a really useful (to me, anyway) combination servo controller and PWM/Led Multiplexer. I cribbed a lot of the serial and servo pulse code from Jon Williams' columns in N&V -- parallax.com/Portals/0/Downloads/docs/cols/nv/vol8/col/nv143.pdf and parallax.com/Portals/0/Downloads/docs/cols/nv/vol8/col/nv144.pdf. See description and code below (including Stamp program that tests it out). It works great! and I'm pretty pleased.

However, my question is more hardware related -- on Jon's schematics for the "control anything" board he built, he has 100ohm resistors between the SX output pins and the servos. Why? Can the servo kick back current through it's signal wire?

Second, the SX data sheet shows that either a 22k or 1mOhm resistor is needed between OSC1 and OSC2 when using an external resonator (like the 20mhz murata sold by Parallax), but Jon's construction on the SX protoboard (NV144) does not have this resistor. My understanding is that the resistor between OSC1 and OSC2 helps the resonator startup up under certain conditions. I always use a 10k on my 50mhz projects, but I see where sometimes folks use a resistor and sometimes don't. What's the rule of thumb? If the SX and the resonator start up you're good? I'm running my Servo Controller at 50mhz, but will probably clock it down to 20mhz if it doesn't get jittery (haven't had a chance to count cycles in the ISR yet, and it's a long ISR).

' ------------------------------------------------------------------------- 
' Program Description 
' ------------------------------------------------------------------------- 
' Servo and LED helper for Stamp-based 'bots (or any project).
' Original servo control and mainline code cribbed nearly verbatim from
' Jon Williams in Nuts n Volts, with some changes by Zoot for padding
' pulsewidths. TX/RX code originally by Al Williams (I believe), cribbed
' by Jon. LED and ramping code by Zoot.
'
' PWM with multiplexing:
'   Two modes -- 0: multiplexing of 8 segments by 2 digits for LEDs, 
'                   with individual PWM brightness on each digit, OR,
'                1: discrete PWM on 2 pins + 8 pin digital outs
'
' Servos:
'   - 8 servos, positions can be sent in brads (0-64-128) or as full range byte:
'     (0-128-255). In either mode, full range of servos is .67ms-2.33ms (or 11-117 brads) 
'   - real time ramping: 0.0-25.5 seconds in 100ms steps
'     Includes real time ramping of servos -- regardless of initial servo
'     position and target position, the servo will take ramp*100ms to reach
'     the desired position. Very useful for group moves where you want all
'     servos to reach their final positions AT THE SAME TIME regardless of
'     distance to move or when command was received.
'
' Setup:
'   A.0 = Serial in/out
'   A.1 = optional status led (anode)
'   A.2 = ledCathodes dig 0 (multiplex mode), or 8-bit PWM A (discrete mode)
'   A.3 = ledCathodes dig 1 (multiplex mode), or 8-bit PWM B (discrete mode)
'   PORTB = servo outs
'   PORTC = ledAnodes (multiplex mode), 8-bit digital outs (discrete mode)
'
' Communication:
'   Serial I/O, Baud set by serial command, 2400 - 38K4 baud
'   Serial format and commands as follows...
'
'   All serial strings start with a three byte command header, followed by commands and/or data:
'
' "!QV" -- get version -- SX will return 3 byte ASCII string.
'                         actual version number is third byte in ASCII string
'
' "!QM" -- set Mode(s)/Baud -- SX will expect 1 more command byte:
'   high nib (bits 4..7):
'     bit7: 0 = leave baud alone;
'           1 = change baud based on bits 4-6
'     bits4-6: baud mode setting...
'       %000 = 0 = 2400 baud (default baud on powerup/reset)
'       %001 = 1 = 4800 baud
'       %010 = 2 = 9600 baud
'       %011 = 3 = 19K2 baud
'       %100 = 4 = 38K4 baud
'   low nib (bits 0..3): mode(s)...
'     bit3: 0 = leave mode(s) alone;
'           1 = change mode(s) based on bits 0..2
'     bit0: 0 = LED multiplexing mode (default on powerup/reset);
'           1 = discrete PWM and digital outs mode
'     bit1: 0 = servo positions as calibrated brads: 11-64-117 = .67ms-1.5ms-2.33ms
'               (default to brads on powerup/reset)
'           1 = servo positions as 6.51us units: 0-128-255 = .67ms-1.5ms-2.33ms

' "!QL" -- set LEDs/PWM/Outs -- SX expects 3 or 4 more bytes depending on the multiplex mode:
'   mode = LED multiplexing -- 4 bytes
'     Byte0: ledAnodes bitmap dig 0 (RC)
'     Byte1: ledAnodes bitmap dig 1 (RC)
'     Byte2: pwm brightness dig 0 (RA.2)
'     Byte3: pwm brightness dig 1 (RA.3)
'   mode = discrete PWM/outs -- 3 bytes
'     Byte0: digital pin outs (RC)
'     Byte1: pwm 0 (RA.2) 
'     Byte2: pwm 1 (RA.3)
'
' "!QS" -- set servos -- SX will expect 3-17 more bytes:
'    Byte0: low nib = start servo index of the position/ramp pairs to follow;
'           high nib = end servo index of pairs to follow (inclusive)
'           E.g., to set only servos 0-3, then the command byte would be 0x30 (hex).
'           To  set 5-7, the command byte would be 0x75
'    The command byte is followed by the specified number of position/ramp byte pairs:
'    Byte1 = servo0 position in brads or 6.51us units, depending on mode
'    Byte2 = servo0 ramp, 0-255 in 100ms units (servo will take this time to complete move)
'    ...Byte15 = servo7 position
'    ...Byte16 = servo7 ramp
'
' "!QF" -- get flags -- SX will return 1 byte of flags. Servo's bit position 
'                       will be set to "1" if servo pulsewidth has reached desired target position.
'
' "!QP" -- get servo positions -- SX will expect 1 more byte:
'    Byte0: low nib = start servo index of the positions to transmit;
'           high nib = end servo index of positions to transmit
'           E.g., to get positions of only servos 1-4, then the command byte would be 0x41 (hex).
'       -- SX will then transmit current actual servo positions in order.
'
' All servos positon/ramp bytes follow this format:
'   position theoretical (brads): 0 = .5ms, 64 = 1.50ms, 128 = 2.5ms
'   positions actually available (brads):
'   11 brads = .67ms, 64 brads = 1.50ms, 117 brads = 2.33ms
'
' The next version of the program will probably use Words to track servo pos
' so that 0-64-128 brads will get you 500us-1500us-2500us
'
' ramp: 0-255 (100ms units)
'   E.g., 10 will give you a 1 second ramp time. Sending a ramp of 0 will set 
'   the servo position immediately (within 20ms of receipt). Ramps are calcuated
'   based on target position and actual position of servo when the ramp is received
'   and set. So, regardless of distance to be traveled, the servo will take the ramp
'   time to move to the final position.
'
' Calibration:
'   Data at end of program lets you adjust the brads->pos and pos->brad midmultiply
'   values. You can adjust these to match individual servos and get all your servos
'   calibrated consistently to brads. The Servo_Offsets are for "recentering" individual
'   servos if you desire other values for "center" than 1.5ms. This is nice if you have
'   servos (like I do) where the horns are not mounted on "pre-centered" servos. The offset
'   adjustments are in units of 6.51us (plus or minus offsets, min -107).
'   Additionally, there is a direction flag if you wish to reverse the output for a given
'   servo (say, if two pan/tilt eyeball assemblies are constructed "mirror image" to each 
'   other but you want both pans to go ccw when brads are > 64).


▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST

Post Edited (Zoot) : 1/6/2008 7:46:40 PM GMT

Comments

  • Sparks-R-FunSparks-R-Fun Posts: 388
    edited 2008-01-04 21:43
    I think the Murata resonators include the appropriate resistance internally.

    (Someone please correct me if I am wrong.)


    - Sparks
  • ZootZoot Posts: 2,227
    edited 2008-01-04 22:01
    I believe the muratas include the caps internally, not the resistance.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • ZootZoot Posts: 2,227
    edited 2008-01-06 19:43
    OK -- I'm going to wire up my servo/led controller over the next two evenings, so maybe some yes/no/maybe questions will be best smile.gif

    - 100ohm resistors between SX pin(s) and servo signal pin(s). Yes? No? Optional?

    - 22k/1mOhm resistor between OSC1 and OSC2 on 20mhz resonator? Yes? No? Maybe?

    - one of Jon's code examples in NV143 has the use of a "armed/syncTimer" so that the program will move on if the correct number of serial bytes are not received. He used a 2 byte threshold (after 2 byte periods or 20 bits) of failure to RX, the program moves on. Given that in some cases my controller receives 14 bytes or so, what's a good threshold for having the program exit an RX loop? Stick with two bytes? Yes? No?

    - This is kind of a Stamp question -- in my tests using the SX controller with a BS2, I've had no problem communicating both ways up to 38k4, though depending on code structure the BS2 can't always reliably read in at 38k4. In any case, Jon's code uses a delay of 15ms before TXing a byte from the SX ("to let the host get ready"). This adds 30ms to my loop time on the *host* side if I've got to SERINs in the loop. Can I get away with shortening this? It seems like the Stamp can get ready for input after issuing output commands within 5ms or so (e.g. the Ping))) firmware which inserts a 5ms delay before sending a pulsewidth reading).

    - since my SX controller code allows for serial commands to change baud rate. Is there any reason not to have differing TX and RX baud rates. It would be easy enough to add in the extra variables and command? This would let me always send to the SX at 38k4 and receive at 19k2 or 38k4 depending on the capabilities of the host.

    - Last but not least, Jon used 2 stop bits on his TX routine, again to give a Stamp host breathing room. ???? I don't get it. Consider me dense.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • ZootZoot Posts: 2,227
    edited 2008-01-07 03:28
    Correction --

    Ping))) Specs said...
    Echo Hold-off - 350 uS from fall of Trigger pulse

    In any case, it would *seem* I could greatly reduce the delay between the SX's receipt of a TX command and the TX itself. No idea if the overhead in SEROUT to SERIN on the Stamp is a lot greater than the overhead from PULSOUT to PULSIN.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
  • JonnyMacJonnyMac Posts: 9,218
    edited 2008-01-07 15:14
    The 15 ms delay in my projects that use single wire serial is to accommodate the Javelin -- it takes a long time to reconfigure a pin from output to input for serial. You're right, the BASIC Stamp doesn't and you could use a much smaller "let master get ready" time.
  • ZootZoot Posts: 2,227
    edited 2008-01-07 16:38
    Jon -- thanks. You think 500us or so would be sufficient for any BS2+ Stamps and the like?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
Sign In or Register to comment.