Micro Maestro USB on Mac

I think Nathan has found a fix. “resetting the configuration” seems to have worked. libusb now detects my Micro Maestro on OS X and pyusb now finds my device :slight_smile:

Patches have been committed to a libusb development branch and hopefully should be included in the next release of libusb. Note: this is not an OS X driver that provides virtual com ports. It’s just the libusb user space tools.

Cheers, Brendan.

Hello Brendan. Thank you for your efforts.

I have emailed Nathan Hjelm directly and offered to help him.

–David

hi
sorry about this being a late post but has anyone successfully completed this? im new to all of this coding and i have only really worked in apple’s Xcode but i want to venture out for the mini maestro 6 and dont know where to start

Michael

Hello, laxhead94.

Here is some example C++ code for Maestro+libusb from a post by CarrotSnack, slightly modified by me:

#include <iostream>
#include <libusb-1.0/libusb.h>
#include "protocol.h"

using namespace std;

bool deviceMatchesVendorProduct(libusb_device *device, unsigned short idVendor, unsigned short idProduct)
{
    libusb_device_descriptor desc;
    libusb_get_device_descriptor(device, &desc);
    return idVendor == desc.idVendor && idProduct == desc.idProduct;
}

void setTarget(int position, int servo)
{
    const unsigned short vendorId = 0x1ffb;
    unsigned short productIDArray[]={0x0089, 0x008a, 0x008b, 0x008c};
    libusb_context *ctx=0;
    libusb_device **device_list=0;
    libusb_init(&ctx);
    int count=libusb_get_device_list(ctx, &device_list);
    for(int i=0;i<count;i++)
    {
        libusb_device *device=device_list[i];
        {
            for(int Id=0;Id<4;Id++)
            {
                if(deviceMatchesVendorProduct(device, vendorId, productIDArray[Id]))
                {
                    libusb_device_handle *device_handle;
                    libusb_open(device, &device_handle);
                    libusb_control_transfer(device_handle, 0x40, REQUEST_SET_TARGET, position*4, servo, 0, 0, (ushort)5000);
                    libusb_close(device_handle);
                    break;
                }
            }
        }
    }
    libusb_free_device_list(device_list, 0);
    libusb_exit(ctx);
}

int main()
{
    while(1)
    {
        int position;
        int servo=0;
        cout << "Enter position: ";
        cin >> position;
        setTarget(position, servo);
    }
    return 0;
}

Please note that one flaw of the code above is that it does not check any of the return codes provided by the libusb functions so it will be hard to debug if something goes wrong.

Even though this code was written for Linux, I think it will work with minimal modification on a Mac. You will need to download, build, and install Libusb. Then should be able to compile the code above either in XCode or with a command like:

c++ test.cpp -lusb-1.0 -o test

Good luck. Let us know if you have any problems.

–David

thanks david, i will give that a try. one more thing, do you know of and material to learn these codes, i have only done one or two projects with C and C++ so it is extremely new to me.

thanks, Michael

The libusb-1.0 documentation is here:
libusb.sourceforge.net/api-1.0/

If you need to send any commands to the Maestro other than the Set Target command, you should look at the functions in the Usc class in the Pololu USB SDK in order to see what commands are available and what the protocol is.

–David

I’m replying almost a year after this was first asked because I ran into the same problem.
Here is the solution.
The Micro Maestros ship with SERIAL_MODE_UART_DETECT_BAUD_RATE as the default.
This seems to enumerate as a CDC device, but the Maestro is not listening to USB in its default mode.
Using “Maestro Control Center” while running Windows is somewhat inconvenient for Linux and OS-X, but that is the easiest way to change the default serial mode setting.
Once SERIAL_MODE_USB_DUAL_PORT is set as the serial mode,
the Maestro will listen to commands over USB.
I also use pyserial. Here is a code fragment:

import serial
s=serial.Serial()
# lower port # is command port
s.port="/dev/tty.usbmodem00022961"
s.baudrate=115200
s.timeout=1
s.open()

def setpos(pos):
    """pos is 0.25us increments centered about 1500us +/- 500us
    so range is 4000..8000
    """
    low=pos&0x7f
    high=pos>>7
    #print low,high
    # cmd, chan, low, high
    s.write(chr(0x84)+chr(0x00)+chr(low)+chr(high))

It is also possible to use libusb via pyusb after unloading the USB CDC driver.
Read the man page for kextunload.
There are separate drivers for Control, Data, and the base class.
Here is a pyusb code fragment to set the serial mode to “USB Dual Port”:

device.ctrl_transfer(0x40, 0x82, 0, ((1<<8)+3))

