ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于Codesys的PLC跑马灯程序开发:从仿真到真机调试全流程

基于Codesys的PLC跑马灯程序开发:从仿真到真机调试全流程 跑马灯这个题目在PLC圈子里基本就是“Hello World”一样的存在。我以前在培训新人的时候每次都会拿这个例子开头不是因为简单而是它刚好能把PLC开发里最核心的那几个环节全部串起来工程怎么建、任务周期怎么设、定时器怎么用、数组和循环怎么写、变量怎么监控最后再到可视化仿真里看效果。这一套走下来你对整套开发工具的底子也就有了。这次我用的是汇川AM系列PLC来做。AM系列在汇川产品线里属于中型PLC基于Codesys内核编程软件用InoProShop。很多刚接触的朋友可能从H5U或者Easy系列入门但AM系列的逻辑和生态更接近国际主流尤其是支持EtherCAT总线、支持多任务仿真调试能力也强很多。用这个平台做跑马灯虽然看着“杀鸡用牛刀”但把流程跑通之后后面做运动控制、做总线通讯都是复用同一套思路。整篇文章我打算按一个完整的项目流程来走从方案选型开始到工程配置、程序编写、仿真调试再到真机切换最后把常见问题梳理一遍。你可以当教程看也可以直接照着操作过程中的变量名、周期参数我都会给出具体值方便你抄作业。1. 跑马灯方案设计与技术选型1.1 为什么用AM系列而不是小型机先把结论放在前面跑马灯这个需求本身随便一台几十块钱的小型PLC都能做用AM系列确实有些“浪费”。但如果你现在手里刚好有一台AM系列或者你想为以后做总线控制、运动控制打基础那用AM系列来练这个项目就非常合适。AM系列和H5U、Easy系列最大的区别在于软件生态。H5U和Easy用的更多是厂家的专用软件体系上手快但功能边界也明显AM系列走的是Codesys路线这意味着你以后接触倍福、博途这类平台时很多概念是直接相通的比如POU、任务配置、库管理器、可视化这套东西的通用性非常强。另一个很现实的原因是仿真能力AM系列在InoProShop里可以完整跑一个软PLC出来不需要接真实硬件就能验证逻辑对于新手学编程、老手测算法都特别有用。如果你用的是AM401、AM402甚至AM600跑这个项目都没有任何问题。我个人的建议是如果你只是学习选AM402-CPU1608TP/TN就够了自带16点输入、8点晶体管输出还带以太网口价格相对适中练习IO、通讯、总线都能兼顾。后续就算你想挂EtherCAT伺服这个型号也能撑起来。1.2 跑马灯程序的三种主流实现路线很多第一次做跑马灯的朋友会犯一个思维误区上来就写一大堆输出线圈一个灯一个定时器8个灯写8段逻辑。这种写法不是说不能跑而是改起来非常痛苦。比如你想从8个灯改成16个灯那就要再复制8段逻辑而且稍微一个定时器时间写错整个流水节奏就乱掉了。真正好的写法是三个方向你可以根据自己习惯选第一种是移位寄存器思路。核心是把8个输出看成一个布尔数组每个扫描周期检查定时器是否到时间到了就把整个数组左移一位然后把第一位或最后一位置1。这个思路最贴合“跑马灯”这个名称逻辑也最容易理解。缺点是在Codesys里对数组做整体移位需要配合FOR循环或者指针对新手来说稍微有点绕。第二种是计数器加数组索引的思路也是我个人最推荐的方案。用一个字节变量做索引每到一个周期索引加1索引从0到7循环然后每次只把数组里对应索引的那个元素置True其余全部置False。这个方案的代码量最少逻辑也最清晰后面想改成双边流水、变速流水都特别方便。第三种是用整数循环移位指令比如SHL、ROL这类。直接在字节或字上做整体移位效率最高但可读性稍微差一些而且如果你要控制单个灯的逻辑状态还得再拆位判断反而不方便。这三种方案我会在后面的代码部分重点讲第二种因为它在调试时最直观而且方便你理解数组、循环、变量索引这几个基本功。1.3 需求拆解与IO规划动手写程序之前先明确一下这个项目的输入输出。标准版跑马灯我按一个启停按钮、一个模式选择开关、8路灯输出来规划启动按钮接PLC的DI点或者仿真时用可视化按钮代替。信号为True时跑马灯开始跑False时全部停止并复位。模式选择开关接另一个DI点False是单方向流水True是双向往返流水。这个开关可有可无但加上它你就能体会用同一个程序块通过参数切换不同模式的控制思想。8路输出对应8个指示灯。仿真时用可视化界面的8个圆形控件绑定真机调试时接到AM402本体自带的8个晶体管输出点。如果你用的是AM402-CPU1608TP/TN本体DO点物理地址一般从Q0.0到Q0.7正好对应8个灯。仿真时不需要关心物理地址直接用内部变量就行这也是仿真调试最舒服的地方——变量随便建不会触发现实世界的任何设备。2. 工程创建与运行环境配置2.1 新建工程与选型打开InoProShop软件之后第一步是新建工程。如果你第一次用这个软件它会提示你选择PLC类型和编程语言。我这边选的型号是AM402-CPU1608TP/TN编程语言我先选了结构化文本ST后面会把另外两种语言的写法也给你做个对照。新建完成后你会看到工程树里面有几个关键节点程序组织单元POU、任务配置、可视化管理器、库管理器。这套结构和Codesys几乎一模一样你用AM系列练会了以后切到任何Codesys系平台都能秒上手。这里有个细节要注意工程名和PLC类型确定之后后期不太好直接在软件里改所以一开始就要选对。如果你手里的实际设备是AM401程序里用到的功能不会超过AM402的能力范围代码可以直接通用工程选型不同影响不大。2.2 总线配置该不该做很多教程一上来就让你配置EtherCAT主站、添加远程IO从站。跑马灯这个项目真没必要原因有两点一是我们只用PLC本体自带的IO点不走总线通讯二是仿真模式下本身就没有真实从站你就算配了EtherCAT从站仿真器也扫描不到反而会报错。所以我的建议是在这个项目里先跳过总线配置直接把程序写好、仿真跑通。等你后期真正接了EtherCAT伺服或者扩展IO模块再回来在Device节点下添加主站、扫描从站那个时候你也会更清楚总线配置的来龙去脉。如果你确实想顺带练一下总线配置可以在真机连接状态下操作右键Device节点添加EtherCAT主站然后用网线连接PLC和从站模块点击扫描软件会自动识别挂在总线上的设备。这个过程在仿真时做不了只能真机操作。2.3 任务周期与程序组织AM系列的程序执行逻辑是“任务驱动”的也就是说你写的程序必须挂到一个任务底下PLC才会按周期循环执行。默认情况下工程里会有一个Task周期任务里面挂载了主程序PLC_PRG。点开任务配置节点你会看到任务类型、优先级、周期Interval这些参数。跑马灯这类逻辑控制程序我习惯把任务周期设在5ms到20ms之间。这里我用10ms原因是跑马灯的亮灯切换间隔是500ms多任务周期下用定时器完全可以精准控制10ms的周期对PLC算力消耗也低。如果你把任务周期设成1msCPU占用会明显提高对跑马灯这种慢速逻辑没有任何必要。这里还想强调一个点把逻辑程序挂到任务里很多人会忽略这一步结果写了半天程序下载到PLC里什么反应都没有。记住POU如果不挂到任务下它就像一本放在书架上的书永远不会自己翻开去执行。3. 跑马灯程序的核心实现3.1 变量规划我建议把跑马灯程序写在主程序PLC_PRG里所有变量先规划好不要边写边补。以下是完整变量清单PROGRAM PLC_PRG VAR xStart : BOOL : FALSE; // 启动按钮仿真/真机绑定 xMode : BOOL : FALSE; // 模式切换FALSE单方向TRUE双向 fbTimer : TON; // 500ms 定时器 byIndex : BYTE : 0; // 当前点亮的灯索引0~7 iDir : INT : 1; // 移动方向1右移-1左移 xRunLamp : ARRAY[0..7] OF BOOL;// 8路输出状态 END_VAR几个变量的设计理由我多说两句。byIndex用BYTE而不是INT是因为8个灯用0到7的索引BYTE完全够用而且在Codesys里BYTE做比较运算时更省内存类型也更安全。iDir用INT来记录方向是为了实现双向流水功能时方便取反。xRunLamp作为输出数组后期绑定到可视化控件时每个元素对应一个灯非常直观。有些人可能习惯把输出直接写到Q地址比如Q0.0到Q0.7。我不太推荐在程序内部直接驱动物理输出点因为这样仿真和真机切换时会很麻烦仿真时没有物理IO输出地址往往直接失效。用内部变量做一层中转仿真绑定可视化控件真机再做一个IO映射这种分层设计在真正的工业项目里是标准做法。3.2 ST语言实现推荐方案下面是核心程序用的是计数器加数组索引的方案。// 1. 定时器逻辑启动按钮为True时定时器开始计时 fbTimer(IN : xStart, PT : T#500MS); // 2. 定时时间到进行一次切换动作 IF fbTimer.Q THEN // 先复位定时器否则Q信号会一直保持True fbTimer(IN : FALSE); // 3. 更新索引 IF xMode THEN // 双向模式到达两端边界时反向 IF byIndex 7 THEN iDir : -1; ELSIF byIndex 0 THEN iDir : 1; END_IF byIndex : byIndex iDir; ELSE // 单方向模式循环0→1→2...→7→0 IF byIndex 7 THEN byIndex : 0; ELSE byIndex : byIndex 1; END_IF END_IF // 4. 根据索引刷新8路输出 FOR i : 0 TO 7 DO IF i byIndex THEN xRunLamp[i] : TRUE; ELSE xRunLamp[i] : FALSE; END_IF END_FOR END_IF // 5. 停车处理按钮松开全部熄灭并复位 IF NOT xStart THEN byIndex : 0; iDir : 1; FOR i : 0 TO 7 DO xRunLamp[i] : FALSE; END_FOR END_IF这段程序里有三个细节你需要注意。第一定时器复位的方式。我在定时器的Q信号为True之后马上把fbTimer的IN输入置为FALSE。这个做法在Codesys里是可行的因为定时器功能块在输出Q为True之后如果IN为FALSE累计时间会被清零下一次IN为True再重新计时。如果你不这么做Q会一直保持True索引会疯狂递增而不是等待下一个500ms。第二FOR循环里用了一个局部变量i。i需要在变量声明区里定义为INT类型否则编译会报错。这个小细节看着不起眼但经常有人漏掉。第三停车时的复位逻辑。很多人写停车只是简单把所有灯熄灭但我特意把byIndex和iDir都复位了。这样做的原因是保证下次启动时从第0个灯开始往右跑而不是从某个中间状态继续跑。工业设备里这叫“上电初始状态”虽然跑马灯无所谓但这种习惯一定要养好。3.3 梯形图与FBD的等价实现我知道不少电工出身的朋友更习惯看梯形图。跑马灯这个项目用ST写确实舒服但如果你公司的电气主管要求统一用梯形图你也得会。梯形图的核心思路是一样先用TON实现500ms脉冲然后用比较指令判断当前索引值等于0就往左移动等于7就重新赋0中间状态就把索引加1。在InoProShop里梯形图对数组的遍历比较麻烦你没办法直接写FOR循环只能把每个输出线圈单独写出来用等于比较指令逐位判断。8个灯要写8个分支逻辑很清晰但代码量会翻好几倍。FBD则介于两者之间你可以在FBD里用TON功能块、SEL选择器、EQ比较器等组合起来。对老手来说FBD画出来比梯形图更紧凑但新手理解起来不如ST直观。我的建议是这个项目至少用一种文本语言跑通再用一种梯形图语言对照看看。两种都理解了你才算真正理解“PLC程序是一回事只是表达语言不同”这件事。3.4 扩展玩法变速、渐变和双灯追逐跑马灯学完之后不要急着就丢到一边。我每次带人学这个案例都会让他们继续扩展几个小功能这个过程比跑马灯本身重要得多。第一是变速效果。把定时器的PT参数从固定值改成一个变量比如nSpeed是一个INT类型取值范围500到2000单位ms。你可以在可视化界面放一个数值输入控件绑定这个变量仿真运行时一边调节速度一边观察效果。改动的代码只有一行把T#500MS改成T#(nSpeed)MS但你会立刻理解“参数化驱动逻辑”的意义。第二是双灯追逐。我刚才的代码是一次点亮一个灯你可以改成一次点亮连续两个灯方法也很简单在FOR循环里加判断条件凡是索引等于byIndex或者byIndex1的都置True超过7就回绕。这样看起来就像两盏灯在赛跑。第三是渐变效果。如果你以后要接的是调光模块比如支持PWM输出的灯光控制器可以让输出值不是一个布尔量而是一个0到1000的整数每次切换不是置0/置1而是逐渐递减。这个功能已经能练到高级的数据变化和限幅处理了。千万别小看这些扩展它们就是你后面做复杂项目时用到的状态机、脉冲控制、速度控制的基础雏形。4. 仿真调试全流程实录4.1 编译与登录仿真器程序写完之后先点击编译按钮。编译通过后在InoProShop的顶部菜单里找“在线”或者“登录”按钮。点击旁边的小箭头可以看到下拉选项里面有“仿真”和“USB/以太网”之类的选项。这里关键一步是选择仿真模式软件会启动一个虚拟的PLC内核作为运行环境。如果你点登录之后没反应先看看左下角的输出窗口有没有报错。常见的是“没有连接设备”这说明你没选仿真模式软件还在尝试找你真实的PLC。还有一种是“仿真器启动失败”这个多半是虚拟网卡或者权限问题用管理员身份重新打开软件一般就能解决。登录成功之后软件会提示你要不要将当前程序下载到设备。这里直接点下载就行。下载完成后再点运行F5这时候你的程序就开始在虚拟PLC里跑了。4.2 可视化界面的搭建与绑定仿真跑起来之后如果不做可视化你只能通过监控表看变量值不够直观。AM系列的可视化编辑器可以让我们直接拖控件出来构建一个虚拟操作面板这也是我非常推荐大家练习的功能。在工程树里找到可视化节点右键添加一个新的可视化对象然后点进去。左侧工具箱里你可以找到基本图形矩形、椭圆、指示灯、按钮、数值显示等控件。我们拖8个圆形出来排列成一行再拖一个启动按钮和一个停止按钮。关键步骤是绑定变量。选中一个圆形控件在属性窗格中找到“颜色”或“动态文本”相关的属性点击绑定按钮选择变量xRunLamp[0]。以此类推8个圆分别绑定xRunLamp[0]到xRunLamp[7]。启动按钮绑xStart。绑定完成后把当前可视化界面设置为启动画面这样仿真登录后它会自动弹出。到这里你的仿真面板就做好了。点击运行后再点一下可视化里的启动按钮你会看到8个灯按顺序亮过去500ms跳一次。如果你再切一下模式开关变量还能看到双向来回流动的效果。整个交互非常直观而且不需要任何物理设备。4.3 监控表与强制变量的使用光看可视化灯亮还不够你还需要学会用监控表看底层变量尤其是看定时器状态和索引值。在工程树里的监控表节点添加一个监控表然后手动添加变量fbTimer.Q、byIndex、xMode、iDir调试时把它们排在一起。代码跑起来之后监控表会实时刷新这些变量的值。你会发现byIndex从0到7循环变化fbTimer.Q每隔500ms跳一次True整个过程一目了然。如果你想在仿真时把某个变量强制为特定值右键变量选择“强制”或者“写入”可以直接给变量赋值。比如你想快速测试从第5个灯启动的场景就直接把byIndex写入5下一次切换会从5开始往右走。这个操作用来做边界测试非常方便真机上就要小心了因为强制信号一旦忘记取消可能造成设备误动作。仿真阶段你尽管随便试。4.4 从仿真切换到真机仿真全部通过之后如果你手头有真机AM402可以准备把程序下载到实际设备里。切换流程很简单停止程序运行点在线菜单里的“注销”退出仿真然后用网线连接电脑和PLC的以太网口设置电脑本地IP地址和PLC同一网段AM402默认IP一般可以在手册里查到常见的是192.168.1.x段重新点登录选择以太网方式下载程序并运行。这时候还有一步映射要做把程序里的xRunLamp数组映射到物理输出点。最简单的方式有两种一种是在程序后面加IO映射代码Q0.0 : xRunLamp[0]; Q0.1 : xRunLamp[1]; Q0.2 : xRunLamp[2]; Q0.3 : xRunLamp[3]; Q0.4 : xRunLamp[4]; Q0.5 : xRunLamp[5]; Q0.6 : xRunLamp[6]; Q0.7 : xRunLamp[7];另一种是在IO映射表里做关联。我个人的习惯是用代码做映射因为更直观后期查问题一眼就能看到对应关系。把8个输出接上指示灯启动按钮接DI点按下按钮就能看到真机上一排灯跑起来那感觉和仿真完全不一样。5. 常见问题与排查技巧实录5.1 编译报错速查第一次写这个程序编译阶段最常见的几个错我整理成一个表报错现象根本原因解决方式变量i未声明FOR循环条件里用了未经声明的变量在VAR区增加i : INT;fbTimer未声明TON功能块实例未创建增加fbTimer : TON;类型不匹配byIndex7报错BYTE和INT混用统一用BYTE或者都转INTPT参数期望时间为标准时间格式定时器时间写法不对用T#500MS格式而不是直接写500POU未分配给任务程序没有被任何任务调用在任务配置里添加调用这些都是很典型的低级错误但新手几乎都会遇到。我的建议是编译报错不要慌双击错误信息软件会定位到具体行很多错误看上下文就能猜出来。5.2 运行时逻辑不对的排查思路编译通过了不代表逻辑对。我见过很多人卡在几个奇怪现象上。现象一跑马灯没反应。先查xStart是否为True再查定时器Q是否在规律跳动。如果Q一直在False说明定时器IN没接收到启动信号如果Q一直为True说明定时器没被复位。这两点检查完90%的问题都解决了。现象二灯亮一下就全灭。这个多半是定时器复位时机不对或者是把复位写到了IF外面导致每个扫描周期都重新清零。检查一下复位逻辑是不是在Q判定里面。现象三双向模式到边界之后不会反向。这个要重点看iDir变量的变化。如果按到边界后iDir没有在等号的后面被赋值说明你的IF判断写得有问题。可以用监控表盯着iDir看看它在byIndex等于7的时候有没有变成-1。现象四仿真时一切正常真机却偶尔丢一拍。这种情况在跑马灯项目里不太可能发生但在真实项目里很常见一般是任务周期太短或者定时器精度不够。你可以把任务周期放宽试试或者把定时器的PT改成1000ms看丢拍现象是否消失。5.3 一些来自实操的避坑经验最后分享几个做跑马灯项目时容易忽略的经验。第一InoProShop仿真器对电脑性能有一些要求尤其是老电脑。仿真时如果软件卡顿明显把任务周期从10ms调到50ms流畅度会好很多对于跑马灯这种慢逻辑没有任何影响。第二如果你在仿真器里绑定了可视化变量但是画面没有动静先确认两件事一是不是把可视化设置成了启动画面二是不是PLC程序已经处于运行状态。我经常看到有人程序下载完忘记点运行画面上当然什么都不会变。第三这个项目做真机调试时如果PLC前面板有RUN/STOP拨码记得拨到RUN位置再下载程序。有些人折腾半天发现程序不进结果只是拨码停在STOP挡。第四变量命名最好统一风格。比如布尔变量用x开头数值变量用n开头数组变量用a开头这个习惯在AM系列里特别重要。因为Codesys的智能提示对命名规范比较敏感命名好了写代码速度快很多。第五真机调试千万别忘了先确认外部接线有没有短路。AM402的输出点虽然有过流保护但接错线烧端子的事情我也不是没见过。上电之前用万用表量一遍比出问题再去查划算多了。6. 写在最后的经验之谈跑马灯虽然只是一个入门案例但我个人觉得它特别适合作为你进入Codesys生态的第一站。你通过这个项目掌握了Array、FOR循环、TON定时器、任务调度、可视化仿真这五个点其实就是以后所有复杂PLC程序的地基。后面你做轴控、做视觉联动、做数据采集本质上都是这些基础模块的排列组合。我自己的习惯是每接触一个新的PLC品牌或新平台都先拿跑马灯练一次手顺便摸一遍软件的操作流程和坑。这也是为什么我一再建议你不要只把程序跑通就算完而是把ST、FBD、梯形图三种语言都各写一遍把变速、双向、双灯这些扩展功能都做一遍。等你哪天不用看资料就能把这段程序写得行云流水恭喜你PLC的入门关算是真正过了。
返回列表