Communicate with USB device in C# using LibUsbDotNet


LibUsbDotNet is a cross-platform library. The source code below has been tested on Mac OS X (version 10.6.8 to be precise) using the Mono .NET run-time. On Linux and Mac LibUsbDotNet requires libusb.

On Mac OS X, you’ll need to obtain and build libusb from source. Ensure you have downloaded and installed the developer SDK for Mac. To build and install it, execute the following commands from a terminal, in the folder that contains the source of libusb.

./configure CC="gcc -m32" --prefix=/usr
make
sudo make install

The following source code snippet is an example of how to send data to a device. The code itself is a heavily modified version of the Read.Write example that ships with LibUsbDotNet.

public static UsbDevice MyUsbDevice;

#region SET YOUR USB Vendor and Product ID!

public static UsbDeviceFinder MyUsbFinder =
    new UsbDeviceFinder(0x0000, 0x0000); // specify vendor, product id

#endregion

public static void Main(string[] args)
{
    ErrorCode ec = ErrorCode.None;

    try
    {
        // Find and open the usb device.
        MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);

        // If the device is open and ready
        if (MyUsbDevice == null) throw new Exception("Device Not Found.");

        // If this is a "whole" usb device (libusb-win32, linux libusb)
        // it will have an IUsbDevice interface. If not (WinUSB) the
        // variable will be null indicating this is an interface of a
        // device.
        IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
        if (!ReferenceEquals(wholeUsbDevice, null))
        {
            // This is a "whole" USB device. Before it can be used,
            // the desired configuration and interface must be selected.

            // Select config
            wholeUsbDevice.SetConfiguration(1);

            // Claim interface
            wholeUsbDevice.ClaimInterface(1);
        }

        // open read endpoint
        UsbEndpointReader reader =
            MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep02);

        // open write endpoint
        UsbEndpointWriter writer =
            MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep03);

        // write data, read data
        int bytesWritten;
        ec = writer.Write (new byte[] { 0x00, 0x00 }, 2000, out bytesWritten); // specify data to send

        if (ec != ErrorCode.None)
            throw new Exception (UsbDevice.LastErrorString);

        byte[] readBuffer = new byte[1024];
        while (ec == ErrorCode.None)
        {
            int bytesRead;

            // If the device hasn't sent data in the last 100 milliseconds,
            // a timeout error (ec = IoTimedOut) will occur.
            ec = reader.Read(readBuffer, 100, out bytesRead);

            if (bytesRead == 0) throw new Exception("No more bytes!");

            // Write that output to the console.
            Console.WriteLine(BitConverter.ToString(readBuffer, 0, bytesRead));
        }

        Console.WriteLine("\r\nDone!\r\n");
    }
    catch (Exception ex)
    {
        Console.WriteLine();
        Console.WriteLine((ec != ErrorCode.None ? ec + ":" : String.Empty) + ex.Message);
    }
    finally
    {
        if (MyUsbDevice != null)
        {
            if (MyUsbDevice.IsOpen)
            {
                // If this is a "whole" usb device (libusb-win32, linux libusb-1.0)
                // it exposes an IUsbDevice interface. If not (WinUSB) the
                // 'wholeUsbDevice' variable will be null indicating this is
                // an interface of a device; it does not require or support
                // configuration and interface selection.
                IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
                if (!ReferenceEquals(wholeUsbDevice, null))
                {
                    // Release interface
                    wholeUsbDevice.ReleaseInterface(1);
                }

                MyUsbDevice.Close();
            }
            MyUsbDevice = null;

            // Free usb resources
            UsbDevice.Exit();

        }

        // Wait for user input..
        Console.ReadKey();
    }
}

Here’s a sample output produced by the code.

00-02-00-00-00-00-00-06-00-00-00-07-00-00-00-02-01-01-01
IoTimedOut:No more bytes!

The same code should run on Windows and Linux. For more details see the documentation page of LibUSBDotNet. They have a really nice wizard that can create an INF and installer package for Windows.

If Mono raises a System.DllNotFoundException, you might want to take a look at this page.

7 thoughts on “Communicate with USB device in C# using LibUsbDotNet

  1. Thanks! It worked excellent.

    Correct me if I’m wrong, but there are 2 small issues solved here:
    1) By default libusb-1.0 will install to ‘/usr/local/lib’ and mono will not find it
    2) Mono is 32bit so without the ‘-m32’ configure switch, libusb-1.0 will build a 64bit library on 64bit machines and mono cannot use it.

  2. This is really cool. Is it possible to use this to talk to an application running on an Android using this? I’ve written one using sockets to have the PC and Android communicate over WiFi. But, it’s not fast enough to meet my application’s needs.

  3. I am trying to get this to work I have libusbdotnet working on windows and Linux for my LEGO Mindstorms Remote http://www.monobrick.dk/software/remote/ but I am not able to get this working. On Linux I found that I had to install libusb with the following command
    sudo apt-get install libusb-1.0-0-dev
    And that I had to have read and write access to the USB device (as descriped here http://www.monobrick.dk/guides/communicating-with-mindstorms-under-linux/)

    I think the read and write access is my problem since I can open the USB device but fail to write… any idear would be nice…

    Ander

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s