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

使用NodeJS和serialport库读取USB RFID读卡器卡号问题咨询

问题根因

  • Readline解析器无输出:该RFID读卡器的串口输出未用换行符作为数据帧分隔符,Readline默认按\n/\r\n切割数据流,因此无法触发回调。
  • 原始data事件输出零散数据:serialport的data事件会实时返回当前收到的字节分片,不会等待完整的读卡数据帧传输完成,因此拿到的是不完整的分段数据。

解决方案

你已经找到了数据帧的前后缀规则,只需先把所有收到的串口数据攒成完整的hex缓存,再按规则匹配完整数据帧、提取中间卡号段即可,参考实现代码如下:

const SerialPort = require('serialport');
const port = new SerialPort('/dev/cu.usbserial-0001', { baudRate: 9600 });

// 全局hex缓存,用于拼接分片数据
let hexBuffer = '';
// 已梳理的固定前后缀(去掉空格拼接为连续hex)
const FRAME_PREFIX = '00181818189898e098';
const FRAME_SUFFIX = '18f8';
// 卡号段长度:10字节对应20位hex字符
const CARD_HEX_LENGTH = 20;

port.on('data', (data) => {
  // 新收到的数据转hex拼入缓存
  hexBuffer += data.toString('hex');
  
  // 循环匹配缓存中所有符合规则的完整帧
  while (hexBuffer.includes(FRAME_PREFIX) && hexBuffer.includes(FRAME_SUFFIX)) {
    // 定位前缀起始位置
    const prefixIndex = hexBuffer.indexOf(FRAME_PREFIX);
    // 前缀结束位置即为卡号段起始位置
    const cardStart = prefixIndex + FRAME_PREFIX.length;
    // 定位后缀起始位置(必须在卡号段之后)
    const suffixIndex = hexBuffer.indexOf(FRAME_SUFFIX, cardStart);
    
    // 确认帧结构完整
    if (suffixIndex !== -1 && (suffixIndex - cardStart) === CARD_HEX_LENGTH) {
      // 提取卡号hex,转大写后拼接MT_前缀即为数据库兼容格式
      const cardHex = hexBuffer.slice(cardStart, suffixIndex).toUpperCase();
      const cardId = `MT_${cardHex}`;
      console.log('读取到卡号:', cardId);
      
      // 从缓存中删除已处理的内容,避免重复匹配
      hexBuffer = hexBuffer.slice(suffixIndex + FRAME_SUFFIX.length);
    } else {
      // 帧不完整,等待更多数据输入后再匹配
      break;
    }
  }
});

port.on('error', (err) => {
  console.error('串口错误:', err.message);
});

可选调整项

  • 如果匹配不到完整帧,可以临时打印hexBuffer内容,确认前后缀规则是否有偏差,比如前后缀的字节长度是否和梳理的一致
  • 若输出的卡号和卡片印刷号不匹配,可调整提取的卡号段长度,若需要匹配印刷的十进制卡号,可以将提取到的hex转十进制后取对应位数即可

内容的提问来源于stack exchange,提问作者mrclbls

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:09:02