You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 17:27:30