Multiple Servo Control (up to 64) Object

Share on facebook
Share on twitter
Share on linkedin
Share on email
Share on print
Table of Contents

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. 


  #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



    svos.write_all(svos.M_ANGLE, 0)           ' fast move all to 0 degrees


    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


    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


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 
Programming Language
Tools and Operating System
Document Author
Source Code Author
Table of Contents
0 0 votes
Article Rating
Notify of
Inline Feedbacks
View all comments
Copyright © 2021 Parallax Inc. All Rights Reserved
Designed and Made in California, USA