Micro Maestro baud rate when connected to A-Star?

I’ve successfully connected A-Star Micro -> Micro Maestro -> servo and driven the servo using the sample sketches included with the PololuMaestro library. I’m pretty experienced with the A-Star, and used a Maestro about 2 years ago, but the excellent documentation is what allowed me to go from a handful of parts to a working test system very quickly. Great job, Pololu!

I do have a question, however. Per the documentation, I configured a Micro Maestro (MM) with the Control Center to use 9600 baud. That matches the 9600 baud rate in the MicroMaestro constructor invocation. Assuming I match the baud rate via the Control Center and in the constructor, can I use a higher baud rate? If so, how high is safe? The user’s guide says the maximum baud rate is 250,000, but I don’t think I need to go that high.

I am using the A-Star to control other devices and I’d like to minimize the time budget for the Maestro. I may have missed it, but I cannot find anything that lets me draw a conclusion about my question.

Thanks.

I am glad you are having a good experience with the A-Star and Micro Maestro!

As stated on the product page for the Micro Maestro, the maximum supported baud rate is 200000 bits per second. I have corrected the number in the “TTL Serial” section of user’s guide to match the product page; thanks for bringing that to my attention.

We have multiple products with “A-Star” and “Micro” in the name. If you could tell me the exact name of the A-Star you are using, that would help me see what baud rates might work best for you. With baud rates this high, it becomes important to consider the details of the clocks on both sides and how baud rates are generated to make sure that the baud rates will end up being close enough.

–David

