USB16 with python

Hello,
I’m new here and I’m probably doing something quite stupid :slight_smile:

I’m trying to drive the usb 16 channel servo controller from python. I’m able to connect and set the baud rate and everything looks good but as soon as I send any data I get the red flashing led which I assume means my data is bad.
I’ll check that tonight with a serial port checker.

However my question is this:
In the non pololu mode, should the green “servos powered” led come on? It is not on and the servo isn’t centering or anything, but I think I read somewhere on here that the servos don’t center until they recieve their first packet of valid data?
Below is some more information about what I’m seeing.
Cheers
Dave

HW

I’m using 4aa duracells as servo power and a hobbico servo that I tested with a servo tester.
I’ve checked voltage across servo connector pin and have 6.5v

Pololu Mode Jumper off

  1. Reset board by disconnecting and reconnecting to USB
  2. USB light is on
    All leds on bottom of board flash in sequence and then only yellow is lit
  3. Run python script
    Serial Activity led flickers once
    Red led starts flashing about 1hz

Output:
Opening Serial Port 3 on real port COM4
Serial<id=0x14bde70, open=True>(port=‘COM4’, baudrate=9600, bytesize=8, parity=‘N’, stopbits=1, timeout=None, xonxoff=0, rtscts=0, dsrdtr=0)
SData 6 : 0x80 0x1 0x0 0x0 0x4f 0x0
SData 6 : 0x80 0x1 0x0 0x0 0x4f 0x0
SData 6 : 0x80 0x1 0x0 0x0 0x4f 0x0
SData 6 : 0x80 0x1 0x0 0x0 0x4f 0x0
SData 6 : 0x80 0x1 0x0 0x0 0x4f 0x0
SData 6 : 0x80 0x1 0x0 0x0 0x4f 0x0
SData 6 : 0x80 0x1 0x0 0x0 0x4f 0x0
SData 6 : 0x80 0x1 0x0 0x0 0x4f 0x0
SData 6 : 0x80 0x1 0x0 0x0 0x4f 0x0
SData 6 : 0x80 0x1 0x0 0x0 0x4f 0x0

Mini SSC II mode Jumper on

  1. Reset board by disconnecting and reconnecting to USB
  2. USB light is on
    All leds on bottom of board flash in sequence and then only yellow is lit
  3. Run python script
    Serial Activity led flickers once
    Red led starts flashing about 1hz

The Other green led never comes on. In the manual it says that in ssc mode this led is always on?

Output:
Opening Serial Port 3 on real port COM4
Serial<id=0x15a2410, open=True>(port=‘COM4’, baudrate=9600, bytesize=8, parity=‘N’, stopbits=1, timeout=None, xonxoff=0, rtscts=0, dsrdtr=0)
SData 3 : 0xff 0x0 0x20
SData 3 : 0xff 0x0 0x20
SData 3 : 0xff 0x0 0x20
SData 3 : 0xff 0x0 0x20
SData 3 : 0xff 0x0 0x20
SData 3 : 0xff 0x0 0x20
SData 3 : 0xff 0x0 0x20
SData 3 : 0xff 0x0 0x20
SData 3 : 0xff 0x0 0x20
SData 3 : 0xff 0x0 0x20

Hello.

I don’t know anything about Python, but a user posted a thread that might have useful information:

- Ben

Hello,

The “servos on” LED should correspond to actual pulse generation. In Mini SSC II mode, the pulse generation begins after the first byte (not packet). In either mode, the servo pulses are stopped if there is a critical error, so once you get to an error state, the LED should be off.

It looks like you’re sending a bunch of bytes; I recommend just sending a single byte: 0xFF in Mini SSC II mode. You should either get the servos to go to their neutral positions, or an error and a really small program to debug.

- Jan

Guys,
Thanks for the speedy responses. I will give some of this a try tonight!
Cheers
Dave

