0
$\begingroup$

I posted a similar question before as I was just getting started with the project but I wasn't specific enough so got a weak response from the SE community. But now I am at a point where I have Python code which is supposed to rotate a servo through Pololu's Maestro Serial servo controller (https://www.pololu.com/product/207). Based on the "Serial Interface" section of the user's guide (https://www.pololu.com/product/207/resources), I sent a sequence of numbers starting with decimal 170 and 12, which are the "first command byte" and the "device number data byte", respectively. The user guide says that 12 is the default device number, so I tried changing it to 18 because that's how many servos my servo controller can drive. But that doesn't make much difference because the servo doesn't rotate at all. The numbers after that are the same as the example from the user's guide. I am not sure what the 4, 112 and 46 are doing, but the 0 targets the servo port "0" on the servo controller (the port to which my servo is connected). The servo doesn't move, regardless of what sequence of numbers I put in. I have very little experience, so if you guys could point me in the right direction or at least point to some useful resources on the web, I'd be very grateful.

import serial
import struct
import time
import Adafruit_BBIO.UART as UART

drive_Motor_Port = serial.Serial(port = "/dev/ttyO1", baudrate=9600)
drive_Motor_Port.close()
drive_Motor_Port.open()

drive_Motor_Port.write(chr(170)); # User guide says we must start with OxAA = 170
drive_Motor_Port.write(chr(18)); # Device number
drive_Motor_Port.write(chr(04));
drive_Motor_Port.write(chr(00));
drive_Motor_Port.write(chr(112));
drive_Motor_Port.write(chr(46));

time.sleep(5);
$\endgroup$

3 Answers 3

2
$\begingroup$

Have you figured out yet that these two devices use incompatible protocols?:

I'm guessing that you're using a Pololu Mini Maestro 18-Channel USB Servo Controller, connected to UART1 of a Beaglebone Black, following the instructions at "Setting up IO Python Library on BeagleBone Black: UART".

If I were you, here are the first few things I'd do to debug the problem of "servo doesn't move":

  • I would print out the pinout and pin labels of the hardware on paper -- see "Mini Maestro Pinout and Components"

  • Is the ground of the Maestro connected to the ground of the BeagleBone?

  • To rule out power interference, does it work any better when I hook it up to a test jig with an independent, overkill power supply for each part?

    • 5V, at least 2A, power to the BeagleBone barrel connector
    • 5V to 16 V, at least 500 mA, power to the Pololu Maestro (see "Powering the Maestro")
    • 5V to 16 V, at least 2A, power to the servos (check servo datasheet for details)
    • (In particular, trying to run all 3 using the power from a single laptop USB port is unlikely to work).
    • See "Powering the Maestro"
  • Check power between VCC and GND on the Maestro board; between VCC and GND on the 3-wire servo cable, and between VCC and GND on the Beaglebone -- ideally check that voltage with an o'scope while the test program is running, but even a multimeter is enough to diagnose some problems.

  • Are the LEDs blinking the way that the "Indicator LEDs" section of the manual says they should?

  • I might consider disconnecting the Beaglebone entirely, and trying to get an Arduino to control the Maestro over the "serial" pins -- see "Arduino library". That would at least distinguish between a problem in the Beaglebone software vs a problem in the power supply hardware.

  • Next I would try disconnecting the Beaglebone entirely, and seeing if I could get a servo to turn with the Maestro Control Center running on my Linux laptop (or a Windows laptop or a Mac OSX laptop), as described in "Installing Linux Drivers and Software".

  • If I could get a laptop to make the servos turn with USB control, I would use that laptop with USB control to reset the Maestro to the default settings, as described in "Using the Maestro without USB".

  • After getting a servo to move while that servo is connected to a Maestro which is in turn connected to a USB cable to a laptop, and resetting everything to the default settings, I would disconnect the USB cable and re-connect the GND and other pins between the Maestro and the Beaglebone -- see "Connecting to a Microcontroller".

Then I would try to make a program on the Beaglebone as close as possible to the example code ( PIC18F4550, etc. ):

import serial
import struct
import time
import Adafruit_BBIO.UART as UART
# warning: untested code
def main():
    drive_Motor_Port = serial.Serial(port = "/dev/ttyO1", baudrate=9600)
    drive_Motor_Port.close()
    drive_Motor_Port.open()
    while True:
        # move to position 1000 us (typical minimum for servos)
        drive_Motor_Port.write(chr(0xAA)) # User guide says we must start with OxAA.
        drive_Motor_Port.write(chr(0x0c)) # "The Pololu Protocol device number is 12" -- https://www.pololu.com/docs/0J40/3.c
        drive_Motor_Port.write(chr(0x04)) # command 4: set target
        drive_Motor_Port.write(chr(0x00)) # channel
        # target position 0x1f20 = 1000 us
        drive_Motor_Port.write(chr(0x20))
        drive_Motor_Port.write(chr(0x1f))
        time.sleep(2)
        #
        # move to position 1500 us (typical neutral for servos)
        drive_Motor_Port.write(chr(0xAA)) # User guide says we must start with OxAA.
        drive_Motor_Port.write(chr(0x0c)) # "The Pololu Protocol device number is 12" -- https://www.pololu.com/docs/0J40/3.c
        drive_Motor_Port.write(chr(0x04)) # command 4: set target
        drive_Motor_Port.write(chr(0x00)) # channel
        # target position 0x2e70 = 1000 us
        drive_Motor_Port.write(chr(0x70))
        drive_Motor_Port.write(chr(0x2e))
        time.sleep(2)

main()
$\endgroup$
1
$\begingroup$

According to the manual you link, byte 3 '04' is the command.

Command 4: Set Position, Absolute (2 data bytes) This command allows direct control of the internal servo position variable. Neutral, range, and direction settings do not affect this command. Data 2 contains the lower 7 bits, and Data 1 contains the upper bits. The range of valid values is 500 through 5500. Setting a servo position will automatically turn the servo on.

if the valid values are from 500 to 5500 the values you have in Byte 5 and 6 are out of range, and the manual is not clear as to the effect this will have.

PS Doesn't it say byte 1 is supposed to be 128?

$\endgroup$
1
$\begingroup$

Sorry that this response is very late. I had a little trouble when I first came across the Maestro board as well while working on a project.

Doing research on controlling the board, I came across this Github:

I wanted more comprehensive instructions then the README provided and also wanted to refactor the code to match PEP8 standards for my modules. I have put up the code here in order to help anyone else who finds themselves working with the Maestro board. Hope it helps:

Important things to remember:

  • Make sure to run ./MaestroControlCenter go to the "Serial Settings" tab and change the "Serial Mode" to "USB DUAL PORT
  • Install the appropriate drivers and "pyserial" module
  • Look through the README, it provides step by step setup instructions.

Here is a quick sample code for using the maestro module:

import maestro
servo = maestro.Controller()
servo.set_acceleration(0,4)   #set servo 0 acceleration to 4
servo.set_target(0,6000)      #set servo to move to center position
servo.set_speed(1,10)         #set speed of servo 1
x = servo.get_position(1)     #get the current position of servo 1
servo.close()

Good luck and hope this answer helps anyone who comes across.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.