工业流水线扫码枪对接编程:实现多台扫码设备的条码数据快速解析与上传
流水线多扫码枪不是“开几个串口读字符串”就完事。多台设备并发、快扫粘包、重复触发、网络抖动断传,任一处漏掉都会让MES收到错码或丢码。 正经做法是:每台扫码枪分配Station ID → 串口/RS485独立缓冲收字节 → 结束符切帧 → 时间窗去重 → 本地队列批量上传。
一、接口与数据格式
工业固定式扫码枪常见三类出口:
RS232/RS485 ASCII透传(老线最多)
网口TCP Client直连MES
Modbus RTU封装或Profinet网关汇聚多台
纯ASCII透传最通用:波特率9600/115200、8N1、无流控,扫码成功发一串字符,末尾带\r、\n或\r\n。 有的厂牌用STX+数据+ETX帧头帧尾。
别用键盘HID模式,焦点一丢数据扫进别处窗口;工业场景统一走串口/CDC。
二、每路独立接收缓冲
多台设备别共用一个recv_buf,中断里只塞字节,解析放主循环。
typedef struct {
int dev_id;
char rx[128];
int len;
uint32_t last_ms;
} scanner_t;
scanner_t sc[8];
void uart_isr_push(int ch, uint8_t c){
scanner_t*s = &sc[ch];
if(c=='\r' || c=='\n'){ // 结束符切帧
if(s->len>0){
s->rx[s->len]=0;
on_barcode(s->dev_id, s->rx, s->len);
s->len=0;
}
return;
}
if(s->len < 127) s->rx[s->len++]=c;
}
粘包场景:两条码连发无结束符间隔,状态机按结束符切,不会混;半包场景:本次没收到\r\n留着下帧拼接。
三、解析后先过四道关
拿到一条完整条码别直接上传:
长度/前缀校验(SN规则、GS1前缀)
时间窗去重(同工位同码500ms内只留一条)
格式非法丢弃并记日志
成功才进上传队列
typedef struct { char code[64]; uint32_t ts; } dedup_t;
dedup_t dd[8][16]; // 每设备滑动窗
int barcode_dedup(int dev, char*code){
uint32_t now=sys_ms();
dedup_t*row=dd[dev];
for(int i=0;i<16;i++){
if(strcmp(row[i].code,code)==0){
if(now-row[i].ts < 500) return -1; // 重复
}
}
// 环形覆盖最旧
static int cur[8];
strcpy(row[cur[dev]].code, code);
row[cur[dev]].ts = now;
cur[dev]=(cur[dev]+1)&15;
return 0;
}
去重按“设备+码”维度,别全局去重——两条线同时扫同一型号SN是正常的。
四、本地缓存+批量上传
接收线程不碰网络。条码进无锁队列,上传线程批量发MQTT/HTTP/Socket,失败回队尾。
typedef struct { int dev; char code[64]; uint32_t ts; } pkt_t;
pkt_t qbuf[256];
int qin, qout;
void on_barcode(int dev, char*code, int len){
if(barcode_dedup(dev,code)) return;
pkt_t*p=&qbuf[qin];
p->dev=dev; strcpy(p->code,code); p->ts=sys_ms();
qin=(qin+1)&255;
}
void upload_task(void){
while(qout!=qin){
pkt_t*p=&qbuf[qout];
char body[96];
sprintf(body,"{\"station\":%d,\"code\":\"%s\",\"ts\":%u}",
p->dev,p->code,p->ts);
if(mes_post(body)==0)
qout=(qout+1)&255;
else{
os_delay(200); // 网络断,留队列重发
break;
}
}
}
断网时队列在RAM会丢,关键产线落文件/FRAM,恢复后补传。
五、多设备汇聚架构
扫码枪1~N ──RS485/串口服务器──▶ 边缘网关/工控机
│
Station ID解析
│
去重+本地缓存队列
│
MES TCP/HTTP
网口枪直接TCP Client连MES,IP按工位分配;老RS232加串口服务器转TCP。 PLC产线走Modbus/Profinet网关,PLC只做工位锁存防重。
六、落坑清单
键盘HID模式收码→焦点丢了全错
多枪同Station ID→数据来源分不清
接收事件里直接HTTP→阻塞丢包
无结束符切帧→粘包错位
全局去重→不同线同SN被误删
不上时间窗→物体抖动重复触发
断网不缓存→整段产线数据没了
波特率/结束符没配对→乱码截断
光电触发没锁存→一次过件扫三次
上传失败不重发→MES缺录
七、落地顺序
每台枪设唯一站号,配结束符\r\n
每路串口独立缓冲,ISR只收字节
结束符切帧,超长丢弃
按设备维度时间窗去重
解析后进本地队列,不在收码路径联网
上传线程批量发MES,失败回队
断网落本地文件/FRAM,恢复补传
PLC工位锁存+光电防重兜底
多扫码枪对接的核心不是“会读串口”,是接收和上传解耦:字节流靠结束符切干净、同工位时间窗挡重复、本地队列扛网络抖动、Station ID保追溯。 解析做在边缘主控,上传走批量异步,MES只收干净数据——产线跑再快也不会丢码,事后查日志也能定位到哪台枪、哪个工位、什么时间出的码。





