【USB】C#使用HID通信
https://blog.csdn.net/gzylongxingtianxia/article/details/137151349
最近做了一个USB通信SDK, 通过HID跟单片机通信,之前研究了一下Libusb, Cyusb, 要么死的太早,要么封装的不好,最后绕来绕去发现还是HID好用,反编译了一个SimpleHid, 别说,用起来还是很酸爽的~~~
1.设备识别
首先你要指定VID和PID, 这2个不知道的可以不用往下看了,就是一个人的名字和性别
设别识别很容易,直接获取设备列表,对比一下vid,pid就搞定了,不多墨迹了
直接Linq一下了
// 获取所有目标设备信息集合
List<HIDInfoSet> acceptableDevices = HIDManager.GetInfoSets()
.Where(set => this.m_OpenOptions.IsVidAndPidAcceptable(set.Vid, set.Pid))
.ToList();
1
2
3
4
2.插拔识别
这里有3中方法
方法1.使用winform pnpinvoke 监听消息句柄,判断插拔, 对上位机来说这种方式很常见了,但是有限制,下面说。
方法2.使用cpp dll, 方法1的限制在于有些native软件不能使用winform,比如Unity I2cpp 打包就不行,所以需要自己用C++封装dll,然后使用委托回调函数触发,这个也不难,可以看看我之前的文章
https://blog.csdn.net/gzylongxingtianxia/article/details/136683845
方法3. 简单粗暴,直接开一个监控线程
private void ThreadProcDeviceDiscovery()
{
while (!this.bKillUsbDiscoverThread)
{
this.DoDeviceDiscovery();
Thread.Sleep(200);
}
this.KillDiscoveryThread();
}
1
2
3
4
5
6
7
8
9
10
监听插拔
/// <summary>
/// The do device discovery.
/// </summary>
private void DoDeviceDiscovery()
{
if (this.m_HidDevices == null)
{
return;
}
// 获取当前已连接的设备的序列号列表
List<string> connectedSerialNumbers = new List<string>();
lock (this.m_HidDevices)
{
foreach (UsbHidDevice device in this.m_HidDevices)
{
connectedSerialNumbers.Add(device.hidInfoSet.SerialNumberString);
}
}
// 获取所有目标设备信息集合
List<HIDInfoSet> acceptableDevices = HIDManager.GetInfoSets()
.Where(set => this.m_OpenOptions.IsVidAndPidAcceptable(set.Vid, set.Pid))
.ToList();
// 获取新发现的设备信息集合
List<HIDInfoSet> newDevices = acceptableDevices
.Where(set => !connectedSerialNumbers.Contains(set.SerialNumberString))
.ToList();
// 获取已断开的设备列表
List<UsbHidDevice> disconnectedDevices = this.m_HidDevices
?.Where(device => !acceptableDevices.Any(set => set.SerialNumberString == device.hidInfoSet.SerialNumberString))
.ToList();
if (disconnectedDevices == null)
{
return;
}
// 断开已断开的设备并移除
foreach (UsbHidDevice device in disconnectedDevices)
{
lock (this.m_HidDevices)
{
this.m_HidDevices.Remove(device);
EventDispatcher.TriggerEvent(EventEnum.DEVICE_DETACHED, device);
}
}
// 实例化新发现的设备并添加到已连接列表中
foreach (HIDInfoSet set in newDevices)
{
UsbHidDevice device = new UsbHidDevice(this, set);
lock (this.m_HidDevices)
{
this.curHidDevice = device;
this.m_HidDevices.Add(device);
}
EventDispatcher.TriggerEvent(EventEnum.DEVICE_ATTACHED, this.curHidDevice);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
3.HID通信
1.创建通信句柄要开启读写
static class DESIREDACCESS
{
public const uint GENERIC_READ = 0x80000000;
public const uint GENERIC_WRITE = 0x40000000;
public const uint GENERIC_EXECUTE = 0x20000000;
public const uint GENERIC_ALL = 0x10000000;
}
this.handle = NativeMethods.CreateFile(devicePath, DESIREDACCESS.GENERIC_READ | DESIREDACCESS.GENERIC_WRITE, 3, IntPtr.Zero, 3, 0x40000000, IntPtr.Zero);
1
2
3
4
5
6
7
8
9
NativeMethods.CreateFile第二个参数要开启读写
2.HidCaps
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct HidCaps
{
public short Usage;
public short UsagePage;
public short InputReportByteLength;
public short OutputReportByteLength;
public short FeatureReportByteLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=0x11)]
public short[] Reserved;
public short NumberLinkCollectionNodes;
public short NumberInputButtonCaps;
public short NumberInputValueCaps;
public short NumberInputDataIndices;
public short NumberOutputButtonCaps;
public short NumberOutputValueCaps;
public short NumberOutputDataIndices;
public short NumberFeatureButtonCaps;
public short NumberFeatureValueCaps;
public short NumberFeatureDataIndices;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
InputReportByteLength 和 OutputReportByteLength 这2个长度很重要,一般是65个字节,ReportId + Data
3. 构建报文数据
Report Id 单个包来说都是 0 ,如果一次发多个包,就要递增,我这里是一个包的情况
总长度 0x41 = 65 , ReportId + Data ,数据占64个字节
长度一定不能错,否则会包HID参数异常
下面是一个参考方法
public void MakeBytes(EMessage cmd, byte value)
{
this.reportId = 0;
this.value = (int)value;
this.length = 1;
this.cmd = (int)cmd;
var i = 0;
this.sendData = new byte[0x41];
this.sendData[i] = this.reportId;
this.sendData[i++] = 0x05;
this.sendData[i++] = 0XAA;
this.sendData[i++] = 0XAA;
this.sendData[i++] = (byte)cmd;
this.sendData[i++] = 1;
this.sendData[i++] = value;
for (; i < 0x41; i++)
{
this.sendData[i] = 0;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
4. 读写
当设备连接成功后,会建立一个字节流
this.fileStream = new FileStream(new SafeFileHandle(this.handle, false), FileAccess.ReadWrite, this.hidCaps.InputReportByteLength, true);
1
通过这个字节流读写数据
public byte[] ReadRawInputReport()
{
byte reportID = 0;
byte[] buffer = this.CreateRawInputReport(reportID);
try
{
this.fileStream.Read(buffer, 0, buffer.Length);
}
catch (Exception e)
{
return buffer;
}
return buffer;
}
public void WriteRawOutputReport(byte[] data)
{
try
{
this.fileStream.Write(data, 0, data.Length);
this.fileStream.Flush();
}
catch (Exception e)
{
throw new HIDDeviceException();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Ojbkey了,剩下的开多少个线程,如何处理发送接收就自己发挥吧,也比较简单,下班了,周末愉快,老铁们~~!!
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/gzylongxingtianxia/article/details/137151349
【USB】C#使用HID通信的更多相关文章
- Android USB Host与HID通讯
前端时间捣鼓一个HID的硬件, 需要和android通信, 网上搜索了一圈,收获不小. 比较好的文章是: Android USB Host与HID通讯 Android Service创建US ...
- Android USB Host与HID通讯 (二)
不好意思,从上一篇到现在确实比较忙,中间又外出了一段时间,虽然也上LOFTER,或者看到一些朋友QQ上加我,给我发信息询问,有些看到了有些可能没看到,偶尔回复了一两个,也不咋的详细,在此我想说,一方面 ...
- 使用C#使用Windows的HID通信
本文转载于:https://blog.csdn.net/u010875635/article/details/73321066 Windows使用HID通信相对比较简单,HID都是通过PID.VID信 ...
- Android USB Host 与 HID 之通讯方法
Android USB Host与HID通讯,就目前Google Developer提供的方法有bulkTransfer()与controlTransfer(),看是简简单单的两个方法,要实现真正的通 ...
- Android USB Host与HID通讯 (一)
去年9月份来到现在的公司,接到新公司的第一个项目就是Android USB Host与HID通讯,当时也什么都不懂,就拿着google的api 开发指南 (http://developer.andro ...
- Python编程实现USB转RS485串口通信
---作者吴疆,未经允许,严禁转载,违权必究--- ---欢迎指正,需要源码和文件可站内私信联系--- -----------点击此处链接至博客园原文----------- 功能说明:Python编程 ...
- Android USB Host 与 HID 之通讯方法(bulkTransfer()与controlTransfer()方法使用)
转载地址:差满多乃几 Android USB Host与HID通讯,就目前Google Developer提供的方法有bulkTransfer()与controlTransfer(),看是简简单单的两 ...
- Android USB Host 与 Hid 设备通信bulkTransfer()返回-1问题的原因
近期一直在做Android USB Host 与USB Hid设备(STM32FXXX)的通信,遇到了很多问题.项目源码以及所遇到的其他问题可以见本博客其他相关文章,这里重点讲一下bulkTransf ...
- USB学习小记-HID类键盘的报告描述符的理解
前言 断断续续的学习了将近三个月,才把USB的HID类搞明白,速度真是够慢的.利用晚上+周末的时间学习自己的东西确实是必要的,不过效率是有点低,以后要更专注一些才行,希望自己能做到吧. 在学习过程中, ...
- USB HID 协议入门
转载请注明来源:cuixiaolei的技术博客 USB HID设备类的应用场合 USB HID类是USB设备的一个标准设备类,包括的设备非常多.HID类设备定义它属于人机交互操作的设备,用于控制计算机 ...
随机推荐
- 解析依赖注入(DI)的本质
本文由 ChatMoney团队出品 在软件开发中,依赖注入是一种常用的设计模式,它允许我们将类的依赖关系通过构造器或其他方式自动注入.这种模式在控制器架构中尤为常见,它使得类的依赖关系更加灵活和可管理 ...
- Docker命令速查
Docker命令 显示所有正在运行的docker容器 docker ps 显示所有docker容器 docker ps -a 运行容器 docker run : 运行一个容器并连接到它 docker ...
- Java源码分析系列笔记-15.CompletableFuture
目录 1. 是什么 2. Future VS CompletableFutre 3. 使用 3.1. 运行一个不返回结果的任务 3.2. 运行一个返回结果的任务 3.3. 线程池 3.4. 手动完成任 ...
- 观点分享:Oracle数据库GRID升级的案例的闲聊
我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢! 由于博客中有大量代码,通过页面浏览效 ...
- MKL库求解矩阵特征值、特征向量(LAPACKE_dgeev、dsyev)
LAPACK(Linear Algebra PACKage)库,是用Fortran语言编写的线性代数计算库,包含线性方程组求解(\(AX=B\)).矩阵分解.矩阵求逆.求矩阵特征值.奇异值等.该库用B ...
- Oracle数据一致性与事务管理
数据一致性和事务 Oracle中的数据一致性 当从A表取一条数据添加到B表时,需先删除A表数据,再新增B表数据, 如果第二条操作出异常时,就造成了数据不一致. Oracle中的事务 事务是保证数据一致 ...
- c#文件压缩,需要借助外部dll文件和ZipHelper.cs
后台代码 ZipHelper z = new ZipHelper(); List<string> pathList=new List<string> (); pathList. ...
- 前端开发系列080-Node篇之cnpm
本文输出Node中另一款包管理工具CNPM相关的内容,包括基本情况和简单使用. 一.简单介绍 CNPM是阿里的Node团队开发的一款NPM工具,由蚂蚁金服Node技术专家苏千(袁锋·Node技术专家) ...
- ICEE-eFuse电子保险丝
eFuse的原理是以测量电压(已知高精密电阻分压分流网络上的)和内部高精密参考电压, 经过ADC变换成数字信号,通过计算来精准检测电流电压, 并且在电流超过设计限值时,通过场效应晶体管 (FET) 切 ...
- Edu-Linguistic-English-IPA-英语发音:Vocal anatomy, muscles and function
https://web.uvic.ca/ling/resources/ipa/charts/IPAlab/IPAlab.htm https://www.internationalphoneticass ...