I am chagrinned that I was not more specific… I am using the A-Star 32U4 Micro (Pololu item #: 3101).

I infer from your reply that if I configure the Micro Maestro baud rate via the Control Center and match that baud rate in the MicroMaestro constructor in my code, I can use a higher baud rate. More good news! While I’m probably not the first person to wonder, it might be nice to include something in the Maestro User’s Guide about that possibility, even if the document has to also say that there are limitations based on the microcontroller and the version of the Maestro.

Thanks again for your responsiveness.

If you configure the Maestro and the A-Star correctly, it is possible to achieve successful communication with a wide range of baud rates, not just the 9600 that we use in our examples. However, correct configuration is not just a matter of using the same baud rate on both devices. You also have to consider how accurately that baud rate can be generated by each device, and be sure not to exceed the Maestro’s maximum of 200000 or its minimum of 300.

With its 16 MHz resonator, the A-Star 32U4 Micro can generate any baud rate that is 2 Mbps divided by a whole number. The Micro Maestro can generate any baud rate that is 12 Mbps divided by a whole number. This means that any baud rate that you pick for the A-Star 32U4 Micro can be matched by the Maestro. (There will still be some error due to variations in the clocks of each device, but that should be inconsequential.) A baud rate of 200000 bps should work well.

There is no baud rate argument in the MicroMaestro constructor in our library. The examples that come with the library show how to set the baud rate.

–David

Sorry to take so long to reply, but I’ve been out of town.

I made a few tests, configuring a baud rate for the Maestro via the Control Center, then used the following code to set the baud rate for the A-Star:

#ifdef SERIAL_PORT_HARDWARE_OPEN
  #define maestroSerial SERIAL_PORT_HARDWARE_OPEN
#else
  #include <SoftwareSerial.h>
  SoftwareSerial maestroSerial(10, 11);
#endif

MicroMaestro maestro(maestroSerial);

<some init code...>
  maestroSerial.begin(<baud rate>);  


<send commands to Maestro>

I did not do an exhaustive list, but here is what I found. A rate of 9600, 48000, 60000, 80000 worked, every trial (only did a few). A rate of 96000 or above (up to 20000) failed every trial.

I should probably elaborate. The so-called “send commands to Maestro” sends a couple of commands to do some initial positioning with a delay in between. As far as I can remember, these commands sent “slowly” always worked, even above 80000. Then I go into a loop where I set a target, start a script at a subroutine that waits for the target to be reached, then “wait” till the target is reached with an inner loop that gets the script status; after the target is reached there is a delay of 20 milliseconds. From what I could tell, the loop worked a handful of times (since the servo moved some), but eventually some aspect of communication failed and the servo quit moving, presumably because no more commands could be sent or responses read.

I am not sure if I’ve done something wrong or what. Any advice?

I am sorry you are having trouble using baud rates above 80000 between the A-Star 32U4 Micro and the Micro Maestro.

As I mentioned in my last post, the A-Star 32U4 Micro can only generate baud rates of the form 2000000/N, where N is a whole number. It cannot generate 96000 precisely, so it would actually use 95238 baud. Some good baud rates to try would be 100000, 125000, and 200000.

You might consider sending some debugging information to the Serial Monitor in the Arduino IDE so you can tell exactly what part of the code is running when the servo stops moving. The code for that would look liks this:

Serial.println("hello");

If you cannot figure out what is going wrong, please simplify your code to the simplest thing that should work but does not, and then post it here. Please post the configuration file for your Maestro too, and any other details that might be needed to reproduce the issue here.

–David

Ah, stupid mistake… I only worried about the Maestro 12,000,000/N and forgot the A-Star 16,000,000 had to match. That said, my initial baud rate test was 200,000, per your earlier response. It failed, but I seem to remember a slightly different result.

I will try to do some digging tomorrow, but I’m headed out of town again and it may be a while.

Thanks again for the great support.

Found time today to play. “Interesting” results.

Here is the “minimal” sketch I created for testing:

#include <PololuMaestro.h>

#ifdef SERIAL_PORT_HARDWARE_OPEN
  #define maestroSerial SERIAL_PORT_HARDWARE_OPEN
#else
  #include <SoftwareSerial.h>
  SoftwareSerial maestroSerial(10, 11);
#endif

MicroMaestro maestro(maestroSerial);

const int channel = 5;

void setup() { 
  // wait for serial monitor to open
  while (!Serial);
  Serial.println("Test Maestro baud rate");
  
  // Set the serial baud rate for Maestro
  maestroSerial.begin(100000);
  maestro.setSpeed(channel, 0); // no speed limit
}

void loop() {

  Serial.println("Position @ 5000");
  maestro.setAcceleration(channel, 100);
  maestro.setTarget(channel, 5000);
  waitTarget(channel, 5000);
  delay(1000);

  maestro.setAcceleration(channel, 0); // no acceleration limit

  Serial.println("Start loop");
  for (int i = 5010; i < 7010; i+=10) {
    maestro.setTarget(channel, i);  
    Serial.println("set target @ " + (String) i);
//    waitTarget(channel, i);
    waitTarget2();
    Serial.println("got target");
    delay(20);
  }
}

void waitTarget(uint8_t channel, uint16_t target) {
  while (maestro.getPosition(channel) != target) {
  } 
}

void waitTarget2() {
    maestro.restartScript(0);
    while (!maestro.getScriptStatus()) {  
    }
}

The interesting area is the for loop in loop(). After setting the target, note the call to either waitTarget() or waitTarget2(). As you can see from the code, waitTarget() uses the get_position command to wait for the servo to reach the target; waitTarget2() uses the restart_script_at_subroutine command to allow the following script (stolen from the User’s Guide) to wait for the servo to reach the target.

sub wait_for_movement_to_end
  begin get_moving_state while repeat
  quit

In theory, waitTarget() and waitTarget2() should perform exactly the same function.

Note that in the for loop, speed and acceleration are set to 0. As I understand, that means that once the target for servo is set, from the Maestro perspective, the position of the servo is at the target (since there is no feedback, the actual position cannot be determined). That means that both waitTarget() and waitTarget2() should immediately return, so in truth, both are superfluous.

Now, things get interesting. As you can see, I’ve set the Maestro baud rate to 100,000. When I use waitTarget(), the sketch works! But when I use waitTarget2(), the sketch fails after 20 or so iterations of the for loop! From my perspective, the only difference is the behavior of get_position versus restart_script_at_subroutine.

I’m not really sure what this means. Maybe the restart_script_at_subroutine does not work as I interpret the User’s Guide. Maybe I’m doing something else wrong.

I decided to try 200,000 using waitTarget(). Unfortunately, the sketch does not appear to work at all even in this simple scenario. In the serial monitor window, I see “Position @ 5000” and that is all. Apparently even the get_position command does not work (well) at that speed. Again, I am puzzled.

One more thing that I should add. I’ve had this Maestro for a long time. The firmware is at 1.02. Should I update? I am a bit hesitant to do so because I’m running the Control Center in Windows 8.1 in the Parallels desktop on MacOS. Seems like a recipe for disaster.

Thanks again for any insight you can offer.

I was able to reproduce your problem here and discovered that there is a bug in the Micro Maestro firmware that can cause it to get stuck in an infinite loop if it receives serial commands too frequently. Also, receiving serial commands can cause inaccuracies in the way the Micro Maestro applies speed and acceleration limits. This bug only affects Micro Maestro 6-Channel USB Servo Controller.

We have started working on a firmware update to fix this, and we should be able to publish it in the Maestro user’s guide by the end of next week. I will post here when it is available. Until then, you might consider using lower baud rates or delaying for about 100 microseconds in any loop where you are repeatedly sending commands to the Maestro.

Thank you for providing enough information for us to identify this issue that has gone unreported since the Micro Maestro was first released nearly 10 years ago! Sorry for any inconvenience this has caused you.

–David

We just published Micro Maestro firmware version 1.04, which fixes this issue. The “Upgrading Firmware” section in the Maestro user’s guide has upgrade instructions. If you decide to try the new firmware, please let us know how it works for you. Thanks again for letting us know about this problem.

–David

I updated the firmware in my Micro Maestro to 1.04 and ran the test sketch from our earlier exchange with the baud rate of 200,000. It worked great! I then ran a more complex test, akin to what I really want to do, and it too worked perfectly!

Thanks for the excellent customer support…

I have another question or two.

The user’s guide says “A speed of 0 makes the speed unlimited, so that setting the target will immediately affect the position.” Is this true if acceleration is non-zero?

If I understand correctly, when speed and acceleration are set to 0 for a servo channel, once the target for servo is set, from the Maestro perspective, the position of the servo is at the target. I think that means that the getPosition() command immediately returns the target, and getScriptStatus() immediately returns “done”, so in truth, both are superfluous calls. Is all this true?

I think it should be possible to create a script that allows me to send the restartScriptWithParameter() with a parameter that is the target, and in the script set the target and then do the get_moving_state loop. Thus from the Arduino I could reduce the number of commands issued. I think the Arduino would still have to loop waiting for the script to finish (depending on speed/acceleration). Should this work?

Thank you for pointing out that issue in the Maestro user’s guide. I have changed it to say:

A speed of 0 makes the speed unlimited. Setting the target of a channel that has a speed of 0 and an acceleration 0 will immediately affect the channel’s position.

If you are setting the target of a servo channel and you know the channel has a speed of 0 and an acceleration of 0, then using getPosition or getScriptStatus to monitor the progress of that channel moving towards its target is indeed superfluous. (However, if you do use getScriptStatus, it might not immediately return 1; it will only return 1 after the script has stopped, and it will take the script some small amount of time to stop.)

Your plan to use the restartScriptWithParameter command should work.

–David