How can I get the position of the servo with Micro Maestro?

Hi! First of all, I’m sorry about my English and aboute my question because I am quite noob in this subject.

I am trying to get the position of a servo using unmanaged code and the libusb-win32 library and C++ language. I’ve noticed I should send the REQUEST_GET_VARIABLES to get the info about the servos but I am not able to get it and I have not found and example to do this on the Internet.

I wrote this function based on the code of Usc.cs:

unsigned short PosicionServo (usb_dev_handle *dev, int servo)
{

    short[] stack;
    ServoStatus[] servos;
    getVariablesMicroMaestro(out variables, out stack, out callStack, out servos);*/
    uscVariables variables;
    char *aux = new char[BUF_SIZE]; //= new char [sizeof(uscVariables) + 6 * sizeof(servoSetting)];
    int ret = usb_control_msg(dev, 0xC0, REQUEST_GET_VARIABLES, 0, 0, aux,BUF_SIZE, 5000);
    short *stack;
    unsigned short *callStack;
    servoSetting *servos = new servoSetting[6];
    char *pointer = aux;
    // copy the variable data
    uscVariables tmp = *(uscVariables*)pointer;
    variables.stackPointer = tmp.stackPointer;
    variables.callStackPointer = tmp.callStackPointer;
    variables.errors = tmp.errors;
    variables.programCounter = tmp.programCounter;
    variables.scriptDone = tmp.scriptDone;

     for (byte i = 0; i < 6; i++)
     {
            servos[i] = *(servoSetting*)(pointer + sizeof(uscVariables) + sizeof(servoSetting) * i);
     }

     stack = new short[variables.stackPointer];
     for(byte i = 0; i < variables.stackPointer; i++) { stack[i] = *(tmp.stack+i); }
     callStack = new unsigned short[variables.callStackPointer];
     for (byte i = 0; i < variables.callStackPointer; i++) { callStack[i] = *(tmp.callStack + i); }
     ret = servos[1].position;
     printf("\nServo's position is %d\n", ret/4);
     return ret;
}

Thank you very much.

Hello, mxypltzx.

You did not post your entire code. Your code is not checking the error codes returned by the libusb functions. You didn’t tell us what happened when you tried to run the program. All of these things make it hard to help you with your code.

Besides, I think it is not a good idea to use libusb-win32. To use libusb-win32, you will have to change the Maestro’s drivers so it uses libusb, and that could be difficult. Here are some better alternatives:

  1. Use the example Visual C++ code in the Pololu USB SDK.
  2. Send commands to the Maestro using its virtual serial port. You will need to set the Maestro’s serial mode to USB Dual Port.
  3. Write your own code that uses WinUSB functions from Winusb.dll to talk to the Maestro.
  4. Use the windows backend of libusb 1.0. I have never tried this so I’m not sure it will work.

If you are already using .NET, I recommend #1.

–David

Hello.

Please also note that a servo controller cannot know a position of a servo. It can only know what position it is commanding the servo to go to.

- Ryan

Thank you very much for the help. I use libusb because I saw it in an example of this forum:

The problem with the example in the SDK is that it is managed code and I need it to be unmanaged so I have to write my orders to the USB port. When I use the usb_control_msg(dev, 0xC0, REQUEST_GET_VARIABLES, 0, 0, aux,BUF_SIZE, 5000) the info I got is stored in a char * aux and I don’t know how to take that info to use it.

I know that the controller can’t know the position of the servos but it knows where it is commanding the servo to go and, if it has already arrived to that postion, it holds it. When I work with the code provided in the SDK I have not problem to get that position which is in ServoStatus but it is written in C# and I need it in C++.

Thank you very much again and I will notice you if I have success with this.

Your code is not checking the return value of usb_control_msg. Are you sure it succeeded?

WinUSB and the SetupAPI are complicated, so I recommend that you use the Maestro’s virtual COM port. Here is some example code that reads the position of a servo, using Serial+C+Windows:

Just remember to configure your Maestro’s serial mode to be USB Dual Port.

–David

Yes, the usb_control_msg is woking because it returns 140 bytes received, which is the number expected.

However, I would give a try to the serial mode because it looks very useful. Thank you very much for the help.