当前位置:首页 > 工业控制 > 工业控制
[导读]流水线多扫码枪不是“开几个串口读字符串”就完事。多台设备并发、快扫粘包、重复触发、网络抖动断传,任一处漏掉都会让MES收到错码或丢码。 正经做法是:每台扫码枪分配Station ID → 串口/RS485独立缓冲收字节 → 结束符切帧 → 时间窗去重 → 本地队列批量上传。


流水线多扫码枪不是“开几个串口读字符串”就完事。多台设备并发、快扫粘包、重复触发、网络抖动断传,任一处漏掉都会让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只收干净数据——产线跑再快也不会丢码,事后查日志也能定位到哪台枪、哪个工位、什么时间出的码。



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