🏷️ 企业刚需方案

工业条码/RFID追溯系统

固定读码器 + UHF RFID + 手持PDA,覆盖产线自动识别+仓储批量识别+人工工位全场景。产品全生命周期追溯、质量追溯、批次管理、PLC联动防错、断线缓存零丢失。开源方案替代昂贵商业追溯系统

📷 固定工业读码器 产线自动识别
📡 UHF RFID读写器 批量/远距离识别
📱 手持PDA/扫码枪 人工工位/仓储
🔌 ThingsGateway 多协议数据采集
🗄️ PostgreSQL 追溯数据存储
🔀 Node-RED 流程逻辑与报警
📷 识别:固定读码器+RFID+PDA 🔗 联动:PLC握手+剔除+防错 🗄️ 存储:PostgreSQL关系型 🔍 查询:正向/反向/批次追溯

01 为什么企业最迫切需要追溯系统

没有追溯系统的痛点

😱
质量召回失控
发现不良品,不知道哪些产品受影响,只能整批召回,损失巨大
🔍
问题定位慢
客户投诉质量问题,要查几天才能知道是哪台设备、哪个班次、哪个操作员做的
📋
工序管理混乱
产品跳工序、漏工序,操作员图省事跳过关键工序,质量无法保证
📦
批次无法关联
原料批次和成品批次对不上,原料出问题不知道哪些成品用了这批原料

核心需求

  • 产品唯一标识:每个产品有唯一条码/RFID标签,从出生到出库全程跟随
  • 工序自动记录:每道工序自动扫码,记录时间/设备/操作员/结果,不用人工填写
  • 质量数据关联:检测数据(尺寸/性能/外观)和产品条码绑定,可追溯到具体检测值
  • 批次正反向追溯:从原料查到成品(正向),从成品查到原料(反向),10分钟内锁定影响范围

02 系统架构

五层架构:识别层→采集层→逻辑层→存储层→应用层,全链路开源方案

01
📷
识别层
读码器/RFID/PDA
固定工业读码器(产线自动扫码)、UHF RFID读写器(托盘/料箱批量识别)、手持PDA(人工工位/仓储),覆盖自动+人工全场景
→
02
🔌
采集层
ThingsGateway
读码器TCP/HTTP协议采集、RFID读写器串口/TCP采集、PDA通过REST API上报,统一数据格式,支持断线缓存和自动重连
→
03
🔀
逻辑层
Node-RED
条码校验(格式/重复/漏扫)、PLC握手信号(扫码OK/NG联动剔除)、工序流转判断(防跳工序)、异常报警(缺码/重码/错料)
→
04
🗄️
存储层
PostgreSQL
产品主表(条码+物料+批次)、工序流转表(每道工序扫码记录+时间+操作员+设备)、质量数据表(检测结果+不良代码)、批次关联表(原料批次→成品批次)
→
05
🖥️
应用层
追溯Web+看板
正向追溯(原料→成品→客户)、反向追溯(成品→原料→工序→操作员)、批次追溯、质量SPC看板、不良品分析、报表导出、Excel批量导入导出
💡 架构设计要点:
  • 识别层多模态:固定读码器(产线高速自动)、RFID(仓储批量)、PDA(人工工位),根据场景选最合适的识别方式,不是一刀切
  • 采集层统一协议:不同品牌读码器协议不同,用ThingsGateway统一成标准数据格式,上层不用关心底层设备品牌
  • 逻辑层可配置:校验规则、工序流程、报警条件用Node-RED可视化配置,现场工程师可调整,不用改代码重新部署
  • 存储层关系型为主:追溯是典型关系型数据(多表关联),PostgreSQL比时序数据库更适合。检测数据用JSON字段灵活存储
  • 断线缓存三级保障:读码器缓存+采集网关缓存+PDA本地缓存,网络断了数据不丢,恢复后自动补传

03 核心软件选型理由

PostgreSQL 追溯数据库

