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!
23 January, 2009 at 12:28 am |
[...] entering some data the output of the Python script is added to the top of the [...]
22 February, 2009 at 2:51 pm |
google pololu wxwidgets :)
22 February, 2009 at 8:07 pm |
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.
16 July, 2009 at 4:54 am |
[...] 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 [...]
21 September, 2009 at 7:26 am |
[...] 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. [...]