下载安装
下载并安装 LibUsbDotNet
查看所需打开设备的PID和VID
using System;
using LibUsbDotNet;
using LibUsbDotNet.Main;
namespace LibUSBDemo
{
class Program
{
static void Main(string[] args)
{
GetUSBInfo();
Console.ReadLine();
}
public static void GetUSBInfo()
{
UsbRegDeviceList allDevices = UsbDevice.AllDevices;
Console.WriteLine("Found {0} devices", allDevices.Count);
foreach (UsbRegistry usb in allDevices)
{
Console.WriteLine("----------------");
Console.WriteLine($"Device info: {usb.Device.Info.ProductString}");
Console.WriteLine($"Pid: { usb.Pid}, VID: {usb.Vid}");
}
Console.WriteLine(allDevices.Count);
}
}
}
LibUSBDotNet写和读的两种方式
第一种
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using LibUsbDotNet;
using LibUsbDotNet.Main;
namespace LibUSBDemo
{
class LibUSB
{
private UsbDevice usbDevice;
private UsbEndpointReader epReader;
private UsbEndpointWriter epWriter;
public void Open(int vid, int pid)
{
UsbDeviceFinder usbFinder = new UsbDeviceFinder(vid, pid);
usbDevice = UsbDevice.OpenUsbDevice(usbFinder);
if (usbDevice == null)
{
// 多次尝试连接USB设备
int count = 0;
while (count < 10 && usbDevice == null)
{
Thread.Sleep(100);
usbDevice = UsbDevice.OpenUsbDevice(usbFinder);
count++;
}
}
if (usbDevice == null)
{
Console.WriteLine("打开USB设备失败");
}
else
{
// 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 = usbDevice as IUsbDevice;
if (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);
}
// open read endpoint 1.
epReader = usbDevice.OpenEndpointReader(ReadEndpointID.Ep01);
// open write endpoint 1.
epWriter = usbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
}
}
public void Close()
{
if (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 = usbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
// Release interface #0.
wholeUsbDevice.ReleaseInterface(0);
}
usbDevice.Close();
usbDevice = null;
}
// Free usb resource
UsbDevice.Exit();
}
public bool IsOpen()
{
if (usbDevice == null)
{
return false;
}
return usbDevice.IsOpen;
}
public List<byte> SendCommand(string cmd)
{
List<byte> result = new List<byte>();
int byteWrite;
ErrorCode ec = epWriter.Write(Encoding.Default.GetBytes(cmd), 3000,out byteWrite);
if(ec != ErrorCode.None)
{
Console.WriteLine($"Write Error, {UsbDevice.LastErrorString}");
return null;
}
byte[] readBuffer = new byte[1024];
int byteRead;
while (ec == ErrorCode.None)
{
// If the device hasn't sent data in the last 1000 milliseconds,
// a timeout error (ec = IoTimedOut) will occur.
ec = epReader.Read(readBuffer, 1000, out byteRead);
// 只有当超时的时候才会有byteRead为0,也就是结束
if(byteRead != 0)
{
byte[] buffer = new byte[byteRead];
Array.Copy(readBuffer, buffer, byteRead);
result.AddRange(buffer);
}
else
{
Console.WriteLine("读取数据结束");
return result;
}
}
return null;
}
}
}
上述代码在SendCommand
发送命令获取返回结果的时候,结束条件byteRead == 0
的时候也就是TimeOut
的时候才会出现,这会造成时间浪费,因为超时时间一般来说设置的都会比较长。那有没有什么方式可以避免这种情况呢?可以使用异步的情况接受数据。
第二种
using System;
using System.Collections.Generic;
using System.Text;
using LibUsbDotNet;
using LibUsbDotNet.Main;
using System.Timers;
namespace LibUSBDemo
{
class LibUSB
{
private UsbDevice usbDevice;
private UsbEndpointReader epReader;
private UsbEndpointWriter epWriter;
private List<byte> recvData;
public LibUSB()
{
recvData = new List<byte>();
}
public void Open(int vid, int pid)
{
UsbDeviceFinder usbFinder = new UsbDeviceFinder(vid, pid);
usbDevice = UsbDevice.OpenUsbDevice(usbFinder);
if (usbDevice == null)
{
// 多次尝试连接USB设备
int count = 0;
while (count < 10 && usbDevice == null)
{
System.Threading.Thread.Sleep(100);
usbDevice = UsbDevice.OpenUsbDevice(usbFinder);
count++;
}
}
if (usbDevice == null)
{
Console.WriteLine("打开USB设备失败");
}
else
{
// 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 = usbDevice as IUsbDevice;
if (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);
}
// open read endpoint 1.
epReader = usbDevice.OpenEndpointReader(ReadEndpointID.Ep01);
epReader.ReadBufferSize = 1024; // 默认是4096
// 设置以下内容将不能使用Read()方法来读取返回值
epReader.DataReceived += EpReader_DataReceived;
epReader.DataReceivedEnabled = true;
// open write endpoint 1.
epWriter = usbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
}
}
private void EpReader_DataReceived(object sender, EndpointDataEventArgs e)
{
byte[] byteRead = new byte[e.Count];
Array.Copy(e.Buffer, byteRead, e.Count);
recvData.AddRange(byteRead);
}
public void Close()
{
if (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 = usbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
// Release interface #0.
wholeUsbDevice.ReleaseInterface(0);
}
usbDevice.Close();
usbDevice = null;
}
// Free usb resource
UsbDevice.Exit();
}
public bool IsOpen()
{
if (usbDevice == null)
{
return false;
}
return usbDevice.IsOpen;
}
public List<byte> SendCommand(string cmd)
{
List<byte> result = new List<byte>();
int byteWrite;
ErrorCode ec = epWriter.Write(Encoding.Default.GetBytes(cmd), 3000, out byteWrite);
if (ec != ErrorCode.None)
{
Console.WriteLine($"Write Error, {UsbDevice.LastErrorString}");
return null;
}
int recvDataLength = 0;
int count = 0;
bool isEnd = false;
Timer timer = new Timer(10);
timer.AutoReset = true;
timer.Start();
timer.Elapsed += delegate
{
if ((count >= 10 && recvData.Count == 0) || (recvData.Count == recvDataLength && recvData.Count != 0))
{
timer.Stop();
timer = null;
isEnd = true;
}
recvDataLength = recvData.Count;
};
while (!isEnd) ;
return recvData;
}
}
}