Problem with getMovingState() using serial

I understand there was a recognized issue with getMovingState() used over serial lines. I have MicroMaestro connected to Teensy 3.2 and sending setTarget () works fine. However, getMovingState() always returns a 0. Has this issue been resolved or is there a workaround. I know Maestro is 5v while Teensy is 3.3, and I’m not using level shifting, but TX at 3.3v to Maestro 5v is working.

Thanks,
Theron

Hello, Theron.

The recommended workaround for the issue is described in the Serial Servo Commands section of the Maestro user’s guide; in short, it involves using a script on the Micro Maestro to wait for movement to end instead of using the “Get Moving State” serial command.

By the way, note that the Maestro is not guaranteed to read 3.3V as high on the RX pin, so while it will probably still work, we recommend using a level shifter for maximum reliability. (There is also the question of whether the other device can accept the 5V from the Maestro’s TX pin, but it looks like the Teensy 3.2’s digital pins are 5V tolerant, so you should be okay there.)

Also, we moved your post to the more appropriate “Servo controllers and servos” category.

Kevin

Kevin,

Ok, tried this test using Arduino Nano to Micro. It sometimes returns 0 on first loop, but then 1 immediately thereafter. I am using a gearservo, SG12 Series Servo Gearbox (5:1 Ratio, 640° Rotation, 1750 oz-in, 0.80 sec/60°) - ServoCity but wouldn’t think this would matter as it responds corrently to setTarget commands. Here’s my code and output.

// Test getMovingState
#include <PololuMaestro.h>
#include <SoftwareSerial.h>
SoftwareSerial maestroSerial(10, 11);
MicroMaestro maestro(maestroSerial);
byte c = 0;

void setup()
{
  // Set the serial baud rate.
  maestroSerial.begin(115200);
  Serial.begin(115200);
  delay(4000);
}

void loop()
{
  // Set the target of channel 0 to 1500 us
  Serial.println(millis());
  maestro.setTarget(0, 6000);
  maestro.restartScript(0);
  c = 0;
  while (c == 0)
  {
    c = maestro.getScriptStatus();
    Serial.println(c);
  }
  Serial.println(millis());
  Serial.println("-----");
  delay(4000);
  // Set the target of channel 0 to 7121 us
  Serial.println(millis());
  maestro.setTarget(0, 6000 + int(90.0F * 3.115F * 4.0F));
  maestro.restartScript(0);
  c = 0;
  while (c == 0)
  {
    c = maestro.getScriptStatus();
    Serial.println(c);
  }
  Serial.println(millis());
  Serial.println("*****");
  delay(4000);
}
3999
0
1
4000
-----
8001
1
8002
*****
12002
0
1
12004
-----
16004
0
1
16006
*****
20005
1
20007
-----
24007
1
24008
*****
28009
0
1
28010
-----

Hi, Theron.

What are the speed and acceleration settings for the channel your servo is connected to? Could you post the settings file from your Maestro? You can save the settings file from the File menu in the Maestro Control Center.

Kevin

Kevin,

In the beginning of the program I have set things at the default, 0 values. Later I do some calculations to slow things up somewhat to keep the servo following the movements of a stepper motor.

Theron

I tested your program with an Arduino Uno and a Micro Maestro and it seems to work as expected. Can you confirm that wait_for_movement_to_end is the first or only script subroutine on your Maestro? Could you try manually setting the speed limit for channel 0 to a known value (such as 100) for testing and see if that makes any difference? (Just to be clear, the Maestro can only report if servos are still moving when the target positions are limited by speed or acceleration settings; it has no way of knowing the actual position of the servos.)

Also, I would still like to see your settings file so we can check for any other possible issues.

Kevin

Kevin,

Thank you for staying with me on this. Here is the current test program. It moves from 6000 to 8800 at a slow speed (I’ve set speed to 10), then it only returns 0’s and does not move back to 6000. Attached screen grabs of maestro settings. I think I’m making progress. I didn’t understand that there needs to be a setSpeed command in the program and was trying to use default. Do I need to setSpeed every time I setTarget? I’m not sure I know what you mean by settings file.

