Problems with Micro Maestro servo controller and Arduino

Hey Folks –

I just got a Micro Maestro servo controller and I’ve been trying to get it to work with my Arduino Uno.

I’m trying to use SoftSerial library. I’ve read though this forum and found lots of example code, however, I’ve never gotten any of it to work.

I can directly control the servo with the USB and Polou control program so I know the controller and servo are working.

I’ve got 4AA batteries hooked up to the controller and I’ve attached it to the positive rail of the servo with a wire on the back, as described in the docs.

I’ve got all the grounds hooked up together.

I’ve got the controllers RX pin hooked up to the defined TX pin (4) and vice versa.

I’ve got one servo on chan 0.

I’ve bee focusing on this bit of code:

// Pololu micro serial servo controller modes
// Software Serial from Arduino example by Tom Igoe
// put() (now position_absolute) & set_speed() functions found on pololu forums & modified
// mike crist 2009-01-03

#include <SoftwareSerial.h>
#define rxPin 3
#define txPin 4

// set up a new serial port
SoftwareSerial softSerial =  SoftwareSerial(rxPin, txPin);

void setup()
{
  pinMode(rxPin, INPUT);
  digitalWrite(txPin, HIGH); // keeps pololu board from getting spurious signal
  pinMode(txPin, OUTPUT);
  // set the data rate for the SoftwareSerial port
  softSerial.begin(9600);
  set_speed(0, 0);
}

void loop()
{
  position_absolute(0, 1000);
  delay(500);
  position_absolute(0, 3000);
}



void position_absolute(byte servo, int angle)
{
  //this function uses pololu mode command 4 to set absolute position
  //servo is the servo number (typically 0-7)
  //angle is the absolute position from 500 to 5500

  unsigned int temp;
  byte pos_hi,pos_low;

  temp = angle & 0x1f80;  //get bits 8 thru 13 of position
  pos_hi = temp >> 7;     //shift bits 8 thru 13 by 7
  pos_low = angle & 0x7f; //get lower 7 bits of position

  //Send a Pololu Protocol command
  softSerial.print(0x80, BYTE);    //start byte
  softSerial.print(0x01, BYTE);    //device id
  softSerial.print(0x04, BYTE);    //command number
  softSerial.print(servo, BYTE);   //servo number
  softSerial.print(pos_hi, BYTE);  //bits 8 thru 13
  softSerial.print(pos_low, BYTE); //bottom 7 bits
}

void set_speed(byte servo, byte speedVal)
{
  //this function uses pololu mode command 1 to set speed
  //servo is the servo number (typically 0-7)
  //speedVal is servo speed (1=slowest, 127=fastest, 0=full)
  //set speedVal to zero to turn off speed limiting

  speedVal = speedVal & 0x7f; //take only lower 7 bits of the speed

  //Send a Pololu Protocol command
  softSerial.print(0x80,BYTE);     //start byte
  softSerial.print(0x01,BYTE);     //device id
  softSerial.print(0x01,BYTE);     //command number
  softSerial.print(servo,BYTE);    //servo number
  softSerial.print(speedVal,BYTE); //speed
}

And when I upload it to the Arduino nothing happens.

The yellow LED blinks twice ever second, & according to the docs:
"two flashes indicates that at least one of the servos is enabled or one of the output channels is being driven high

Any help would be great. Thanks!

Hello.

The code you are using was written for a different product. It can still serve a good starting point for your own program, but you will need to change the actual bytes you’re sending to represent valid micro maestro command. Have you looked at the serial commands section of the Maestro user’s guide? If there’s something specific about it that you find confusing, please let us know.

- Ben

Hi Ben –

Thank’s for your reply. I’ve now reread the documentation and read though a few more examples of other peoples code.

However, my more informed second attempt is also not working.

The servo is engaged in a fixed position and the yellow LED blinks twice quickly and is then solid briefly.

But it’s not in the position specified in the code and it’s also not changing between the two positions.

Any additional help or insight would be helpful.

#include <NewSoftSerial.h>
#define RxPin     10 // digital pin connected to Maestro TX
#define TxPin     9  // digital pin connected to Maestro RX
NewSoftSerial MaestroSerial =  NewSoftSerial(RxPin, TxPin);
#define MAESTRO_BAUDRATE         9600  // set to the baudrate used.
void setup(){
  pinMode(RxPin, INPUT);
  digitalWrite(TxPin, HIGH); // keeps pololu board from getting spurious signal. Serial is idle high.
  pinMode(TxPin, OUTPUT);
  MaestroSerial.begin(MAESTRO_BAUDRATE); // init the serial communication to the board
}

void loop() {
  MaestroSerial.print(0x84, BYTE);
  MaestroSerial.print(0, BYTE);
  MaestroSerial.print(2000 & 0x7f, BYTE); 
  MaestroSerial.print((2000 >> 7) & 0x7f, BYTE); 
  delay(1000);

  MaestroSerial.print(0x84, BYTE);
  MaestroSerial.print(0, BYTE);
  MaestroSerial.print(500 & 0x7f, BYTE); 
  MaestroSerial.print((500 >> 7) & 0x7f, BYTE);
  delay(1000);
}

Hello. What serial mode is the Maestro in? By default, it is in “UART, auto detect baud” mode, but that mode will not work for you because you are not sending the 0xAA byte. I recommend using “UART, fixed baud” mode and setting the Maestro’s baud rate to match the baud rate your Arduino is using (which is 9600 right now).

Secondly, the target values you are sending look incorrect. You are sending 500 and 2000, but the units of that variable are quarter microseconds so those values you sent correspond to 125 us and 500 us, which are not valid for most servos. Try sending target values between 4000 and 8000 (1000 and 2000 us).

In general, I recommend having the Maestro connected to a computer via USB and looking in the Maestro Control Center’s Status tab while the Arduino is sending commands so you can see what effect your serial commands have.

–David

Hi David –

Thank you so much, it was the timing that was off. It’s working as expected now.