Guys,
I solved my problem. It was something to do with the usb port. I moved the USB connection from the usb ports on the front of my computer to the powered hub on the back and everything works as advertised. Took me a while to figure it out though.
Cheers
Dave

Hey,
I thought I just post this up. Its my work in progress servo controller in python. To run it under windows, you’ll need python, win32all, and pyserial which are all easy to get off the net.
The name of the serial device will vary depending on whether you run on linux or windows. I haven’t tested it under linux.

Why am I using python? Its a great language with a lot of power and it is simple to set up and use. Its a bit weird if you are used to C/C++ as its typeless and relies on white space formatting but once you get used to it, its nice. It is very good for parsing text file and stuff like that.

Next I’m going to add a script parser, so I can create scripts and run them as my application is primarily animatronic and not robotic. I’ll post that stuff up as I go along.
Cheers
Dave

<code begins>

#############################################################################
# Feb-08 Servomonster.py dcoombes
# Usage: 
#############################################################################
import sys
import string
import serial
import time


class servoMonster:
    def OpenCommunications(self,port):
        self.ser = serial.Serial(port)
        print "Opening Serial Port ",port," on real port ",self.ser.portstr


    def CloseCommunications(self):
        self.ser.close()

    def Print(self):
        print self.ser

    def InitServo(self,ServoNum,Direction,Range):
        CommandData = Range | (Direction<<5) | (1<<6)
        outStr = chr(0x80)                  #start byte
        outStr = outStr+ chr(0x1)           #device Id
        outStr = outStr+ chr(0x0)           #command
        outStr = outStr+ chr(ServoNum)      #servo
        outStr = outStr+ chr(CommandData)   #data1
        self.ser.write(outStr)

    def SetSpeed(self,ServoNum,speed):
        outStr = chr(0x80)                  #start byte
        outStr = outStr+ chr(0x1)           #device Id
        outStr = outStr+ chr(0x1)           #command
        outStr = outStr+ chr(ServoNum)      #servo
        outStr = outStr+ chr(speed)         #data1
        self.ser.write(outStr)

    def SetPosition(self,ServoNum,Position):
        outStr = "%c%c%c%c%c" % (chr(0x80),chr(0x1),chr(0x2),chr(ServoNum),chr(Position))
        self.ser.write(outStr)

    def SetPosition2(self,ServoNum,Position):   #8 bit position command
        Pos2 = Position
        Pos1 = 0
        if Pos2>128:
            Pos2-=128
            Pos1 = 1
        outStr = "%c%c%c%c%c%c" % (chr(0x80),chr(0x1),chr(0x3),chr(ServoNum),chr(Pos1),chr(Pos2))
        self.ser.write(outStr)
        
  
PORT = 3  # 3 works for me on windows but you may need something else esp if you are on linux
#############################################################################
# if the script is being run call main
#############################################################################
if __name__ == '__main__':

    test =servoMonster()
    test.OpenCommunications(PORT)
    test.Print()
    test.InitServo(0,0,15)  #init servo 0 : range of 15 gives 180 degrees of movement
    test.SetSpeed(0,127)    #set servo 0 speed to 127 (top speed for servos)

    test.SetPosition2(0,0)  #set servo 0 to position 0
    time.sleep(2)          
    test.SetPosition2(0,255)  #set servo 0 to position 255
    time.sleep(2)          
    test.SetPosition2(0,0)  #set servo 0 to position 0
    time.sleep(2)          
    
    test.SetSpeed(0,12)     #set servo 0 speed to not very fast

    #this loop moves servo 0 through 180 degrees in 10 steps
    i=0
    while i<255:
        test.SetPosition2(0,i)  #update servo position
        print '*',
        time.sleep(0.5)     #wait half a second
        i=i+25

    test.SetSpeed(0,66)     #set servo 0 speed 
    test.SetPosition2(0,0)  #set servo 0 to position 0
    
    test.CloseCommunications()

<code ends>

Thanks for the contribution, Dave!

- Ben