Getting odd position values based on channel (Micro Maestro)

I’m using c++, linux, usb and a Micro Maestro to control two servos.

The servo on channel 0 moves as expected with the position read back from the controller varying from 4000-8000 (corresponding to 1 and 2ms). If I command the servo all the way to one side and then to the other I can see the intermediate position values.

The servo on channel 1 reports 40975 at one extreme and 16415 at the other. The intermediate positions are given.

If the servo from channel 1 is switched to channel 2 the values are correct (4000-8000) but the intermediate values are not given. The current position read back from the controller is immediately the commanded value.

Moved to channel 3 the extremes become 2575 and 2591, and intermediate values are not shown.

I tried swapping the servos themselves, and using a different micro Maestro. I tried the windows based servo control application without issue. I am using the same code to perform all the functions so I’m not doing anything differently with each channel.

Is this a controller firmware issue?

Hello.

This could also be bug with your C++ code. Could you show us the simplest possible code that reproduces the problem? Or better yet, describe how to reproduce the problem using only Pololu software if it is possible.

Are you using the Maestro’s native USB interface or the virtual COM port?

How did you configure the Maestro? Did you use the Maestro Control Center or have you written you own software that sets configuration parameters? If there is any doubt about the Maestro’s configuration, I recommend resetting it to its default settings (using the appropriate menu item in the Maestro Control Center) and then changing the serial mode to USB Dual Port so it won’t be in auto-baud-detect mode.

I’m not totally sure what you mean by “see intermediate position values”, but if you enabled a speed or acceleration limit on some channels but not on others, that would explain what I think you’re trying to describe.

–David

I just noticed the following:

4000 = 0x0FA0
8000 = 0x1F40

40975 = 0xA00F (4000 with bytes flipped)
16415 = 0x401F (8000 with bytes flipped)

2575 = 0x0A0F
2591 = 0x0A1F

I suspect you are doing something wrong with a “unsigned char *” pointer in your C++ program. That’s why it will be good to post the simplest code that demonstrates the problem.

–David

I’m using code ported from the usc.cs file provided. I’m using this code to set the parameters.

By intermediate position values I mean set the position to 1ms and the speed to 1, then command the position to 2ms. while the servo is moving monitor the position output from the controller. On the working channel the values will change on the way to 2ms. on the channels I’m having issues with the value immediately changes to whatever the 2ms represented value is and stays there until the servo has finished moving. it’s as if the target is being returned rather than the position.

I’m going to check through the structures and make sure I have all the variable types correct (sizes etc)

To wrap up the issue:

It turned out to be a problem with the structure packing gcc was applying to the servo and micromaestrovariables structs.
gcc applied 2 byte packing to the structure, this meant that servo[0] appeared correct and all the others were thrown off by the fact that the servo struct’s last value is a single byte

I surrounded the structure definitions with:

#pragma pack(1)

… stuct def here

#pragma pack()

problem solved