Description
The jm_servo_multi.spin2 simple servo driver that uses P2 smart pins to create the servo signal on up to 32 outputs. A second instance of the object may be started to drive 32 more servos, or 64 total.
This object uses the Propeller 2 smart pins and leaves all seven remaining processors open for other tasks, like monitoring an R/C receiver, sensors, or servo drive routines.
Ramping and other slow-motion behavior of the servos is controlled by the parent application jm_servo_multi_demo.spin2.
All channels must fit within the A pins group (0..31) or the B pins group (32..63); using pins 58..63 is not recommended. If you need to control more than 32 servos, simply create another instance of the object.
When controlling more than eight servos from the P2 Edge Breakout Breadboard – the “JonnyMac” (#64020) you will run out of 3-pin servo ports that are already connected to Vin, Vss, and will need to wire 5V to the breadboard power rails. Use caution not to connect the 5V to a P2 Edge IO pin, or you will damage the module.
To use the object, it’s easiest to put your servos on groups of I/O pins. In the jm_servo_multi_demo.spin2 top object file, identify the base pin I/O attached to the first servo.
con { app io pins }
SVO_BASE = 0 { O } ' servos base pin
The N_SERVOS is the total number of servos connected from the SVO_BASE pin.
con
#true, ON, OFF
#false, NO, YES
N_SERVOS = 16 ' # of servos to run
Within the pub main() method the example code sets all servos in the same position (angle of 0), moves them together from 0 to 180 degrees, and then one at a time before repeating the whole process.
pub main() | angle, ch
setup()
'wait_for_terminal(true)
repeat
svos.write_all(svos.M_ANGLE, 0) ' fast move all to 0 degrees
waitms(500)
repeat angle from 1 to 180 ' sweep to 180 position
svos.write_all(svos.M_ANGLE, angle) ' sweep all
waitus(2_000_000 / 180) ' in 2 seconds
waitms(500)
repeat ch from 0 to N_SERVOS-1 ' loop through servos
repeat angle from 179 to 90 ' sweep back to 90 degrees
svos.write(ch, svos.M_ANGLE, angle) ' one at a time
waitus(1_000_000 / 360) ' in 1 second
waitms(500)
Inside the jm_servo_multi.spin2 object you’ll see how the pinstart and wypin commands are used to configure the smart pin.
The pinstart() function configures the IO pin for PWM using output with the enabled (so we can drive the servo). The x register has been configured for standard servo timing (20ms refresh window, and 1us position units), and the y register (us) is the starting position. While we could start all the servos at the same time, it is common practice to stagger the servo outputs so that servo command pulses do not overlap, hence we enable the outputs in a loop.
pinstart(sp0+ch, P_PWM_SAWTOOTH | P_OE, x, us) ' enable smart pin for servo
After the servo pin has been configured, changing the output is a simple matter of writing the new position (in microseconds) to the smart pin y register; this is accomplished with wypin(). The new position value will be output starting with the next servo refresh cycle.
wypin(sp0+ch, usecs[ch]) ' update servo
Document Author
- Ken Gracey
Source Code Author
- Jon McPhalen