3. 视觉检测结果的数据结构
视觉系统输出的“结果”并不是一句“合格/不合格”,而是一组结构化数据。PLC 要做的判定、分拣、报警、追溯,全部依赖这组数据能否被稳定、无歧义地读取。因此本节的核心任务是:先把视觉侧的结果字段定义清楚,再把它映射成 PLC 能直接寻址的寄存器格式。
一、视觉结果的标准字段定义
一个可工程化的单次检测结果,通常包含以下字段。字段名可以不同,但语义必须固定:
- 判定结果 Result:整件产品的总判定,取值 OK / NG。建议用整数 0=OK、1=NG,避免字符串比较。
- 缺陷类型 DefectType:NG 时的分类编码,如 1=划伤、2=脏污、3=缺料、4=尺寸超差、5=错件。OK 时填 0。
- 缺陷数量 DefectCount:本件检出的缺陷个数,用于判断是否多缺陷。
- 坐标 X、Y:缺陷在图像坐标系中的位置,单位像素。需明确原点在左上角、X 向右、Y 向下。
- 尺寸 Width、Height:缺陷外接矩形宽高,单位像素;也可用面积 Area。
- 置信度 Score:0~100 的整数,表示模型对该缺陷判定的可信程度。
- 图像 ID ImageID:本次检测图像的唯一编号,用于追溯原图。
- 时间戳 Timestamp:检测完成时刻,用于与 PLC 节拍对齐。
这里有一个关键约定:坐标与尺寸统一使用像素整数,不直接传毫米。原因是像素是视觉侧的原生量,转毫米需要标定系数,一旦标定变更,历史数据就不可比。若 PLC 需要毫米值,应在 PLC 侧用标定系数换算,或由视觉侧额外输出一份毫米字段,二者不可混用同一寄存器。
二、从视觉结构体到 PLC 寄存器的映射
PLC 不认 JSON、不认字符串,它只认连续的寄存器区。因此映射的本质是:把结构体按固定偏移量铺平成一维数组。以三菱/西门子常见的 32 位寄存器为例,一个结果块可规划为 16 个字(Word):
| 偏移 | 字段 | 类型 | 说明 |
|---|---|---|---|
| D100 | Result | INT16 | 0=OK,1=NG |
| D101 | DefectType | INT16 | 缺陷分类编码 |
| D102 | DefectCount | INT16 | 缺陷个数 |
| D103 | Score | INT16 | 0~100 |
| D104 | X | INT32 | 占 D104/D105 |
| D106 | Y | INT32 | 占 D106/D107 |
| D108 | Width | INT32 | 占 D108/D109 |
| D110 | Height | INT32 | 占 D110/D111 |
| D112 | ImageID | INT32 | 占 D112/D113 |
| D114 | DataReady | BOOL | 数据就绪握手位 |
| D115 | Ack | BOOL | PLC 应答位 |
注意 INT32 在 PLC 中占两个字,存在高低字顺序问题。三菱、西门子、欧姆龙对 32 位数据的字序约定不同,必须在通信配置中显式指定,否则会出现“X 坐标变成 65536 倍”这类典型错误。工程上建议:视觉侧发送前先确认目标 PLC 的字序,并在联调时用一个已知值(如 X=1000)验证读回是否正确。
三、握手时序:数据何时有效
寄存器写好了不等于 PLC 能读。必须用握手位保证“读到的是完整的一帧”。典型流程是:视觉侧先写数据区,最后置 DataReady=1;PLC 检测到上升沿后读取全部字段,处理完置 Ack=1;视觉侧收到 Ack 后清 DataReady,准备下一帧。这样可避免 PLC 读到半帧数据。
四、字段取值与边界处理
映射中最容易出问题的是边界值。工程上建议明确以下规则:
- OK 件:Result=0,DefectType=0,DefectCount=0,Score 可填 100 或 0,坐标尺寸填 0。PLC 侧只判 Result,不读坐标。
- NG 件:Result=1,DefectType 必填,Score 低于阈值时是否仍判 NG,需在视觉侧先决定,PLC 不再二次判断。
- 多缺陷:若一件有多个缺陷,只上传“最严重”或“面积最大”的一个,其余用 DefectCount 计数。PLC 寄存器区不展开数组,避免长度不定。
- 无结果:相机未触发或通信超时,Result 保持上一次值会误判,应设一个独立状态位或约定 Result=2 表示“无数据”。
五、一个可用的映射配置示例
下面是一段视觉侧发送前的字段打包伪代码,展示如何把结构体按偏移写入寄存器数组。示例参数为教学假设值,非实测:
// 假设本次检测:NG,划伤,1 个缺陷,Score=87
// X=1240, Y=860, W=36, H=12, ImageID=20240513_0007
regs[0] = 1; // D100 Result = NG
regs[1] = 1; // D101 DefectType = 划伤
regs[2] = 1; // D102 DefectCount
regs[3] = 87; // D103 Score
regs[4] = 1240; // D104~105 X (INT32)
regs[6] = 860; // D106~107 Y
regs[8] = 36; // D108~109 Width
regs[10] = 12; // D110~111 Height
regs[12] = 202405130007; // D112~113 ImageID
// 最后一步:置就绪位
regs[14] = 1; // D114 DataReady = 1
联调时用一个已知值验证:把 X 写成 1000,在 PLC 侧读 D104/D105 组合值,若读回 1000 则字序正确;若读回 65536000,说明高低字颠倒,需在通信配置中交换字序。这个验证只需做一次,但能避免后续所有坐标类缺陷定位错误。
总结来说,视觉结果的数据结构设计要抓住三点:字段语义固定、寄存器偏移固定、握手时序固定。做到这三点,PLC 侧的程序就退化成“读固定地址、判 0/1、执行动作”,稳定且易维护;视觉侧也能独立升级算法而不影响 PLC 逻辑。