Problems controlling servos on Maestro 18 from Python

Hi All,

I’m working on a project which I need to control the servos connected to a Maestro through the serial connection.

To test the setup I have the following:

  • One servo (at position 0 on the Maestro)
  • Servo power from a battery pack (6V)
  • Maestro power from USB
  • Serial setting of USB Dual Port
  • Device Number of 0

I can control the servo from the Control Centre with no problems. However, I can’t get any response when attempting to control from Python. Below is a very simple program which I think should work but doesn’t for me:

import serial

ser = serial.Serial('COM2', timeout=2)  # COM2 for Pololu command port, 2sec timeout

ser.write(0x84)  # Command to set position
ser.write(0x00)  # Channel number
ser.write(0x70)  # High/low bits
ser.write(0x2E)

ser.write(0x90)  # Command to get position
ser.write(0x00)  # Index of servo to check position of

print(ser.read(2))  # Print what is read from the port

ser.close()  # Close the port

When I run the script the green light on the Maestro blinks but then the read from the serial port times out and returns:

b''

So I can’t seem to set or get the servo position from the Maestro. This code is about as simple as I can make it and has been put together from the code I’ve researched on these forums and Google. I’m sure the issue could be something very simple. Any thoughts and help would be greatly appreciated.

Cheers,
Andrew

If the 18 has the same command set as the micro, I have a small python class that sets position and angle, triggers a script and reads the pos and error bytes. It’s written for the Raspberry Pi but I would imagine all you would have to change is the com port string. You can find it here on the forum, or on my site: http://martinsant.net

Hello, Andrew.

Comparing your code to martan’s, it looks like the main difference is that he is using chr() and you are not. I think you might need to use chr() to guarantee that you are writing binary bytes to the serial port instead of ASCII representations of integers. For example:

ser.write(chr(0x84))

–David

Hi all,

It’s been a bit delayed but I thought I would right to let you know the solution I found to the problem.

It was related to the chr() difference to the Python 2 code. However, the solution I’m using is to use “bytearray” function in Python 3. This takes a tuple of bytes and converts it to one string which can be written to the port. Here is an eample which takes the controller index and queries whether any of its servos are moving:

def get_servo_moving(comport, controller):
    comstring = bytearray((controller, 0x13))
    comport.write(comstring)
    comport.flush()

where comport is the serial port to which the controller is connected to and controller is the index of the controller to be queried.

Hope this helps someone out.

Thanks for the help,
Andrew