一个简单的结构式文本 (PLC) 程序,可在 RevPi Core 3 上运行以控制交通灯。 将 RevPi Core 3 和 DIO 安装在 DIN 导轨上并成功运行后。
结构式文本 (ST)
创建 PLC 控制程序的主要标准语言分为 3 种 - 结构式文本语言 Structured Text Language (ST)、梯形逻辑和功能块图 (FBD)。顾名思义,后两者是更为图形化的界面,然而它们的灵活性不如结构式文本语言,加上 RevPi 随附的免费版 logi.CAD 3 仅支持结构式文本语言,因此我选择使用它。
尽管结构式文本是一种行业标准 IEC 61131-3 管理范围内的标准化语言,且语言核心保持不变,但是每个 PLC 供应商都做出特定的修改和增加。我在网上找到了一篇实用的入门教程,在它的指导下我开始着手搭建。对于熟悉计算机语言的人来说,结构式文本由 PASCAL 发展而来,它让我想起许多年前,我在 ZX80 上用来进行乒乓球游戏编程的 BASIC 语言。
logi.CAD 3
除了使用新的语言以外,我还使用了以前从未用过的软件。我发现,通过浏览 logi.CAD 3 术语表了解一些使用的术语,然后在必要时再次查阅,对我的工作有很大的帮助。我特别记录了以下几点:
- 对象 - logi.CAD 3 项目资源管理器中的对象位于文件夹内,是该文件夹的子文件夹。对象相当于文件系统中的文件。
- 项目 - 项目是 logi.CAD 3 项目资源管理器中的一种特殊类型的文件夹。默认情况下,项目是项目资源管理器中的根目录。
完整的内容总称为应用程序,它不仅有包含已编写代码的 STL 文件,还包括配置文件、全局变量和专用于 PLC 的库。
这时,我发现了一个有效的办法,那就是通过单击“Project Menu(项目菜单)”下的“Clean(清理)”选项来“清理”项目,然后等待 Logi.CAD 3 运行完毕,之后应用程序创建并加载成功。
PROGRAM RevolutionPiCounterProgram VAR value : BOOL; END_VAR VAR_EXTERNAL Red_1 : BOOL; Amber_2 : BOOL; Green_3 : BOOL; END_VAR IF value THEN Red_1 := False; value := False; ELSE Red_1 := True; value := True; END_IF; END_PROGRAM
本例中,LED 持续闪烁。这是因为 PLC 应用程序会自动重复。“End_Program”实际上表示返回到起始行然后重新开始。
教程中解释如下“当 PLC 运行到 END_PROGRAM 时,PLC 扫描周期将重新开始,程序将重新运行”:
交通信号灯
现在,我需要研究出如何使 LED 以标准交通灯亮顺序闪烁 - 红、红和黄、绿、黄,然后再回到红。
更改信号灯的闪烁速度时,只需在配置文件中编辑一个数值即可,但是这会改变整个扫描循环的速度,因此这种方法较为粗糙,只会使应用程序整体减慢。此外,我还想要能单独改变不同灯的闪烁速度。事实证明,这比最初预期的难度更大。
TON 函数(计时器延迟)提供了所需的延迟,但我无法通过代码获得所需的效果。我能够使 LED 亮起一定时间后熄灭,但是却无法再次亮起,或者能够使 LED 闪烁并熄灭,但是却无法指定熄灭时间。我反复碰壁,一度觉得这项任务可能超出了我的处理能力。就在这时,我在网络上寻求帮助,在 Codesys 论坛上找到了一篇实用的博客文章,其中提到了 CASE 语句。Codesys 的功能与 logi.CAD 类似,而我发现它们所用的结构化文本语法存在一些差异,但是我成功地根据我的需要对示例进行了调整。
最终代码如下:
PROGRAM RevolutionPiProgram
VAR wait : TON; count : INT; END_VAR VAR_EXTERNAL Red_1 : BOOL; Amber_2 : BOOL; Green_3 : BOOL; END_VAR CASE count OF 0: //init count := count + 1;
1: // Red Red_1 := True; Amber_2 := False; Green_3 := False; wait(IN:=TRUE, PT:=T#5s); IF wait.Q THEN wait(IN:=FALSE); count := count + 1; END_IF;
2: // Red and Amber Red_1 := True; Amber_2 := True; Green_3 := False; wait(IN:=TRUE, PT:=T#5s); IF wait.Q THEN wait(IN:=FALSE); count := count + 1; END_IF;
3: // Green
Red_1 := False; Amber_2 := False; Green_3 := True; wait(IN:=TRUE, PT:=T#5s); IF wait.Q THEN wait(IN:=FALSE); count := count + 1; END_IF; 4: // Amber Red_1 := False; Amber_2 := True; Green_3 := False; wait(IN:=TRUE, PT:=T#5s); IF wait.Q THEN wait(IN:=FALSE); count := count + 1; END_IF; ELSE count := 0;
END_CASE;
END_PROGRAM
CASE 用于在出现特定整数值时执行语句。本例中创建了一个名为“count”的整数变量,此变量在每次 PLC 扫描时增加 1,直到最终条件运行以及 ELSE 将它重新设置为零。而 TON 将每个语句运行 5 秒。更改该数值时,只需编辑以下行中的 5s 值即可:
- wait(IN:=TRUE, PT:=T#5s);
复制代码
如有需要,可以为每次灯亮指定不同的时间
|