Mini-Maestro 18ch Resetting Issue with Arduino Lib

Hi.

I am having a very strange problem with my mini-maestro 18ch using the Arduino Library. I have built a robot arm with 6 servos and am the maestro for control through the Arduino Uno. What is happening is I after I move the two of the servos (shoulder and elbow in this case) and then try to move a third servo the maestro resets itself to the home values.

As for trouble shooting I checked and rechecked all the connenctions and they match what is on the Github page. I powered the setup with both a LiPo and wall charger (note power goes through a 5v regulator). I also ran the same sequence through the maestro control panel with the battery and the wall supply and it worked without an issue. I can not for the life of me think of what else to try to solve this problem.

Listed below is the code and a screen shot of the control panel settings:

[code]#include <PololuMaestro.h>
#include <Wire.h>
#include <avr/pgmspace.h>

/*in the Maestro Control Center and apply these settings:

  • Serial mode: UART, fixed baud rate
  • Baud rate: 9600
  • CRC disabled

Be sure to click “Apply Settings” after making any changes
*/

/* On boards with a hardware serial port available for use, use
that port to communicate with the Maestro. For other boards,
create a SoftwareSerial object using pin 10 to receive (RX) and
pin 11 to transmit (TX). */
//#ifdef SERIAL_PORT_HARDWARE_OPEN
// #define maestroSerial SERIAL_PORT_HARDWARE_OPEN
//#else
#include <SoftwareSerial.h>
SoftwareSerial maestroSerial(10, 11);
//#endif

/* Next, create a Maestro object using the serial port.
Uncomment one of MicroMaestro or MiniMaestro below depending
on which one you have. */
//MicroMaestro maestro(maestroSerial);
MiniMaestro maestro(maestroSerial);

struct maestro_parameters
{
int servo_channel;
char servo_name[20];
int servo_min;
int servo_max;
int servo_home;
int servo_speed;
int servo_accel;
int servo_neutral;
int servo_fromLow;
int servo_fromHigh;
} servo[6];

String inputString = “”;
String servoString = “”;
String commandString = “”;
boolean stringComplete = false;
int servoNum, servoPosMs;
float servoPosDeg;

void setup() {
Serial.begin(9600);
// Set the serial baud rate.
maestroSerial.begin(9600);

Serial.println(“Ready”);

inputString.reserve(10);
servoString.reserve(10);
commandString.reserve(10);

//Serial.println(map(0,180,-180,4244,7680));

//maestro_parameters servo[6];
servo[0] = (maestro_parameters) {0, “Base”, 762, 1920, 1361, 0, 0, 1504, -180, 180};
servo[1] = (maestro_parameters) {1, “Shoulder”, 640, 2248, 2040, 40, 0, 1500, -180, 180};
servo[2] = (maestro_parameters) {2, “Elbow”, 992, 1856, 1738, 10, 0, 1505, 180, -180};
servo[3] = (maestro_parameters) {3, “Wrist_Pitch”, 896, 2064, 896, 10, 0, 1500, -90, 90};
servo[4] = (maestro_parameters) {6, “Wrist_Rotate”, 608, 2448, 1500, 40, 0, 1500, 90, -90};
servo[5] = (maestro_parameters) {7, “Gripper”, 1312, 1792, 1358, 7, 0, 1500, 0,10};

}

void loop(){
parseCommand();
}

void finish(){
while(true){
;
;
}
}

/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == ‘\n’) {
stringComplete = true;
}
}
}

void parseCommand(){
// print the string when a newline arrives:
if (stringComplete) {
inputString.trim();
//Serial.println(inputString);
int separatorIndex = inputString.indexOf(’,’);
servoString=inputString.substring(0,1);
commandString=inputString.substring(separatorIndex+1);
servoNum = servoString.toInt();
servoPosDeg = commandString.toInt();

moveServo();

// clear the string:
inputString = "";
servoString = "";
commandString = "";
stringComplete = false;

}
}

void moveServo() {

//Mini Maestro values given in 1/4 ms so you have to multiply by 4.
servoPosMs = 4*map(servoPosDeg, servo[servoNum].servo_fromLow, servo[servoNum].servo_fromHigh,
servo[servoNum].servo_min, servo[servoNum].servo_max);

maestro.setSpeed((uint8_t) servo[servoNum].servo_channel, (uint16_t) servo[servoNum].servo_speed);
maestro.setTarget((uint8_t) servo[servoNum].servo_channel, (uint16_t) servoPosMs);

//Serial.print ("Position is: ");
//Serial.println (maestro.getPosition(servo[servoNum].servo_channel));

Serial.println (“Done”);

}
[/code]

Any help would be appreciated.

Thanks in advance
Mike

EDIT: Here are a couple of photos of the Arm and Servos used as well as a shot of the electronics:






Hello.

I looked at your code briefly and did not notice anything obviously wrong with it. I suspect the issue could be caused by either providing insufficient power or sending incorrect serial values. From the picture of your setup, it looks like the Maestro logic is powered by the same supply as your servos. I suspect that when the servos draw a lot of current (e.g. like having three servos moving at the same time), it causes the output of the regulator to drop which resets the Maestro. Can you try powering the Maestro logic separately from the servos? (You might also want to use a voltage higher than 5V, since that is right at the edge of the Maestro’s operating range.) Please make sure to remove the VSRV=VIN jumper.

The other possibility is that your code is sending incorrect values. Since you are passing input values to the Arduino’s serial line, can you send me the exact values you used when you encountered the error?

- Amanda

Thanks Amanda

I will change the power supply wiring tonight and let you know how it goes. Will 5 volts work for the electronics or should I go higher? For servos I will leave at 5 volts.

As for the sequence i move the elbow servo first to about -61 degrees (0, -61), then i move the should to about 72 degrees (0, 72) then when I move any amount on any of the any other servos - even opening the gripper it resets it self. By the way i only moved one servo at a time as I am still working on the interfaces. What is perplexing is that it works fine when I use the Maestro Control Center and follow the same sequence of moves.

Thanks for the help
Mike

UPDATE: I powered the servos separate from the Maestro, used 8v just as a test. It worked like a charm. No resetting experienced. Even tried it from the processing sketch I am working and no issue. Problem seems to be resolved at least for now :smiley:

Another quick question - does the multiple target command in the library allow the movement of the servos at the same time? If not how can I do that from the Arduino? This piece isn’t critical just curious.

Thanks again - not sure what I would have done without your help

Mike

Hi, Mike.

The “Set Multiple Target” serial servo command will set a target for each channel in a contiguous block. Essentially, each position value in the command sequence is sent in sequential order starting from the first channel number, so the command does not truly send the positions values to the block of servos at the same time. (However, there shouldn’t be any perceptible lag between each servo movement after sending the “Set Multiple Target” command.) More information about that command can be found under the “Serial Servo Commands” section of the Maestro User’s Guide.

- Amanda