返回
SCL PLC 编程教程第七篇 数组、结构体、字符串的处理方法:为什么 SCL 更适合做复杂数据处理
很多工程师第一次正式接触数组、结构体、字符串时,心里都会有一点别扭。
因为在以前以梯形图为主的编程习惯里,大家更熟悉的是:
一个按钮
一个输出
一个中间位
一个定时器
一个设定值
一个故障位
也就是说,很多时候我们处理的是“单个变量”。
但一旦项目复杂起来,你会很快发现,工程实际根本不是一直在处理单个变量。
你经常会遇到这些情况:
20 路报警
16 路输入状态
8 路温度采样
一整套配方参数
一整组电机状态
一批工件信息
一组扫码字符
一串通信报文内容
这时候,如果你还一直按“一个变量一个变量地散着写”,程序会越来越难看、越来越难维护。
而数组、结构体、字符串,正是帮助你把这些“零散数据”组织起来的工具。
所以这一篇,你不要把它理解成三个孤立的知识点。
更准确地说,它们共同解决的是一个问题:
当 PLC 程序面对一组数据、一类数据、或者文本数据时,怎样把它们组织得更清楚。
一、先记住这一句最重要的话:单个变量是点,数组和结构体是在组织“数据的形状”
这句话可能一开始稍微抽象一点,但非常值得你理解。
比如以前你可能只写:
Temp1
Temp2
Temp3
Temp4
看起来也能表示四个温度值。
但这种方式的问题是,它只是四个散点。
如果你改成数组:
Temp[1]
Temp[2]
Temp[3]
Temp[4]
那它们立刻就从“四个分散变量”变成了一组有顺序的数据。
再比如你以前可能有:
Motor1_RunCmd
Motor1_RunFB
Motor1_Fault
Motor1_Overload
Motor1_SpeedSP
这也能写。
但如果你用结构体去组织,意思就完全不一样了:
这个数据不再只是几条散乱的变量,而是“1 号电机的完整信息集合”。
也就是说:
数组解决的是“同类数据成组”的问题
结构体解决的是“同一对象的多项属性组织在一起”的问题
字符串解决的是“文本数据怎么表示和处理”的问题
这三者一旦真正理解,你的程序结构感会明显提升。
二、为什么 PLC 项目越来越需要这些数据组织方式
很多人一开始会觉得:
“我做现场控制,真的需要数组和结构体吗?”
答案是:
项目越简单,越感觉不明显;项目越复杂,越离不开。
因为设备一复杂,控制就不再只是几个点位开关了。你会越来越频繁地碰到这些需求:
1. 批量处理一组同类对象
例如:
所有报警位统一复位
所有温度点统一超限判断
所有输入点统一做状态扫描
所有产品槽位统一检查占用情况
这时候数组就非常自然。
2. 组织一个对象的完整信息
例如一个气缸,不只是“有个输出位”,它还可能有:
伸出命令
缩回命令
伸出到位
缩回到位
动作超时
故障状态
自动允许
手动允许
这些信息如果散着写,后面非常容易乱。
而结构体可以把它们聚合成“一个对象的一组属性”。
3. 处理文本类数据
例如:
扫码器读到的条码
产品型号名称
报警描述
配方名称
通信字符串
这时候字符串就会变得很重要。
所以你可以这样理解:
数组、结构体、字符串,不是为了让程序显得高级,而是为了让复杂数据不至于散掉。
第一部分:数组
三、数组到底是什么
数组最简单的理解就是:
把一组同类型的数据,按顺序放在一起,并用下标来访问。
这句话里有两个关键词:
第一,同类型
也就是说,这一组里的元素通常类型一致。
比如都是 BOOL,或者都是 INT,或者都是 REAL。
第二,有编号顺序
也就是说,你不是靠不同变量名区分它们,而是靠“第几个”来区分。
例如:
Alarm[1]
Alarm[2]
Alarm[3]
这就表示一组报警位。
如果换成以前那种散写方式,可能就是:
Alarm1
Alarm2
Alarm3
表面看差不多,
但一旦你要循环处理、批量复位、统一比较,数组的优势就会越来越明显。
四、数组最适合处理什么场景
1. 一批规则相同的数据
例如:
16 路输入状态
8 路模拟量
20 路报警位
12 个工位占用状态
只要这些数据的处理规则相似,数组通常都很合适。
2. 需要配合循环批量处理的场景
前一篇我们讲过 FOR 循环。
数组和 FOR 几乎是天然搭档。
例如:
FOR i := 1 TO 16 DO
IF SensorOK[i] = FALSE THEN
FaultExist := TRUE;
END_IF;
END_FOR;
这种逻辑如果不用数组,会写得非常散。
3. 顺序明确、编号明确的对象集合
例如:
第 1 到第 10 个工位
第 1 到第 8 路温度
第 1 到第 32 个报警点
这些都非常适合数组。
五、数组和“很多个类似变量”最大的区别是什么
这点一定要讲透。
例如你有 8 路温度,你可以这样写:
Temp1
Temp2
Temp3
Temp4
Temp5
Temp6
Temp7
Temp8
这样当然也能做。
但问题在于,这 8 个变量在程序眼里,其实彼此没什么结构关系。
你自己知道它们是“一组温度”,但程序只是看到 8 个独立名字。
而如果你写成:
Temp[1]
Temp[2]
Temp[3]
...
Temp[8]
那它们就正式成为一组可遍历、可统一处理的数据。
差别就在这里:
很多个类似变量,只是“看起来像一组”;
数组,是“真正被程序当成一组”。
这也是为什么数组一旦用起来,程序会更像“规则处理”,而不是“零散堆逻辑”。
六、数组最常见的工程用途
1. 批量报警处理
例如:
一键清除所有报警位
遍历查找第一个故障报警
统计当前有几个报警正在激活
2. 多通道模拟量处理
例如:
对 8 路温度统一限幅
对 4 路压力统一滤波
对多路液位统一超限判断
3. 工位状态管理
例如:
12 个工位是否有料
12 个工位产品编号
12 个工位加工完成状态
4. 配方参数组
例如:
一组产品参数
一组延时设定
一组速度设定
一组压力设定
5. 历史数据缓存
例如:
最近 10 次采样值
最近 20 次称重结果
最近 50 条报警编号
这些场景一旦出现,数组的优势就会非常明显。
七、使用数组时最重要的习惯:边界意识
数组特别好用,但也特别容易因为边界没想清楚而出问题。
比如你的数组定义是 1 到 10,那么你用 FOR 遍历时,就必须严格对应这个范围。
如果你写成 1 到 12,或者从 0 开始,就可能出问题。
所以每次用数组时,都要问自己:
下标从几开始
到几结束
循环范围是不是一致
有没有越界风险
我有没有漏掉第一个或最后一个元素
这和前一篇讲循环时的边界意识是完全连在一起的。
一句实在话:
数组本身不难,真正容易出错的是“编号范围”和“访问边界”。
八、数组为什么特别适合和循环配合
我们前面讲过,循环的本质是“对一组对象重复同样处理”。
而数组的本质是“把一组对象按编号组织起来”。
这两者一结合,就非常顺。
例如你要对 8 路温度做超温报警:
FOR i := 1 TO 8 DO
IF TempPV[i] > TempHighLimit[i] THEN
TempHighAlarm[i] := TRUE;
ELSE
TempHighAlarm[i] := FALSE;
END_IF;
END_FOR;
这段程序的价值不只是代码短。
更重要的是,它表达了一个非常清晰的工程规则:
对 8 路温度,都按同样的规则判断。
这就是结构化编程的味道。
九、数组适合做“同类数据”,但不适合硬塞“不同意义的数据”
这一点很重要。
比如下面这些适合数组:
8 路温度
16 路输入
12 个工位占用状态
因为它们本质上是同一类数据的多个元素。
但如果你把这些放在一个数组里,就不太合适:
启动按钮
温度设定
报警代码
产品名称
因为它们不是同一类数据,意义完全不同。
这时候如果硬塞成数组,程序会变得很别扭,也不利于维护。
所以你要记住:
数组适合“横向一排同类对象”,
不适合把风马牛不相及的数据硬放成一组。
第二部分:结构体
十、结构体到底是什么
如果说数组解决的是“很多个同类元素怎么放在一起”,
那么结构体解决的就是:
一个对象有很多不同属性,这些属性怎么归到一起。
例如一台电机,它可能有这些信息:
启动命令
停止命令
运行反馈
故障状态
热继电器报警
允许启动
当前速度
速度设定
这些变量彼此不是“同类元素排成一列”,而是“同一个对象的不同方面”。
这时候,结构体就特别合适。
你可以把结构体理解成:
给一个对象做一张信息表,把它相关的字段集中放在一起。
十一、结构体和数组最大的区别是什么
这个问题非常关键。
数组
强调的是:
一组元素
元素类型通常相同
通过下标区分第几个
结构体
强调的是:
一个对象
对象有多个字段
字段可以类型不同
通过字段名区分是什么属性
例如:
数组更像这样
8 路温度值:
Temp[1]
Temp[2]
Temp[3]
这是“同一类数据的一组”。
结构体更像这样
1 号电机的信息:
RunCmd
StopCmd
RunFB
Fault
SpeedSP
SpeedPV
这是“一个对象的多种属性”。
所以你可以把它们这样区分:
数组是很多个同类点排成一列;
结构体是一个对象展开成很多属性。
十二、结构体为什么特别适合工程项目
因为工程项目里的很多对象,本来就不是单一变量,而是一组相关数据。
例如:
一个气缸
它至少可能包括:
ExtendCmd
RetractCmd
ExtendFB
RetractFB
TimeoutAlarm
ManualEnable
AutoEnable
一个电机
可能包括:
StartCmd
StopCmd
RunFB
Fault
Overload
Permit
Ready
SpeedSP
SpeedPV
一个工位
可能包括:
Occupied
ProductID
ProcessDone
ClampOK
NGFlag
一条报警记录
可能包括:
AlarmID
Active
Acked
Timestamp
Description
这些东西如果全散着写,后面越来越大时很难维护。
而如果用结构体组织,你会明显感觉程序变得更有“模块感”。
十三、结构体最典型的工程价值:让程序更像“对象”,而不是一堆碎变量
这一点特别值得体会。
以前你可能写的是:
Motor1_RunCmd
Motor1_RunFB
Motor1_Fault
Motor1_Permit
Motor1_SpeedSP
看起来也没错。
但如果项目里再来一台 Motor2、Motor3、Motor4,你很快就会进入复制命名的世界。
而结构体思路更像是:
“电机”本身就是一个对象,它天然有一组属性。
一旦你这样思考,后面的程序组织会完全不一样。
尤其做标准化模块、重复设备、批量对象管理时,结构体会非常有价值。
十四、结构体特别适合和功能块、数组继续结合
这一点虽然现在你还没有完全展开,但先建立概念非常有帮助。
结构体本身已经能组织一个对象的字段。
而一旦后面你把它和功能块结合,就能形成更清晰的模块边界。
如果再进一步和数组结合,甚至还能形成:
一组对象,每个对象内部又有自己的多项属性。
例如:
10 个工位,每个工位都有 Occupied、ProductID、DoneFlag
4 台电机,每台电机都有 RunCmd、Fault、SpeedSP、SpeedPV
这种写法在大型工程里非常常见,也很有力量。
所以你现在先记住:
数组和结构体不是互相替代,而是经常配合使用。
十五、什么时候应该想到结构体
以后你遇到这些场景时,就应该本能想到结构体。
1. 一个设备单元有很多相关状态和命令
比如电机、气缸、阀门、工位。
2. 一条记录包含多个字段
比如报警记录、配方记录、产品数据。
3. 想让程序更模块化、更容易维护
尤其项目开始变大后,这一点越来越重要。
4. 不想再到处写一长串前缀变量名
例如不想一直写:
Station1_XXX
Station1_YYY
Station1_ZZZ
而是想把它们归在同一对象下。
十六、结构体使用时最重要的一个工程意识:字段命名要有层次
结构体虽然能让程序更规整,但如果字段名本身乱起,依然会混乱。
例如一个电机结构体里,如果字段叫:
A
B
C
D1
New2
那结构体也救不了程序。
结构体字段依然要清楚表达含义,例如:
RunCmd
StopCmd
RunFB
Fault
Ready
SpeedSP
SpeedPV
也就是说:
结构体不是让你少思考命名,而是要求你更认真思考命名层次。
因为它本质上是在给对象建立“内部属性表”。
第三部分:字符串
十七、字符串到底是什么
字符串最简单的理解就是:
一段文本。
例如:
产品型号
条码
报警说明
配方名称
设备名称
通信报文字段
很多 PLC 工程师早期接触字符串不多,所以容易觉得它离现场控制有点远。
但实际上,只要你开始接触这些内容,字符串就会很快出现:
扫码器
HMI 文本显示
报警描述
通信协议里的文本字段
产品名称和批次信息
所以字符串虽然不像 BOOL 和 REAL 那么“天天都在用”,但一旦碰到相关项目,它会非常关键。
十八、为什么字符串和数值变量不一样
这点必须先有直觉。
例如:
25.6 这是一个数值
“25.6” 这是一个字符串文本
人看起来可能差不多,但程序眼里完全不是一回事。
数值可以直接比较大小、加减乘除。
字符串更适合做:
显示
拼接
比较是否一致
提取某段文本
作为标识符
所以你一定要记住:
字符串不是“带引号的数字”,它本质上是文本。
十九、PLC 项目里字符串最常见的应用场景
1. 扫码器与条码处理
例如:
读取产品条码
判断条码是否为空
对比条码是否匹配当前配方
保存最近一次扫码结果
2. 配方名称
例如:
A 产品
B 产品
配方001
配方002
3. 报警描述或状态说明
虽然有些系统用报警编号加 HMI 文本表,但在某些场景下也会直接涉及字符串处理。
4. 通信报文内容
例如某些串口通信、文本协议、扫码枪、打印机指令。
5. 设备识别信息
例如工件编号、订单号、批次号。
二十、字符串处理时最重要的意识:它不是数值运算逻辑,而是文本逻辑
比如你处理温度值时,关心的是:
大于多少
小于多少
相加后是多少
平均值是多少
但字符串处理关心的是:
是否相等
是否为空
长度是多少
是否包含某段内容
能否拼成完整文本
所以字符串思路和数值思路不一样。
这也是为什么很多工程师一开始对字符串会稍微不适应。
不是它很难,而是它不像你平时常见的开关量和模拟量控制。
二十一、字符串在工程里最大的风险:看起来简单,实际容易牵扯长度、格式、空值问题
例如你拿到一个扫码结果,表面上只是“一个字符串”。
但实际工程里你可能要考虑:
它是不是空字符串
长度够不够
是否有前后空格
是否包含回车换行
是否和目标型号完全一致
设备发送过来的格式有没有固定前缀
所以字符串虽然看起来只是“文字”,但用在工程里,细节往往不少。
二十二、数组、结构体、字符串这三者,真实工程里常常是一起出现的
这点特别重要。
例如你做一个产品工位管理,可能会同时有:
每个工位是一个结构体
里面包括:
Occupied
ProductCode
OKFlag
DoneFlag
多个工位组成一个数组
Station[1]
Station[2]
Station[3]
其中 ProductCode 又是字符串
这样你就会形成一个很典型的工程数据组织方式:
一组对象,每个对象内部有多个字段,其中某些字段还是文本。
你一旦接受了这种思路,SCL 程序的层次感会一下提升很多。
这也是为什么这一篇非常关键。
因为它开始把你从“单个变量控制”带向“数据结构控制”。
二十三、为什么很多人学到这里,才开始真正觉得 SCL 和梯形图拉开差距了
因为前面 IF、CASE、FOR 这些,虽然已经是文本编程,但逻辑上你还能比较容易用梯形图思维去类比。
可到了数组、结构体、字符串这里,你会越来越明显地发现:
SCL 不只是另一种写法,它开始让你可以更自然地处理“复杂数据组织”。
而这正是很多复杂工程逻辑的核心。
例如:
配方系统
报警系统
多工位管理
产品追踪
通信解析
条码处理
历史数据记录
这些内容如果只靠传统散点变量去堆,会非常辛苦。
而 SCL 在这方面明显更顺手。
二十四、初学者在这一部分最容易犯的几个错误
错误一:明明是一组同类数据,却还是散着命名
例如:
Temp1
Temp2
Temp3
Temp4
而不是考虑数组。
错误二:明明是一个对象的多属性,却硬拆成大量独立变量
例如:
Motor1_RunCmd
Motor1_RunFB
Motor1_Fault
Motor1_Ready
后面再来 10 台电机,程序就越来越难看。
错误三:把不同意义的数据硬塞成一个数组
这样虽然“凑成了一组”,但程序逻辑并不自然。
错误四:对字符串缺乏格式意识
例如只知道读到文本了,但没考虑长度、空值、格式匹配。
错误五:只会“定义”,不会“组织”
也就是说,虽然知道有数组和结构体这些词,但程序里还没有真正形成数据分层意识。
二十五、从工程角度看,什么时候优先考虑数组,什么时候优先考虑结构体
这个判断非常实用。
优先考虑数组的时候
当你面对的是:
一组同类对象
每个对象处理规则类似
需要按编号遍历
需要统一批量处理
例如:
16 路输入
8 路温度
20 路报警
12 个工位的占用状态
优先考虑结构体的时候
当你面对的是:
一个对象有多种属性
属性类型可能不同
希望把它们归成一个整体
后面可能要模块化、复用
例如:
一个电机
一个气缸
一个工位对象
一条报警记录
一套配方记录
两者配合的时候
当你面对的是:
很多个对象
每个对象又有多项属性
例如:
10 个工位,每个工位有状态、编号、完成标志
4 台电机,每台有命令、反馈、报警、速度
这时候通常就是“结构体数组”的思路。
二十六、给初学者一个很实用的数据组织判断法
以后你拿到一个需求,可以先问自己三个问题:
第一,这是“一组同类元素”,还是“一个对象的多个属性”
如果是一组同类元素,优先想数组。
如果是一个对象的多个属性,优先想结构体。
第二,这里面有没有文本信息
如果有产品号、条码、名称、描述,就要考虑字符串。
第三,这些数据后面是要单点处理,还是批量处理
如果要批量处理,数组价值会非常高。
如果要模块化维护,结构体价值会非常高。
只要这三个问题想清楚,很多数据组织方式就不会乱。
二十七、这一篇最后,给你一个非常实在的工程理解
你可以这样想:
以前你写 PLC 程序,像是在桌子上摆很多零散的小零件。
每个变量都是一个零件,哪里需要就拿哪里。
而数组、结构体、字符串的出现,相当于你开始学会:
把同类零件装进抽屉
给一个设备建立完整档案夹
把文字标签也纳入管理
也就是说,程序不再只是“有没有这个变量”,而开始变成:
这些数据应该怎么归类、怎么组织、怎么让后面处理更顺。
这就是为什么这一篇很重要。
因为从这里开始,你的 SCL 编程会越来越有“工程结构感”。
小结
这一篇你最应该记住这些核心点:
数组适合处理一组同类型、按编号排列的数据,特别适合与循环配合做批量处理。
结构体适合组织一个对象的多项属性,它强调的是“一个对象的完整数据集合”。
字符串用于表示和处理文本数据,在扫码、报警描述、配方名称、通信文本中很常见。
数组和很多个相似变量的本质区别在于,数组是真正被程序作为“一组数据”来处理的。
结构体和数组不是互相替代,而是经常配合使用,尤其适合做一组对象的管理。
字符串处理和数值处理思路不同,它更关注文本内容、格式和比较。
当项目开始涉及多工位、多参数、多对象、条码、配方、记录等复杂信息时,这些数据组织方式会变得非常重要。
SCL 的一个核心优势,就是它能比传统散点式写法更自然地处理复杂数据结构。
下载资料前请先绑定手机号码