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!


[...] entering some data the output of the Python script is added to the top of the [...]
google pololu wxwidgets :)
Thanks for the comment – that may be fine for some but my linux setup is not running a GUI. The servomonster.py script it refers to may be of interest though.
[...] 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 [...]
[...] 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. [...]