为什么选它:追溯系统是典型的关系型数据(产品-工序-质量-批次多表关联),需要复杂JOIN查询和事务保证。PostgreSQL支持JSON字段(存灵活的检测数据)、CTE递归查询(追溯链路)、全文搜索(条码/批次快速检索),比MySQL更适合复杂追溯查询。开源免费,单机支撑百万级产品记录无压力。

对比过:对比过MySQL(复杂查询性能弱)、SQLite(并发写入不够)、InfluxDB(不适合关系型关联)

ThingsGateway 读码器/RFID采集

为什么选它:工业读码器品牌杂(基恩士/康耐视/海康/新大陆),协议不统一(有的TCP Socket、有的HTTP POST、有的串口)。ThingsGateway支持自定义协议驱动,可以把不同品牌读码器统一成标准数据格式。支持断线缓存(网络断了数据存在本地,恢复后自动补传),这对追溯系统至关重要——追溯数据不能丢。

对比过:对比过直接写采集程序(每个品牌要写一套,维护成本高)、Node-RED直接采集(断线缓存和工业协议支持弱)

Node-RED 业务逻辑与PLC联动

为什么选它:追溯系统的逻辑经常变(增加工序、调整校验规则、新增报警条件),用硬编码改一次要重新部署。Node-RED可视化拖拽改逻辑,现场工程师就能调整。和PLC通讯用Modbus TCP节点,扫码OK给PLC发信号、NG触发剔除,响应快(<100ms)。异常报警可以直接发邮件/钉钉/企业微信。

对比过:对比过硬编码C#逻辑(改一次要编译部署,现场无法快速调整)、规则引擎(太重,学习成本高)

UHF RFID 批量/远距离识别

为什么选它:条码只能一个个扫,RFID可以批量读取(一箱产品同时读)、远距离读取(3-5米,不用对准)。在仓储入库/出库、料箱流转、托盘管理场景,RFID效率是条码的10倍以上。超高频UHF RFID标签成本已经降到几毛钱一张,读写器开源方案(用Impinj R420或国产读写器+LLRP协议)可以自己开发,不用买昂贵的中间件。

对比过:对比过HF RFID(距离近,只有几厘米,不适合批量)、条码(需要逐个扫描,效率低)、二维码(和条码一样需要对准)

04 部署要点(关键配置)

01

编码规则设计

先定条码编码规则:产品码(唯一序列号,建议20位以内,含工厂/产线/日期/流水号)、批次码(原料批次/生产批次)、工单码。码制选Code128(密度高)或QR码(可存更多信息,支持中文)。RFID标签选EPC编码(96位或128位),和产品码建立映射关系。写一份《编码规范文档》,所有系统统一遵守

02

读码器选型与安装

固定读码器:产线速度<30件/分钟选1280×1024分辨率,>30件/分钟选更高分辨率+全局快门。安装角度:读码器与条码呈15-30度角(避免反光),加环形光源或同轴光源。光电传感器装在读码器前方5cm处,用于触发。测试:用最差质量的条码(油污/磨损/弯曲)测试,识别率必须>99.5%才上线

03

RFID系统部署

UHF RFID:仓储/托盘场景用,选Impinj R420或国产高性能读写器。天线选型:通道门用线极化天线(读取距离远),工位用圆极化天线(对标签朝向不敏感)。发射功率从20dBm开始调,逐步增大直到读取率稳定。现场测试:用实际产品+实际标签在实际环境测试,不要在实验室测(金属/液体/人体遮挡影响很大)。金属表面必须用抗金属标签

04

数据库表设计

核心5张表:①product(产品主表:条码/物料号/批次号/生产日期/状态);②process_record(工序记录表:条码/工序号/设备号/操作员/扫码时间/结果OK-NG/检测数据JSON);③quality_record(质量表:条码/检测项/检测值/标准值/判定/不良代码);④batch_relation(批次关联表:原料批次/成品批次/数量/投料时间);⑤device(设备表:读码器/RFID/PLC的设备编号/类型/IP/工位号)。所有表加created_at索引,process_record加(barcode, process_no)联合索引

05

PLC联动与防错