Ooops, forgot the program.

// Test getMovingState
#include <PololuMaestro.h>
#include <SoftwareSerial.h>
SoftwareSerial maestroSerial(10, 11); // RX, TX
MicroMaestro maestro(maestroSerial);
byte c = 0;

void setup()
{
// Set the serial baud rate.
maestroSerial.begin(115200);
Serial.begin(115200);
delay(4000);
Serial.println("Starting");
}

void loop()
{
// Set the target of channel 0 to 1500 us
Serial.println(millis());
maestro.setSpeed(0, 10);
maestro.setTarget(0, 6000);
maestro.restartScript(0);
c = 0;
while (c == 0)
{
c = maestro.getScriptStatus();
Serial.println(c);
}
Serial.println(millis());
Serial.println("-----");
//delay(2000);

// Set the target of channel 0 to 8800 us
Serial.println(millis());
maestro.setSpeed(0, 10);
maestro.setTarget(0,8800);
maestro.restartScript(0);
c = 0;
while (c == 0)
{
c = maestro.getScriptStatus();
Serial.println(c);
}
Serial.println(millis());
Serial.println("*****");
// delay(2000);
}

Can you send me a copy of your working Uno program?

Theron

The program I tested with was exactly the one you posted here with no changes.

For channel settings like the speed limit, you can set default values through the Channel Settings tab of the Maestro Control Center; after these settings are applied, those defaults will persist on the Maestro (even when it is reset or powered off). You can also override the defaults on the Status tab of the Control Center or through serial commands (which is what the setSpeed() Arduino function uses); if you do so, the override will stay in effect until it is changed again or until the Maestro is reset or power cycled. So you do not need to call setSpeed() every time you call setTarget() (unless you actually want to set a different speed for the next movement), but you do need to have an appropriate non-zero speed limit set for the wait_for_movement_to_end script to behave meaningfully.

You can save a settings file through the File menu of the Control Center software.
image

Kevin

Kevin,

Again, thanks for your help. I finally found my mistake, exceeding Max amount in channel settings. So it’s going back and forth OK, but it doesn’t quite appear to hit the target angle before it starts back in the other direction. Is this possibly a settings thing?

Thanks, Theron

I’m glad to hear you figured out one problem and seem to be making progress. When you say it doesn’t quite appear to hit the target angle, do you mean that it reverses while it is still moving (before reaching its original target), or that it stops short of the target and is stationary for a while before reversing?

Kevin

It reverses while it is still moving before reaching its original target. This becomes obvious when one of the targets is 6000, the middle position. I’m seeing this on the servo gearbox motor from ServoCity. https://www.servocity.com/sg12-series-servo-gearbox-5-1-ratio-640-rotation-1750-oz-in-0-80-sec-60/ at a setSpped of 10.

When using a regular servo this doesn’t appear to happen at speed 10, but does show up at speed 100.

Don’t know why it should be different. The gearbox just reduces the gear ratio on the potentiometer allowing for more turning of the big gear before it comes to equilibrium.

Theron

I think probably what is happening is that your servo cannot keep up with the Maestro when you set the speed limit to 100. If you further increase the speed limit to 150, for example, does it still turn at the same speed?

As I mentioned before, the Maestro can only determine whether a servo is still moving if the Maesto itself is limiting how fast it can move (in other words, if the Maestro is commanding the servo to move no faster than the servo is capable of moving). Otherwise, if the servo is not keeping up, the Maestro has no way of knowing that, since the standard RC servo interface does not provide a way for the controller to sense the servo’s position.

If that is the case in your setup, you’ll want to experiment with speed limits between 10 and 100 to find a limit that matches or is just under the maximum speed the servo can attain. Once the speed limit is set appropriately, the wait_for_movement_to_end script should work as expected.

Kevin

Kevin,

That makes sense. I’ll do some experiments tomorrow. Thanks for all your help.

Theron

Kevin,

Did the math. The gear servo’s top speed is 75 degrees/sec. So working that out it looks like 9 is the highest I could go on setSpeed().

Theron