简介:面向创维电视及智能终端生产线的串码写入与校验工具包,专注解决SN码、MAC地址等关键参数的批量写入、读取与校验,同时集成条码打印与工位检测能力,适用于工厂测试人员、产线信息化工程师以及自动化设备集成商,尤其适合需要快速部署或定制写码逻辑的场景。压缩包共18个文件,大小仅151KB,以cfg、txt、ini等配置文件为主体,辅以bat脚本、btw条码模板和xls表格,分别用于厂商ID与供应商数据维护、高安检测参数设置、BarTender标签版面定义及标准指令格式说明。工具包的目录结构反映出从设备识别、数据交互到标签输出的完整流程,如主程序与服务模块的协同、组件注册脚本等,虽然包体小巧,但覆盖了产线扫码、写码、打标、工位联调的关键环节。目前已有33人学习,对于希望掌握产线写码工具组成或二次开发的工程师,可以参考其中的配置结构和脚本逻辑,减少从零搭建环境的时间成本。 一台电视下线时,机身后侧贴的那张标签上有一串SN和一张二维码,很多人以为这是打印工序的事。其实在贴纸之前,这串代码已经通过工具软件写进了电视主板的存储区域,写了之后还要在下个工位用扫码枪扫回来,系统自动比对是不是刚才那台、有没有写错、型号批次对不对。这个“写入→校验→打印→工位确认”的链路,就是我今天想讲的串码写入与校验工具包。我是前几年在电子制造产线上做上位机软件出身,前后做过几条电视、机顶盒产线的写码测码工具,今天把整套思路和踩过的坑整理出来,供做产线自动化的朋友参考。
1. 产线工具包要解决的三个真实痛点
1.1 串码体系不只是SN:电视设备出厂到底要写入哪些身份信息
很多人以为串码就是SN序列号,真正做过产线才知道,一台电视或机顶盒要写入的身份信息远不止一个SN。通常包括:整机SN(机身唯一序列号)、WIFI模组的MAC地址、蓝牙MAC地址、产品型号编码、生产日期批次、软件版本号,有的还要求写工厂代码和客户定制码。这些信息分布在不同模组和存储分区里,有的走系统属性,有的要走工厂私有接口,不是一个简单赋值能解决的。
1.2 通用工具和手工方式在产线上的问题
在没有专用工具之前,产线常见的做法是拿一个通用写码软件,手动输入SN再点写,或者用Excel管理号段,复制粘贴。这种方式在低速小批量时还能凑合,一旦节拍压到25秒一台,问题就接踵而至:
- 人工输入SN容易漏字符、看错位,写坏设备进维修站;
- 没有校验码,写错一位字符设备照样能开机,到售后才发现序列号对不上;
- 写了SN但不回读,实际没有生效也直接放行,等到包装工位扫码才发现主板里是空的;
- 标签打印和写入内容各管各的,标签打的是A号,设备里面写的是B号。
所以这套工具包的核心价值,不是把某个功能做得花哨,而是把“写入、校验、打印、检测”四个动作绑在一起,用软件强制流程顺序,从工艺上防呆。
1.3 站在“工艺防呆”角度的整体设计思路
我在设计工具时给自己定了几条原则:
- 能做自动判断的,绝不让操作人员做选择题;
- 能回读校验的,绝不信单次写入返回值;
- 能记录日志的,每个动作都留痕;
- 能配置驱动的,不同型号、不同产线只改配置文件,不改代码。
这几条贯穿了整个工具包的设计。后面所有模块都是围绕它们展开的。
2. 串码规则设计与校验码算法选型
2.1 串码号段的拼接规则
串码不是随便生成的一串数字,它要承载追溯信息。以电视SN为例,比较通用的组合是:
- 厂商标识段:2~3位字母,代表品牌或生产基地;
- 产线代码段:1~2位数字或字母,标识是哪条流水线;
- 生产日期段:年月日,或者用年份和周数组合;
- 流水号段:当天/当班次递增数字,长度由产能决定。
比如一种格式是“3个字母厂段 + 2位产线号 + 2位年份 + 2位月份 + 2位日期 + 5位当日流水号”,拼出来一共16位。为什么不用纯数字?因为字母加数字在相同长度下能容纳更多编码空间,而且印刷成条码后容易被扫码枪识别。
实际生产时,号段一般由MES系统下发,工具包要做的不是自己生成号段,而是接收MES下发的号段池,存到本地缓存,逐台分配。一个重要的防重设计是:每次取号后,立即将这个号标记为“已用”,写入本地数据库,程序崩溃重启也不会重复取号。如果直接从内存取号不做落盘,中途断电重启,大概率会把已经贴上标签的SN再写一次,这是很严重的质量事故。
2.2 为什么产线校验偏爱CRC而不是简单校验和
校验码的作用是快速识别串码传输出错。常见的校验方式有累加校验和、CRC8、CRC16、CRC32,还有MD5这类哈希。很多刚接触的人觉得校验和最简单,加起来取个余数就行。但校验和有个致命问题:两个数位发生对调或一个字符加一、一个字符减一,累加结果可能不变,错误就漏过去了。
产线写入场景,最关心的是查出“单位字符错误”和“相邻字符交换”这两类高频问题。CRC循环冗余校验对这两类错误非常敏感,16位CRC可以保证对单比特错误和绝大多数突发错误都能检出。所以我最终在SN长字符串校验上选了CRC16,具体是CRC16-CCITT或CRC16-Modbus,取决于后端MES和售后系统的预期。如果MES系统本身用Modbus协议维护,就选CRC16-Modbus,统一标准,不折腾。
2.3 CRC16-Modbus计算细节与跨语言一致性
CRC16-Modbus的算法参数我遇到过很多次实现不一致的情况,这里把参数说清楚:
- 宽度:16位;
- 多项式:0x8005(反转后是0xA001);
- 初始值:0xFFFF;
- 输入数据是否反转:是(LSB first);
- 输出结果是否反转:是;
- 结果异或值:0x0000。
如果工具包用C#或Python实现,MES端用Java或C,务必统一这几个参数。我见过一个项目,写入端和校验端一个用查表法、一个用按位计算法,结果算法流程有一处反射处理的差异,导致同一个SN两侧算出的校验码不一致,现场排查了整整一天,最后发现是CRC初值写错。为了避免这种问题,建议在工具包开发时直接写一组已知测试向量做单元测试,比如输入“123456789”时CRC16-Modbus应该输出0x4B37,输入“ABCDEF”应该输出多少,先固定下来再开发业务逻辑。这样跨语言对接时,只要各自跑同一组测试向量就能验证实现是否一致。
3. 写入设备的核心流程与Android侧通信实践
3.1 ADB调用与工厂模式下写入SN的路径
电视、机顶盒这类设备大多基于Android系统,产线上写码一般是走ADB通道,而不是打开系统设置界面手动输入。ADB的全称是Android Debug Bridge,产线工具通过它和设备的bootloader或工厂模式通信。
ADB写入SN的思路有两种层次。第一种是对普通系统属性,比如设置软件版本或默认语言,可以直接用:
adb shell setprop ro.product.factory.version "V1.0.2"这种方式改的是运行时属性,重启后可能丢,适合临时参数。第二种是对真正要持久化的SN、MAC这类关键数据,setprop是不够的,需要调用芯片方案商的工厂接口,写入到专门的NV存储或工厂分区。不同方案商接口不同,但产线工具层的调用方式一致:通过ADB下发一个intent或执行一个工厂测试APK的特定Activity,由设备端程序接收广播并执行写入。
举个我实际用过的流程:
adb shell am broadcast -a com.factory.WRITE_SN --es sn "SN1234567890123"设备端工厂APK收到这个广播后,调用底层接口写入NV存储,同时把写入结果通过logcat或文件回传。工具这边做的是把这段完整命令封装好,执行后自动抓取设备端回显的“WRITE_OK”或“WRITE_NG”。
写到这里必须提醒一个容易忽略的点:ADB的USB通道在产线上经常因为线材或HUB供电不稳导致设备掉线。更稳妥的方案是网络ADB,让设备通过有线网络连接,工具用adb connect 设备IP:5555连接,这样一台电脑能同时管理多台设备,而且不占USB口。不过要注意,网络ADB首次连接需要授权确认,有些产线设备出厂模式没有确认界面,还需要在工厂镜像里预先配置adb白名单或关闭授权提示。
3.2 回读校验的“写入≠生效”问题
这是写码工具里最重要的一条经验:写入指令返回成功,绝不等于系统里已经写对了。在我的工具里,写完任何一个字段都会强制做回读:
- 写完SN,立刻执行
adb shell getprop ro.serialno或者从工厂分区重新读取; - 写完MAC,回读
adb shell ifconfig wifi0或通过接口读取当前MAC; - 回读的数据与预写数据做逐字符比对,不只是简单相等,还要比对长度。
曾经遇到过一种情况:写入接口返回成功,但设备端使用的同步机制是异步落盘,工具回读时数据还没刷进去,读出来是空的。如果直接按写入成功放行,到了售后该台设备的SN在系统里缺失。所以我一般会要求设备端设计成同步写入,或者工具端在回读前做一次等待延时,必要时重启设备后再回读确认。
把回读放在流程里还有个附加价值:它可以同时验证设备在写入过程中是否发生蓝牙或WIFI模组重启,如果MAC回读失败,说明模组通信有问题,及时隔离。
3.3 写入流程状态机与超时控制
产线工具绝对不是把写码命令一执行就完事。现场操作员一天要重复几百次动作,工具必须状态清晰、防误操作。
我设计的流程状态机大致如下:
- 空闲状态:操作员点击“开始”,工具自动连接设备;
- 取号状态:从本地号段池取一个SN,等待操作员或自动触发写入;
- 写入状态:执行ADB广播/命令,写入SN、MAC、蓝牙地址等字段;
- 回读状态:逐个字段回读并比对,任一步失败进入异常分支;
- 打印状态:全部校验通过后,自动触发打印机出标签;
- 完成状态:日志落盘,界面提示放行,状态机回到空闲等待下一台。
每个状态都要有超时约束。我一般设置:设备连接超时15秒,写入命令执行超时30秒,回读轮询最多10次,单次间隔500毫秒,超过即判定失败。如果不用状态机,直接顺序执行,一旦中间步骤卡住,整个工位就会停线,产线吵起来很难收场。
4. 条码打印与工位检测的联动设计
4.1 标签打印:走ZPL指令而不是驱动打印
条码打印这块,很多人习惯在电脑上装好打印机驱动,用打印控件生成标签。但在产线环境,我对驱动方案一直保留意见。产线工控机经常换、驱动版本五花八门,而且打印控件的页面设置很容易被误改。稳妥的做法是走ZPL指令,直接向打印机发送指令文本。
ZPL(Zebra Programming Language)是条码打印机的标准指令集,主流工业打印机基本都支持。比如打印一个Code128条码和QR码的指令大概是:
^XA ^FO20,20^BC^FD>;SN1234567890123^FS ^FO20,80^BQN,2,6^FDLA,SN1234567890123^FS ^CF0,30 ^FO20,150^FDModel: TV-ZX-2024^FS ^XZ工具通过TCP连接打印机的9100端口,把这段指令直接发过去。这样做的好处是:
- 不依赖打印机驱动,跨电脑环境一致;
- 打印速度快,不占用系统打印队列;
- 标签内容完全由程序渲染,模板改起来只是改文本指令。
一个容易踩的坑是:打印完成后立即放行,操作员撕下标签时打印机切纸还没完成,下一张标签的数据有概率串内容。更可靠的做法是,打印完主动向打印机查询状态,确认“打印完成”再亮绿灯放行。
4.2 工位检测逻辑:扫码后自动比对
工位检测是这套工具包的第二大模块。它的典型场景是这样:1号工位负责写码和打标签,2号工位负责贴标签并扫码确认。2号工位操作员用扫码枪扫一下机身标签,工具收到条码数据后自动做以下几件事:
- 解析出SN和校验码,校验码不对直接报警;
- 查询本地数据库,确认该SN在1号工位确实写码成功;
- 查询MES/数据库,确认该SN没有被重复扫描过;
- 全部通过后,上传条码数据到MES,点亮绿色信号灯放行。
这里有一个设计原则:工位检测不是把扫描到的条码原样上报,而是要“消费”前一个工位的操作结果。如果1号工位写入失败,但标签已经打出来了,那2号工位扫描时必须能查出来并拦截。所以我这边在本地数据库里维护了一张“写码记录表”,写入成功的SN才标记为“可扫描”,否则扫码结果一律视为NG。
4.3 与三色灯、PLC等外部设备的配合
工位检测不只是软件层面的事,产线上通常还有三色信号灯、气动夹具或传送带,这些一般由PLC控制。软件和PLC的通信方式,我见过串口Modbus、TCP Modbus、甚至直接接IO卡的都有。我的建议是优先走Modbus TCP,原因是传输稳定、接线简单、和PLC程序对接容易。
工具在工位检测通过后,通过Modbus TCP向PLC写入一个线圈或寄存器值,比如“放行”,PLC据此控制信号灯变绿、松开夹具。如果检测失败,写入“拦截”,灯变红并发出蜂鸣。这样做的好处是:即使上位机软件出现异常崩溃,PLC还能保持当前状态,不会误放行;同时操作员判定结果不是看电脑屏幕,而是看信号灯,符合产线习惯。
5. 工具包分层架构与配置化设计
5.1 三层架构:界面、业务、通信分离
这个工具包一开始如果只是自己用,代码怎么写都行。但一旦要推广到多条产线、多个工厂,架构就必须分层。我采用的是最基础的三层:
- 界面层(UI):负责显示当前状态、SN信息、操作按钮、结果告警;
- 业务层(BLL):负责流程状态机、校验算法、数据比对、打印内容渲染;
- 通信层(DAL):负责ADB命令执行、网络打印机通信、Modbus TCP读写、MES/数据库交互。
分层最大的价值是方便排查问题。比如工位检测上传MES失败,只排查通信层,不用去翻界面代码;比如二维码内容不对,只找业务层模板渲染逻辑。如果全部揉在一起,线上出问题,改一处崩三处。
5.2 用配置文件适配不同产品线和型号
电子制造产线最怕的是“每条线单独开发一套工具”。同一套工具包要能通过配置适配不同产品,我采用的做法是外部XML或JSON配置文件,里面定义:
- 产品型号代码和串码拼接规则(厂段、产线位、日期格式、流水号位数);
- 需要写入的字段列表(SN、WIFI MAC、BT MAC...);
- 校验码算法类型和CRC参数;
- 标签模板(选择哪个ZPL模板,模板中哪些字段需要填充);
- 工位检测的放行条件(是否检查MES、是否允许重扫、上传地址)。
换产品线时,只需要新增一个配置文件,或者用界面上的“切换产品”下拉框加载不同配置。程序内部所有逻辑读配置文件运行,代码层面不做产品分支判断。
5.3 日志留痕:从“出现异常”到“可追溯”
做产线工具,日志才是保命的东西。我的日志设计分三层:
- 操作日志:记录每一次取号、写入、回读、打印、工位扫描,包含操作员姓名/工号、SN、时间戳、结果;
- 通信日志:记录ADB原始命令和返回值、打印机返回状态、Modbus读写帧;
- 错误日志:记录异常堆栈和关键上下文。
操作日志建议同时写入本地数据库和上传到MES,本地数据库用于快速查询,MES用于跨线追溯。曾经出现过一次售后投诉:某台电视SN在官方售后系统里查不到生产记录,最后是通过操作日志反查,发现操作员在写码工位误操作跳过了上传步骤,问题定位只用了几分钟。没有日志的话,这种纠纷基本说不清楚。
6. 产线运行半年后的踩坑记录
6.1 CRC算法跨语言不一致
这个坑在前面提过了,这里再补充一个实例。我们的工位检测端用Java,工具端用C#,双方约好用CRC16-Modbus。对接后发现相同SN算出的校验码完全不同,排查了一轮,最后发现Java端实现时把输入数据按字节做了无符号右移,而C#端是直接按byte类型计算,符号位导致多项式运算结果不一致。这种问题光看代码很难发现,用测试向量一跑就暴露了。所以我现在不管哪一端实现CRC,都强制要求先跑标准测试向量再联调。
6.2 ADB设备掉线与端口冲突
产线工控机经常有多个设备同时插USB,ADB服务会出现端口冲突或设备枚举混乱。我遇到的现象是:十几台设备在同一台电脑上切换,adb devices下面有时能看到,有时看不到,甚至偶发把设备串号都读错。解决办法是:
- 给每台设备配置固定的网络ADB方式,用IP区分,不依赖USB枚举;
- 执行ADB命令前先
adb kill-server再adb start-server,避免服务僵死; - 每次只对当前目标IP执行
adb connect,连接成功后立即执行命令,完成后adb disconnect,防止多个连接互相干扰。
6.3 打印标签和写入内容不一致
这个问题的来源很隐蔽:打印机缓存了上一次的标签数据。ZPL指令发送成功后,打印机把数据存在内部缓存里,如果上一次打印因为切纸检测异常没有完全结束,下一次触发打印时,打印机会把旧缓存再执行一遍。表现就是操作员听到打印声,但出来的标签还是上一台SN的。排查了很久,最后是在ZPL模板开头增加了一条清除缓存指令,并且每次打印完主动查询^HS打印机健康状态,确认缓存清空后再放行。
6.4 工位扫描过快导致的漏扫
2号工位操作员熟练之后,扫码动作特别快,扫码枪刚扫完信号还没稳定,软件如果立刻做逻辑判断,偶尔会把条码读成不完整的数据。解决方式是加一个稳定时间窗口:扫码枪触发中断后,延时80毫秒再读取完整数据;同时业务层判定条码长度,不符合SN长度要求直接忽略,不进入校验逻辑,也就不会误报。
这个工具包从立项到稳定运行,前后改了大大小小几十轮,最深刻的体会是:产线自动化工具的价值不是功能有多炫,而是能不能在高压节拍下稳定运转、出问题时能不能快速定位、换产品时能不能快速切换。如果你也在做类似的产线写码校验工具,建议一开始就把校验算法参数固定成测试用例,把日志结构想清楚,把ADB通信的超时和重试机制做好,这三个地方投入的时间,后面都会加倍省回来。
本文还有配套的精品资源,点击获取