与 HID 设备的通信在读/写时挂起(AS3992 RFID 阅读器)

Posted

技术标签:

【中文标题】与 HID 设备的通信在读/写时挂起(AS3992 RFID 阅读器)【英文标题】:Communication with HID device hangs on read/write (AS3992 RFID reader) 【发布时间】:2014-05-31 13:58:12 【问题描述】:

我正在尝试与基于 AS3992 芯片的 UHF RFID 阅读器进行通信。 此设备被 Windows 检测为标准 HID,并且可以与 3rd 方应用程序一起使用(我发现 LinkSprite 的一些 UHF RFID 阅读器 GUI 可以工作,但它看起来像是一些较旧的 C++ 应用程序)。

所以我正在尝试将此设备支持集成到我的 .NET 应用程序中。经过一番研究,我尝试了HidLibrary,但是当我尝试向这个设备写一些东西时(这个示例中的初始序列),它挂在“写”上。

有人知道我做错了什么吗?

谢谢!

我的操作系统是 Win 8.1 x64。

这是示例应用程序:

using HidLibrary; namespace HidTest2 class Program static void Main(string[] args) var devices = HidDevices.Enumerate(0x1325); var rfid = devices.First(); rfid.OpenDevice(); rfid.Write(new byte[] 0x31, 0x03, 0x01 ); // Application hangs here while (true) // I can't get here Thread.Sleep(50); var result = rfid.Read(); Console.Write(result.Data);

PS:我也尝试过 HidSharp,但我得到了相同的结果。检测到 HID 设备,但我无法写入。

PSS:这是设备:Link to ebay

【问题讨论】:

你从哪里得到 0x1325?听起来您正在尝试与音频硬件对话。 这是供应商 ID,它是正确的......这不是问题...... 【参考方案1】:

我找不到你提到的 AS3229 芯片的数据表,所以我在这里猜测......

该设备可能显示为 USB 键盘,因此您通常只能向其写入 LED 状态位(Caps lock、Num lock、Shift)。这就是你要写的吗?

尝试删除写入,然后等待扫描的 RFID 字符串进入。

编辑:看起来此设备通过 USB 显示为串行设备...我在这里找到了与它非常匹配的描述: https://s3.amazonaws.com/linksprite/cuttonwood/datasheet.pdf

如果它是您正在测试的同一设备,那么我会尝试通过 COM 端口 API 与其通信,而不是使用您一直在使用的相对较低级别的 HID API。

【讨论】:

嗨,我能够在谷歌中找到数据表作为“AS3992 数据表”的第一个结果。不幸的是,这个设备不能像键盘一样工作。您可以在代码中看到的“写入”是“初始化序列”,它告诉设备“开始读取 RFID 芯片”。顺便说一句:读取也挂起。问题是:为什么写(或读)挂起。 嗯,也许您应该更新您的问题以指定正确的设备(AS3992 而不是 AS3229)【参考方案2】:

因为我时常收到一封电子邮件,如果我解决了这个问题,我如何解决,这里有一个答案:

我不得不替换原始固件以通过 固件 进行串行通信(在 Internet 上搜索“as399x uart 115200 hex”或“as399x uart 9600 hex” ) 然后它就像一个沙姆一样工作。当然,你需要合适的 C8051Fxxx 编程器(大约 20 美元来自中国)、USB 串行转换器并熟悉一些焊接(你必须在板上焊接 JTAG 和串行端口的引脚)。

【讨论】:

【参考方案3】:

如上所述,该设备实际上可能不是 Hid 设备。您是否尝试过通过 USB 设备而不是 Hid 设备进行枚举?这是一些枚举 USB 或 Hid 设备的代码。代码是here。

对于隐藏设备,请使用 ClassGuid:4D1E55B2-F16F-11CF-88CB-001111000030

对于 Win USB 设备,请使用:dee824ef-729b-4a0e-9c14-b7117d33a817

https://github.com/MelbourneDeveloper/Device.Net/blob/master/src/Device.Net/Windows/WindowsDeviceConstants.cs

public async Task<IEnumerable<DeviceDefinition>> GetConnectedDeviceDefinitions(uint? vendorId, uint? productId)
    
        return await Task.Run<IEnumerable<DeviceDefinition>>(() =>
        
            var deviceDefinitions = new Collection<DeviceDefinition>();
            var spDeviceInterfaceData = new SpDeviceInterfaceData();
            var spDeviceInfoData = new SpDeviceInfoData();
            var spDeviceInterfaceDetailData = new SpDeviceInterfaceDetailData();
            spDeviceInterfaceData.CbSize = (uint)Marshal.SizeOf(spDeviceInterfaceData);
            spDeviceInfoData.CbSize = (uint)Marshal.SizeOf(spDeviceInfoData);

            var guidString = ClassGuid.ToString();
            var copyOfClassGuid = new Guid(guidString);

            var i = APICalls.SetupDiGetClassDevs(ref copyOfClassGuid, IntPtr.Zero, IntPtr.Zero, APICalls.DigcfDeviceinterface | APICalls.DigcfPresent);

            if (IntPtr.Size == 8)
            
                spDeviceInterfaceDetailData.CbSize = 8;
            
            else
            
                spDeviceInterfaceDetailData.CbSize = 4 + Marshal.SystemDefaultCharSize;
            

            var x = -1;

            var productIdHex = GetHex(productId);
            var vendorHex = GetHex(vendorId);

            while (true)
            
                x++;

                var isSuccess = APICalls.SetupDiEnumDeviceInterfaces(i, IntPtr.Zero, ref copyOfClassGuid, (uint)x, ref spDeviceInterfaceData);
                if (!isSuccess)
                
                    var errorCode = Marshal.GetLastWin32Error();
                    if (errorCode == APICalls.ERROR_NO_MORE_ITEMS)
                    
                        break;
                    

                    throw new Exception($"Could not enumerate devices. Error code: errorCode");
                

                isSuccess = APICalls.SetupDiGetDeviceInterfaceDetail(i, ref spDeviceInterfaceData, ref spDeviceInterfaceDetailData, 256, out _, ref spDeviceInfoData);
                WindowsDeviceBase.HandleError(isSuccess, "Could not get device interface detail");

                //Note this is a bit nasty but we can filter Vid and Pid this way I think...
                if (vendorId.HasValue && !spDeviceInterfaceDetailData.DevicePath.ToLower().Contains(vendorHex)) continue;
                if (productId.HasValue && !spDeviceInterfaceDetailData.DevicePath.ToLower().Contains(productIdHex)) continue;

                deviceDefinitions.Add(GetDeviceDefinition(spDeviceInterfaceDetailData.DevicePath));
            

            APICalls.SetupDiDestroyDeviceInfoList(i);

            return deviceDefinitions;
        );

【讨论】:

以上是关于与 HID 设备的通信在读/写时挂起(AS3992 RFID 阅读器)的主要内容,如果未能解决你的问题,请参考以下文章

Apache/PHP 进程在与 MySQL 交互时挂起

如何与 Windows 上的 USB-HID 设备通信?

USB-HID的介绍

是啥导致 Eclipse 在与工作区断开连接时挂起?

使用 Android 与 USB HID 设备通信

ResultSet.next() 在使用 jdbc 与 oracle 11.2 交谈时挂起