Use kextload to reload the CDC drivers to use pyserial.

I installed mono and libusb and set serial mode to USB dual port using a windows box.

I was able to run the linux version of Maestro Control Center, but I got the following error:

“There was an error while starting up. libusb-1.0”

any ideas?

Hello. We don’t support running the Maestro Control Center on Mac OS X, but from the error message I would guess that you didn’t install the right version of libusb (1.0).

–David

ok. How about the bash script? I found two cu.usbmodem**** when I connected Micro Maestro. I tried

./servo3.sh /dev/cu.usbmodem00038283 0 900
and
./servo3.sh /dev/cu.usbmodem00038281 0 900

Nothing happened with either. Any suggestions?

I guess you are talking about the bash script found in the Serial Example Code > Bash Script section of the Maestro user’s guide. That bash script has instructions at the top of it that tell you how you need to configure the Maestro. Did you follow those instructions? What serial mode is your Maestro in?

–David

I’ve read info that recent versions of OS X do not allow the USB CDC drivers to be unloaded, which is required to claim the device and communicate using native USB control transfers.
The current solution offered is to write a codeless kernel extension (kext) which matches the USB device Vendor ID and Product ID, so that the OS X CDC driver wont claim the device. I think that the codeless kext can then be unloaded and a userspace app can then claim it and use the native usb control transfer.

To me that seemed like a bit of a hassle, especially if you are not a developer. It would be good if someone could contribute such kext to Pololu so they can upload it to the resource page :slight_smile:

Now another solution could be if the USB descriptors in the Maestro did not contain the CDC interface classes (2 and 10), and just have the proprietary interface class (255). That way no kext should claim the device and the userspace app is free to claim it and use it :slight_smile:

Is it possible to have two versions of the firmware – one with the full usb descriptors, and one with only the proprietary descriptors ??
Given that native usb is the preferred/recommended method of communication, one could suggest that the having only the proprietary descriptors should be the default ??

Any thoughts ??

Also I think that Dual USB mode should be the default configuration.

Hello, Brendan

I think that’s true, but it should not be a problem for the Maestro. The Maestro is a composite device with 5 interfaces. If I recall correctly, the first interface is the native USB interface, the next two are linked together and represent the CDC ACM command port, and the last two are linked together and represent the CDC ACM TTL port. The USB CDC drivers should not be messing with the native USB interface, so you should be able to connect to that one and do control transfers using libusb.

We made “UART, auto detect baud rate” mode be the default to give people the option of using the Maestro without touching USB at all.

–David

I’m not sure that is true on OS X (I’m using 10.7.5). Nathan (libusb OS X author) says:

So it sounds like we need to make OS X not load the drivers (because one of them wont release the device when asked). Codeless kext is a solution, but it feels a little messy to me, and you may have to have several for different USB devices and different versions of OS X.

Having a version of Meastro firmware with only the descriptors modified so that only the proprietary interface is present means the OS will not load the CDC drivers, and OS X would be free to talk using native USB :slight_smile: So could we have two versions of the firmware? One with full descriptors and one with minimal descriptors ?? I’m happy to use Windows (via VirtualBox) to reprogram my Meastro. BTW, using native USB in Windows/VirtualBox works fine :slight_smile:

BTW, interface class 255 is proprietary. Is there any information on how to use this proprietary interface ?? I believe this is different to native usb using control_transfer() – but maybe I misunderstand ??

You should do what Nathan suggests above. (You don’t need to claim the USB interfaces used for the virtual COM ports; the native USB interface is more powerful than those interfaces combined.) The only documentation we have for the Maestro’s native USB interface is in Usc.cs in the Pololu USB SDK, but that should be enough for you to figure out what you need. For basic use, you should look at the setTarget method and see what kind of control transfer it uses.

If you have trouble doing this, please post your code here. We have a Mac here that runs 10.7.3 so I can test your code on my machine and probably get it working. I recommend using libusb 1.0 and libusb_control_transfer.

–David

Hi all, I realize this is an ancient thread. However, after dealing with lots of strange issues with the serial device on Mac/OSX I just broke down and used libusb. Here’s a really crappy UDP server that reads x y data from UDP packets and controls 2 servos accordingly: gist.github.com/asm/8b5217ed6d688c26ad70. Hopefully this will help someone :slight_smile:

Note the controller sends its data back in packed form so the structs in the protocol.h that comes with the SDK won’t work on architectures that byte align.

Hello.

Thank you for posting your UDP server code! We have added a link to it in the “Related Resources” section of the Maestro User’s Guide.

–David