[libusb] linux/windows set position with unmanaged C++

I saw in the usb sdk that the C++ example ran on .NET so I’ve made a quick example using libusb and unmanaged C++. I’ve tested it on Ubuntu 10.10 netbook edition and windows 7. I’ll later be testing this on a Gumstix overo-worked.

#include <iostream>
#include <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;
}

maestro.zip (3.76 KB)

Hello,

That’s great - thanks for posting this example. This is libusb-1.0, right, not 0.1? Could you also post your Makefile for other people who might want to try it? We will also be really interested to know what happens on the Gumstix.

-Paul

It does use libusb-1.0, I’ll post the files and whether the Gumstix worked with it next weekend.

After a lot of fiddling with bitbake I eventually managed to compile it for the gumstix. It worked on the gumstix perfectly with both a servo and a brushless motor with an esc.
I’ve only ever used makefiles, never made them but it doesn’t seem complicated, I’ll post one soon.

Edit: Thought I might mention I created this by looking at MainWindow.h, Usc.cs and UsbDevice.cs in the SDK and rewriting the minimum amount of code to set a position in C++. It should also work as C with some quick changes.

Hi,

wow - that is exactly what I need as well - great job! :slight_smile:
I’m using Ubutu 10.10 as well and I’m not realy an expert in coding on linux (yet :wink: ), but I tried to compile your file and had a view problems. It seems that I’m missing something :wink:
What am I doing wrong?

I copied protocol.h from “sdk/Maestro/protocol.h” and added a view lines at the beginning:

typedef unsigned int u32;
typedef unsigned short int u16;
typedef unsigned char u8;
typedef signed short int s16;

The Mini Maestro 12 Controller is plugged in via USB and set to “USB Dual Mode”

Than I tried to compile your file with this command:
c++ test.cpp -I/usr/include/libusb-1.0 -o test

But I got some errors:

/tmp/ccsW2it5.o: In function `deviceMatchesVendorProduct(libusb_device*, unsigned short, unsigned short)':
test.cpp:(.text+0x22): undefined reference to `libusb_get_device_descriptor'
/tmp/ccsW2it5.o: In function `setTarget(int, int)':
test.cpp:(.text+0x81): undefined reference to `libusb_init'
test.cpp:(.text+0x93): undefined reference to `libusb_get_device_list'
test.cpp:(.text+0xf6): undefined reference to `libusb_open'
test.cpp:(.text+0x140): undefined reference to `libusb_control_transfer'
test.cpp:(.text+0x14b): undefined reference to `libusb_close'
test.cpp:(.text+0x188): undefined reference to `libusb_free_device_list'
collect2: ld returned 1 exit status

Any Ideas what I did wrong?

Greetings from Germany,
Steven

I’d bet that the problem relates to this being a C-compiled library and you using a C++ source file.

Try surrounding your include statement with:

__BEGIN_DECLS
#include “sdk/Maestro/protocol.h”
__END_DECLS

…which is the equivalent of doing:

#ifdef __cplusplus
extern “C” {
#endif
#include “sdk/Maestro/protocol.h”
#ifdef __cplusplus
} /* extern “C” */
#endif

…which in turn will advise the compiler to use a C naming convention for the methods in the library. Should fix the linking problems.

You’re getting linking errors because you didn’t include the -lusb-1.0 option which tells the linker to use libusb.

–David

Okay, well, that sounds good too. :slight_smile:

Added makefile to first post

You are really quick :slight_smile:
Thank you! I’m now able to compile it. You were right:

c++ -I/usr/include/libusb-1.0 -lusb-1.0 test.cpp -o test

Greetings,
Steven

Hi dear Pololu users,

I was testing the C++ example code and I am having a small problem.
so far I tested the code in 3 machines with ubuntu (9.10, 10.04 and 10.10)
the code code compiles well, but when I send several servo positions
(one after an other) the servo stops moving after 350 servo positions
(in one machine actually sent 520). I have to restart the program in order to
send more servo positions

Probably I am sending the positions to fast. However, I tested with a wait-step
and it did not work.

do i have to configure my pololu servo controler before executing this program???
am I sending too fast theservo positions?
any ideas to fix this problem??

thank you for your help
Julio


After adding the
libusb_exit(ctx); (just like carrotSnack mentioned)

the USB example works. Thank you!!!

I also changed the files in the attachments
they should be working now.


cosine.zip (3.85 KB)

Facepalm! I found out what the problem was, I forgot to include libusb_exit(ctx); at the bottom of setTarget(), I’ve updated the code in my first post so try it out and it should now work :smiley:

I’m glad you were able to fix it!

You were probably running out of memory. Most of the libusb functions have return codes (such as LIBUSB_ERROR_NO_MEM) that tell you whether there was an error or not. I recommend that you check those return codes in your program and if there is an error code then you should print it and exit. This will make it easier to debug future problems.

–David

Thank you guys
I really appreciate your help

I will test the code right now.

I also would like to share
some code I generated using Perl. Basically
It does the same as in the C++ version
(see above cosine.zip)

Ubuntu-Linux to Mini-Maestro 12 (/dev/ttyACM0)

Greetings
Julio
serial.zip (902 Bytes)

Hi,

Thanks for the code. That is exactly what I needed. I am trying to port the code over to a gumstix and I am having problems with the recipe. Any chance you could give me a few pointers on what you did with your recipe and with the cross compiler? I’ve spent hours trying to figure it out without any success.

-Scott

First off bitbake libusb, then extract the maestro folder in the attached zip to your user recipes and bitbake maestro. In the bitbake file replace with your own.
Remember to increase the revision number in the bitbake file every time you make a modification.
maestro.zip (4.18 KB)

Hello, Brown.

In another thread, ChisBob has posted his kernel module for sending commands the Maestro. He wrote it specifically for a Gumstix. I thought this might help you.

–David

Hi guys,

our application is finally working :slight_smile:
We build a little Wrapper around the C+±Code so you have a C+±Class to work with.

Here are the source-files:

and you of course need libusb-1.0.

Here you find a little video about our finished project - it was for so called “Studienarbeit” :wink:
http://www.youtube.com/watch?v=24lgaq8CVGY

Greetings from Germany,
Steven

Hello, Steven.

I’m glad that things worked out for you. Thanks for sharing your code and the video!

–David

Im sorry , but im having trouble setting up libusb in Visual C++ Express . If anyone could give me any instructions on how to get it running I would be incredibly in his/her debt.

Cheers .