Python to interface with the Pololu 8-channel servo controller

I now have a Python script which is general enough to move any of the 8 servos to any angle. At the bash shell I can type:

python controlsscii.py pos 0 90

and the ‘position’ routine will run – moving servo 0 to 90 degrees using the ‘Mini SSC II’ protocol. Along side this I produced a ‘Pololu’ protocol version running a ’speed’ and ‘position’ routine which can be updated with further routines. I concentrated on the former for ease of debugging when things got frustrating!

The code is as follows:

import serial
import sys
#set up the serial port for action (0==COM1==ttyS0)
ser=serial.Serial(0)
ser.baudrate=2400

def setpos(n,angle):
  #Quick check that things are in range
  if angle > 180 or angle <0:
    angle=90
    print "WARNING: Angle range should be between 0 and 180. Setting angle to 90 degrees to be safe..."
    print "moving servo "+str(n)+" to "+str(angle)+" degrees."

  byteone=int(254*angle/180)
  #move to an absolute position in 8-bit mode (0x04 for the mode, 0 for the servo, 0-255 for the position (spread over two bytes))
  bud=chr(0xFF)+chr(n)+chr(byteone)
  ser.write(bud)

mode=sys.argv[1]
n=int(sys.argv[2])
m=int(sys.argv[3])

if mode=='pos':
  setpos(n,m)
else:
  print "No commands given.\nUsage: controlsscii.py pos <servo> <angle>"

Simple when you know how! And here’s the ‘Pololu’ protocol version (so far):

import serial
import sys
#set up the serial port for action
ser=serial.Serial(0)
ser.baudrate=2400
def setspeed(n,speed):
  #Quick check that things are in range
  if speed > 127 or speed <0:
    speed=1
    print "WARNING: Speed should be between 0 and 127. Setting speed to 1..."
    print "Setting servo "+str(n)+" speed to "+str(speed)+" out of 127."
  speed=int(speed)
  #set speed (needs 0x80 as first byte, 0x01 as the second, 0x01 is for speed, 0 for servo 0, and 127 for max speed)
  bud=chr(0x80)+chr(0x01)+chr(0x01)+chr(n)+chr(speed)
  ser.write(bud)

def setpos(n,angle):
  #Check that things are in range
  if angle > 180 or angle <0:
    angle=90
    print "WARNING: Angle range should be between 0 and 180. Setting angle to 90 degrees to be safe..."
    print "moving servo "+str(n)+" to "+str(angle)+" degrees."

  #Valid range is 500-5500
  offyougo=int(5000*angle/180)+500
  #Get the lowest 7 bits
  byteone=offyougo&127
  #Get the highest 7 bits
  bytetwo=(offyougo-(offyougo&127))/128
  #move to an absolute position in 8-bit mode (0x04 for the mode, 0 for the servo, 0-255 for the position (spread over two bytes))
  bud=chr(0x80)+chr(0x01)+chr(0x04)+chr(n)+chr(bytetwo)+chr(byteone)
  ser.write(bud)

mode=sys.argv[1]
n=int(sys.argv[2])
m=int(sys.argv[3])
if mode=='speed':
  setspeed(n,m)
elif mode=='pos':
  setpos(n,m)
else:
  print "No commands given.\nUsage: controlfunction.py speed <servo> <speed>, or\n controlfunction.py pos <servo> <angle>"

Hope this has helped someone. Don’t forget to set the jumpers to set the protocol.

Updated: Code had all the indentation removed on upload (really not a good thing for Python!). It’s still not great as it runs off the right hand side but I’ll work out showing code at some point!

5 Responses to “Python to interface with the Pololu 8-channel servo controller”

  1. Quick screenshots of the PHP-to-Servo file running « dmt195 today Says:

    [...] entering some data the output of the Python script is added to the top of the [...]

  2. some guy Says:

    google pololu wxwidgets :)

  3. Pololu Python Library | Carlitos' Contraptions Says:

    [...] know there is already a python interface for it but I really wanted to have an object oriented way of managing motors (i.e. they can be [...]

  4. Half-Byte.com » Servo Controller Driven over a USB-Serial Adapter Says:

    [...] In the end I was able to whip together a simple python demo script (see below) that moves the servo to various positions.  Feel free to use it, I got inspiration from a previous test script. [...]

Leave a Reply