2

I have a USB device from which I need to read data via LibUsbDotNet.

If I use the following code after I've successfully opened the device...

    protected UsbEndpointReader _libUsbReader = null;
    protected UsbEndpointWriter _libUsbWriter = null;

.

        IUsbDevice wholeUsbDevice = PhysicalLibUSBDevice 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 #1
            wholeUsbDevice.SetConfiguration(1);

            // Claim interface #0.
            wholeUsbDevice.ClaimInterface(0);
        }


        // Create the reader and writer streams
        _libUsbReader = PhysicalLibUSBDevice.OpenEndpointReader(LibUsbDotNet.Main.ReadEndpointID.Ep01);
        _libUsbWriter = PhysicalLibUSBDevice.OpenEndpointWriter(LibUsbDotNet.Main.WriteEndpointID.Ep02);

        _libUsbReader.DataReceivedEnabled = true;
        _libUsbReader.DataReceived += OnDataReceived;
        _libUsbReader.ReadThreadPriority = System.Threading.ThreadPriority.Highest;
        _libUsbReader.ReadBufferSize = 32;

and define the method:

    private void OnDataReceived(object sender, EndpointDataEventArgs e)
    {
        Console.WriteLine("Data received");
    }

The event never fires. I know the packets are being received by my code as I have a USB analyser attached and can see them coming in.

If I change the code to remove the reliance upon the event callback and instead use the loop below on a background thread to read the reader object

while(true)
{
     ErrorCode ec = ErrorCode.None;
     Thread.Sleep(5);
     int bytesRead;
     byte[] buffer = new byte[32];
     ec = _libUsbReader.Read(buffer, 1000, out bytesRead); 
     if(bytesRead>0) Console.WriteLine("Data Received");
}

Then everything works great.

I've tried playing around with the order I initialise, the values etc and can still get no joy. Can anyone suggest why the events aren't firing if I use the DataReceived event?

I'm using LibUsbDotNet 2.2.8.

Richard Baxter
  • 1,317
  • 1
  • 15
  • 24
  • The event can fire, but not every time, 1 of 3 times in my tryout. And your while(true) codes save me, thanks a lot. – DS. Jan 13 '21 at 10:33

4 Answers4

1

I know this is old, but in your code:

...
_libUsbReader.DataReceivedEnabled = true;
_libUsbReader.DataReceived += OnDataReceived;
_libUsbReader.ReadThreadPriority = System.Threading.ThreadPriority.Highest;
_libUsbReader.ReadBufferSize = 32;
...

I have DataReceivedEnabled set after DataReceived (not sure if this makes a difference).

Also, I do not change thread priority and ReadBufferSize. The latter is 4096 by default. When data arrives, the EndpointDataEventArgs parameter to the event has the Count property with the actual number of bytes received.

Hope this helps.

nurchi
  • 770
  • 11
  • 24
1

When opening the endpoint for reading, you should define the endpoint type to interrupt, otherwise the Datarecieve event won't fire. (Optionally define the size of the read buffer)

In your code you'll have to modify just this row:

_libUsbReader = PhysicalLibUSBDevice.OpenEndpointReader(LibUsbDotNet.Main.ReadEndpointID.Ep01, 64, EndpointType.Interrupt);
L. Guthardt
  • 1,990
  • 6
  • 22
  • 44
Sztiv
  • 11
  • 1
0

Please try like this:

_libUsbReader.DataReceived += mEp_DataReceived;

private void mEp_DataReceived(object sender, EndpointDataEventArgs e) 
{
    try
    {
        Invoke(new OnDataReceivedDelegate(OnDataReceived), new object[] { sender, e });
    }
    catch
    {
        closeDevice();
    }
}
Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291
erdemu
  • 1
-1

I think the sollution is that you should read the endpoint content at the event (or discard it). I had the same problem, when only printing at the console the message I only entered 1 time. When I process in the event the data on the endpoint with read command, the problem seems to be solved.

Vertexwahn
  • 7,709
  • 6
  • 64
  • 90