每道工序:光电传感器检测产品到位→触发读码器→读码器返回条码→系统校验(条码格式/工序顺序/是否重复)→校验通过给PLC发"OK"信号(放行),校验失败发"NG"信号(剔除/报警停机)。PLC端做超时保护:5秒内没收到系统信号,按NG处理(防止系统挂了产品直接流过去)。关键工位加"扫码确认"按钮(操作员人工确认后才放行)

06

追溯查询界面

Web界面功能:①条码查询(输入条码,显示完整追溯链路:原料→各工序→检测数据→成品→出库);②批次追溯(输入批次号,显示该批次所有产品列表+质量统计);③正向追溯(从原料查到成品和客户);④反向追溯(从成品查到原料和工序);⑤质量分析(不良品柏拉图、工序合格率趋势、SPC控制图);⑥报表导出(Excel/PDF)。界面要快:查询<500ms出结果,支持扫码枪直接输入(光标自动聚焦查询框)

05 踩过的坑(真实问题与解决方案)

追溯系统最容易出问题的就是读码器漏扫、RFID串读、数据丢失、工序跳越,这里是真实踩过的6个坑

坑 01 固定读码器偶尔漏扫,产品流过去了没扫到码,追溯数据断链
原因: 产线速度快(>30件/分钟),读码器曝光时间不够;且产品表面有油污/反光/弯曲,条码印刷质量差。用读码器的"扫码成功"信号直接触发放行,漏扫了也流过去了
解决: 加光电传感器(产品到位信号)+读码器触发模式:光电传感器检测到产品→触发读码器拍照→给500ms超时→超时未读到码判定为"无码"→给PLC发NG信号→剔除或报警。读码器参数调优:增加曝光时间、用自动对焦、加环形光源(解决反光)、选高分辨率读码器(1280×1024以上)。关键:追溯系统必须有"无码"记录,不能 silently 漏掉
坑 02 多个读码器同时扫码,数据串了——A工位的码记到了B工位
原因: 所有读码器都往同一个TCP端口发数据,服务端只收到条码内容,不知道是哪个读码器扫的。或者用了同一个IP不同端口,但端口映射搞错了
解决: 每个读码器配置独立的标识(设备编号),在数据协议中带上设备ID:读码器发的数据格式是 `{deviceId: "READER-01", barcode: "xxx", timestamp: 1234567890}`。服务端根据deviceId判断是哪个工位。或者用不同的TCP端口,每个端口对应一个工位,服务端监听多个端口。绝对不能只靠条码内容判断工位——同一产品可能在多个工位被扫到
坑 03 网络断了5分钟,恢复后这段时间的追溯数据全丢了
原因: 读码器和PDA都是实时上报,网络断了数据直接丢弃。没有本地缓存机制,恢复后也不会补传
解决: 三层缓存机制:①读码器本身支持缓存(选带缓存功能的工业读码器,可存上千条);②ThingsGateway采集层做本地缓存(SQLite本地存储,网络恢复后按时间顺序补传);③PDA端做离线模式(网络断了存本地数据库,恢复后手动/自动同步)。关键:补传时必须带原始时间戳,不能用补传时间作为扫码时间,否则追溯时序会乱
坑 04 RFID批量读取时,经常读到隔壁托盘的标签(串读),或者同一批标签有几个读不到(漏读)
原因: UHF RFID是无线电信号,读取范围是一个区域(3-5米),隔壁托盘的标签也在范围内就会被读到。漏读是因为标签朝向不对(UHF标签有方向性)、金属/液体遮挡、标签贴在金属表面没有用抗金属标签
解决: 串读解决:①用屏蔽天线(定向天线,读取角度控制在60度以内);②调低发射功率(从30dBm降到20-25dBm,缩小读取范围);③软件过滤(按读取次数过滤,只保留读取次数>阈值的标签,隔壁托盘的标签只会被读到1-2次,本托盘的会被读到10次以上);④物理隔离(加金属隔板)。漏读解决:①用抗金属标签(贴金属表面必须用);②标签贴在产品非金属区域;③多次读取(停留3秒以上,读3次取并集);④关键工位加复核(RFID+条码双确认)
坑 05 产品在某道工序漏扫了(操作员忘了扫),后面工序扫了,追溯链路中间断了一环
原因: 没有防跳工序校验,产品可以不按顺序流转。操作员图省事,跳过某道工序直接流到下一道
解决: 强制工序流转校验:每道工序扫码时,系统检查上一道工序是否已完成(查数据库中该条码的上一工序记录)。如果上一道没扫,系统报警"工序顺序错误",并给PLC发信号禁止放行。特殊情况(返工/维修)需要有"工序跳越授权"功能:班组长刷卡授权后可以跳过,但必须记录跳越原因和授权人。追溯报表中要标出"工序缺失"和"工序跳越"的产品,质量追溯时重点关注
坑 06 追溯查询太慢——查一个条码的完整追溯链路要5秒以上,产线等不及
原因: 数据库表设计不合理,每次查询要JOIN 5-6张表,且没有建索引。产品数据量大了以后(>100万条),查询性能急剧下降
解决: 数据库优化:①产品主表加条码唯一索引(最常用查询条件);②工序记录表建(条码+工序号)联合索引;③用CTE递归查询追溯链路,比多次JOIN快;④冷热数据分离(近3个月数据在主库,历史数据归档到单独表或压缩存储);⑤追溯查询接口加Redis缓存(热门条码缓存1小时)。实测:100万产品记录,优化后单条码追溯查询<200ms

