Node.js中通过WebUSB读取ACR122U读卡器的卡片UID问题
问题分析与解决方案
你遇到的核心问题是发送获取UID指令后无响应,大概率是多余的控制传输干扰了读卡器的状态,同时需要确保指令交互流程符合ACR122U的规范。以下是具体修正方案:
1. 移除错误的控制传输
你添加的controlTransferOut调用既不必要,参数也不符合ACR122U(CCID类设备)的控制传输规范,会导致读卡器进入异常状态,无法响应后续指令,直接删除该部分代码即可。
2. 修正后的读取UID代码
保留你已验证有效的上电和ATR读取逻辑,调整读取UID的代码如下:
// 上电及读取ATR的代码(已验证有效,保留不变) import { usb, findByIds, WebUSBDevice } from 'usb'; const device = findByIds(0x072F, 0x2200); const webDevice = await WebUSBDevice.createInstance(device); webDevice.open(); webDevice.selectConfiguration(1); webDevice.claimInterface(0); // 上电指令 const powerUpDevice = new Uint8Array([0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00]).buffer; await webDevice.transferOut(2, powerUpDevice); // 读取ATR let result = await webDevice.transferIn(2, 64); console.log('ATR响应:', new Uint8Array(result.data.buffer)); // 读取UID的修正代码 const getCardUID = new Uint8Array([0xFF, 0xCA, 0x00, 0x00, 0x04]); await webDevice.transferOut(2, getCardUID.buffer); // 读取UID响应 result = await webDevice.transferIn(2, 64); const responseBytes = new Uint8Array(result.data.buffer); console.log('UID响应原始数据:', responseBytes); // 解析UID(ACR122U响应格式:0x80 + 数据长度 + UID + 状态码) if (responseBytes[0] === 0x80 && responseBytes[responseBytes.length - 2] === 0x90 && responseBytes[responseBytes.length - 1] === 0x00) { const uidLength = responseBytes[1]; const uid = responseBytes.slice(2, 2 + uidLength); console.log('卡片UID:', uid.map(byte => byte.toString(16).padStart(2, '0')).join(':')); } else { console.log('读取UID失败,响应状态异常'); }
3. 关键注意事项
- 端点选择:ACR122U的批量输入/输出端点通常为端点2,你的代码中选择正确,无需修改。
- 指令格式:
0xFF 0xCA 0x00 0x00 0x04是标准的获取UID指令(GET UID),格式正确。 - 响应解析:ACR122U的响应以
0x80开头,后跟数据长度,最后以0x90 0x00表示操作成功,需按此格式解析有效数据。 - 错误处理:建议添加
try/catch捕获传输过程中的异常,比如卡片移除、设备断开等情况。
内容的提问来源于stack exchange,提问作者Jarda Hrbacek
相关产品推荐
相关产品推荐

