4. 数据类型不匹配(下):数组/列表维度错误、结构体字段缺失、枚举值越界
好,咱们接着聊数据类型不匹配。上一节讲了基础类型,这一节我重点说说数组、结构体和枚举——这三个坑,我在现场调试时踩过无数次。
你想想看,配方变量绑定的时候,PLC 那边传过来一个数组,HMI 这边却按标量去接,或者结构体字段对不上号,那画面……嗯,画面太美我不敢看。
4.1 数组/列表维度错误
数组维度错误,说白了就是“装东西的盒子大小不对”。PLC 发过来 10 个元素,你只准备了 5 个位置,或者反过来。系统不会帮你自动裁剪,它只会报错或者乱读内存。
4.1.1 一维数组长度不匹配
这是最常见的。我记得有一次在食品产线,配方里有个温度曲线数组,长度是 20。HMI 那边绑定的时候,工程师手快,配成了 10。结果每次下载配方,最后 10 个温度值全是垃圾数据。
// PLC 侧定义
ARRAY[0..19] OF REAL; // 20 个元素
// HMI 侧错误绑定
ARRAY[0..9] OF REAL; // 只有 10 个元素 —— 维度不匹配!
// 正确做法
ARRAY[0..19] OF REAL; // 必须一致
4.1.2 多维数组索引顺序搞反
多维数组的坑更隐蔽。PLC 里定义的是 ARRAY[0..3, 0..5],HMI 那边如果配成 ARRAY[0..5, 0..3],虽然元素总数都是 24,但数据排列顺序完全乱了。
我个人习惯的做法是:在绑定多维数组之前,先在纸上画个表格,把索引顺序标清楚。别嫌麻烦,这一步能省你半天调试时间。
| 场景 | PLC 定义 | HMI 错误绑定 | 后果 |
|---|---|---|---|
| 一维数组 | [0..9] | [0..4] | 数据截断,后 5 个元素丢失 |
| 二维数组 | [0..3, 0..5] | [0..5, 0..3] | 行列颠倒,数据错位 |
| 三维数组 | [0..1, 0..2, 0..3] | [0..3, 0..2, 0..1] | 数据完全混乱,难以排查 |
4.2 结构体字段缺失
结构体这东西,用起来方便,但绑定的时候特别容易出问题。PLC 那边结构体有 8 个字段,HMI 这边只绑了 6 个,或者字段名拼写错了——系统不会告诉你“字段缺失”,它只会给你一个空值或者报错。
4.2.1 字段数量不一致
我在项目中遇到过一件事:一个设备参数结构体,PLC 侧有 12 个字段,HMI 侧只绑了 10 个。看起来好像没什么大问题,但实际运行时,只要配方写入操作涉及那 2 个缺失字段,整个结构体就会写入失败。
// PLC 结构体定义
TYPE DeviceParam :
STRUCT
Speed : REAL; // 速度
Temp : REAL; // 温度
Pressure : REAL; // 压力
Mode : INT; // 模式
Alarm : BOOL; // 报警标志
END_STRUCT
END_TYPE
// HMI 错误绑定 —— 缺少 Pressure 和 Alarm 字段
// 绑定结果:写入配方时,结构体数据不完整,系统拒绝写入
4.2.2 字段类型不匹配
字段名对了,但类型不对,这也是常见问题。PLC 里是 REAL,HMI 里配成了 INT,或者 BOOL 配成了 BYTE。系统在转换时可能会截断数据,或者直接报类型错误。
| PLC 字段类型 | HMI 错误类型 | 可能后果 |
|---|---|---|
| REAL (32位浮点) | INT (16位整数) | 小数部分丢失,大数值溢出 |
| DINT (32位整数) | INT (16位整数) | 数值超过 32767 时溢出 |
| BOOL (位) | BYTE (8位) | 可能只读取最低位,其他位被忽略 |
| STRING[20] | STRING[10] | 字符串被截断,末尾字符丢失 |
4.3 枚举值越界
枚举值越界,这个坑比较隐蔽。PLC 里定义了一个枚举,取值范围是 0~5。HMI 那边如果写入了 6 或者 -1,系统会怎么处理?
答案是:看系统实现。有的系统会直接报错,有的会默默接受然后产生未定义行为。我见过最离谱的一次,枚举值越界导致设备进入了“幽灵模式”——既不是自动也不是手动,PLC 逻辑完全混乱。
4.3.1 枚举值范围检查
绑定枚举变量时,一定要确认 HMI 侧的取值范围和 PLC 侧完全一致。如果 HMI 侧允许用户输入数值,必须做范围限制。
// PLC 枚举定义
TYPE MachineMode :
(
Idle := 0, // 空闲
Auto := 1, // 自动
Manual := 2, // 手动
Clean := 3, // 清洗
Error := 4 // 错误
) := Idle;
END_TYPE
// HMI 侧错误:允许用户输入 0~10
// 当用户输入 5 时,PLC 收到无效枚举值,逻辑混乱
// 正确做法:HMI 侧限制输入范围为 0~4
4.3.2 枚举值映射错误
还有一种情况:PLC 和 HMI 的枚举定义不一致。PLC 里 0 表示“空闲”,HMI 里 0 表示“自动”。这种映射错误比越界更可怕,因为系统不会报错,但设备行为完全不对。
嗯,这里要注意:不同品牌的 PLC 和 HMI,枚举的默认值可能不同。有些系统从 0 开始,有些从 1 开始。绑定之前,一定要确认两边的枚举值定义。
4.4 知识结构总览
下面这张图,我把数组、结构体、枚举这三类错误的排查要点整理了一下。你可以把它当成一个快速检查清单。
4.5 快速排查清单
最后,我整理了一个排查清单。下次遇到这类问题,按这个顺序查一遍,基本能定位 90% 的问题。
- 数组维度核对:PLC 和 HMI 的数组长度、维数是否完全一致?
- 索引顺序验证:多维数组的索引顺序是否正确?用坐标值法测试。
- 结构体字段清单:逐字段核对名称、类型、顺序,确保一个不落。
- 枚举值范围:HMI 侧是否限制了输入范围?枚举定义是否一致?
- 全量读写测试:绑定完成后,写入一组测试数据,再读回来对比。