06 关键代码片段

扫码校验与PLC联动(Node-RED Function节点示例)

// 收到读码器数据,校验后给PLC发OK/NG信号
// msg.payload = { deviceId, barcode, timestamp }
const { Pool } = require('pg');
const pool = new Pool({ connectionString: 'postgresql://user:pass@localhost/traceability' });

const barcode = msg.payload.barcode;
const deviceId = msg.payload.deviceId;

// 1. 条码格式校验(20位,字母数字)
if (!/^[A-Z0-9]{20}$/.test(barcode)) {
    msg.result = 'NG';
    msg.reason = '条码格式错误';
    return msg;  // 直接发NG给PLC
}

// 2. 查数据库,校验上一道工序是否完成
const client = await pool.connect();
try {
    const lastProcess = await client.query(
        'SELECT process_no FROM process_record WHERE barcode=$1 ORDER BY process_no DESC LIMIT 1',
        [barcode]
    );
    
    const currentProcess = getProcessByDevice(deviceId);  // 根据设备ID查当前工序号
    
    if (lastProcess.rows.length > 0) {
        const lastNo = lastProcess.rows[0].process_no;
        if (currentProcess !== lastNo + 1) {
            msg.result = 'NG';
            msg.reason = `工序顺序错误,上一道工序=${lastNo},当前=${currentProcess}`;
            return msg;
        }
    } else if (currentProcess !== 1) {
        msg.result = 'NG';
        msg.reason = '首道工序未扫码,产品来源不明';
        return msg;
    }
    
    // 3. 校验通过,写入工序记录
    await client.query(
        'INSERT INTO process_record (barcode, process_no, device_id, operator, scan_time, result) VALUES ($1,$2,$3,$4,NOW(),$5)',
        [barcode, currentProcess, deviceId, msg.operator || 'auto', 'OK']
    );
    
    msg.result = 'OK';
    return msg;  // 发OK给PLC,放行
} finally {
    client.release();
}

07 实际效果

<200ms
追溯查询速度
百万级数据单条码查询
99.8%
读码识别率
产线固定读码器(含油污/磨损)
100件/3秒
RFID批量读取
托盘整托批量识别率>99%
100%
数据完整性
断线缓存+补传,追溯数据零丢失
0漏扫
防跳工序
强制工序校验+授权跳越记录
<10分钟
质量追溯响应
从发现不良到锁定影响批次范围

08 相关软件与工具

需要条码/RFID追溯系统方案?

丁丁做过工业追溯系统项目,熟悉固定读码器部署、UHF RFID调试、PLC联动防错、PostgreSQL追溯数据库设计、Node-RED业务逻辑开发。可以帮你做方案设计、设备选型、系统开发、现场调试。