ARTICLE DETAIL

资讯详情

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

汇川INPROSHOP位逻辑指令详解:常开常闭与沿触发

汇川INPROSHOP位逻辑指令详解:常开常闭与沿触发 干工控这一行尤其是刚摸到汇川PLC的人十个里有八个第一次打开INPROSHOP不是被运动控制难住的而是被最不起眼的位逻辑搞得晕头转向。常开、常闭谁都认识但一到现场接线、写程序、联调才发现“认识符号”和“搞懂逻辑”完全是两码事。更不用说上升沿和下降沿很多干了两三年的人也只停留在“用过”的层面真问他沿指令到底是怎么实现的、为什么有时候信号明明到了却没触发他答不上来。这篇文章就专门把INPROSHOP里位逻辑的四大指令掰开揉碎讲清楚。适合刚入门汇川PLC编程的小白也适合那些被现场怪问题折磨过、想回头补基础的项目工程师。内容不只是讲指令符号而是把物理接线、扫描周期、故障安全、在线调试这些串成一条完整的链路。看完你不仅能写对程序还能明白为什么这样写才可靠。1. 定位位逻辑为什么这四个指令是所有PLC程序的地基1.1 从一次“按下按钮没反应”的排查说起先讲个真事。有个朋友调试一台小型设备用的汇川H5UINPROSHOP编程。现场反馈说“急停按下去了设备还在动”他第一反应是急停回路接错了。结果拿万用表一通量急停按钮的常闭触点输入信号在按下瞬间确实从ON变成了OFFPLC输入指示灯也灭了。但程序里就是没停电机还在跟着跑。查了大半天最后发现他在梯形图里写的急停逻辑是|/| 急停输入 ( 电机运行 )也就是用了常闭指令去读这个信号。输入信号在正常状态下是ON程序里常闭指令取反后反而不通真按了急停输入变OFF常闭指令反而导通。方向整个反了。这件事听起来像个段子但在实际项目里一点不罕见。原因就是很多教材只告诉你“常开是NO、常闭是NC”却没说清楚程序里的常开/常闭指令和你接的那个物理按钮的常开/常闭触点是两个维度的东西。两者叠加之后的最终效果才是你真正输入到逻辑里的电平状态。1.2 INPROSHOP在汇川平台里的位置在讲指令之前得先把软件平台的关系理一理。汇川现在主要有几条PLC产品线早期的H1U/H2U小型机用的AutoShopAM系列、AC800系列、H5U、EASY系列用的INPROSHOP。INPROSHOP是基于Codesys V3内核二次开发的所以它继承了IEC 61131-3的编程体系支持LD梯形图、FBD功能块图、ST结构化文本、SFC顺序功能图、CFC连续功能图。这个背景很重要因为很多人在AutoShop和INPROSHOP之间横跳的时候会发现同一个逻辑两个软件的“长相”不太一样甚至指令名字都有差异。比如AutoShop里的上升沿可能叫PLS/PLF而INPROSHOP里则是标准的R_TRIG/F_TRIG或者触点属性里的“上升沿”选项。理解了它基于Codesys你很多指令的查找和使用习惯就能很快对齐。位逻辑在INPROSHOP里对应的就是逻辑运算这一大类核心就是常开触点、常闭触点、上升沿、下降沿这四个。听起来简单但几乎所有复杂控制——电机启停、报警连锁、模式切换、单次触发计数——都是从这四个指令的组合开始的。1.3 四大指令的一句话语义与符号总览先把最基础的定义用表格列清楚后面每一节再逐个深挖。指令梯形图符号ST等价写法导通条件典型用途常开触点--| |--变量直接用变量为TRUE时导通读取启动按钮、传感器信号、运行状态常闭触点--|/|--NOT 变量变量为FALSE时导通读取停止按钮、故障信号、互锁条件上升沿--|P|--R_TRIG实例变量从FALSE变为TRUE的瞬间导通一个周期按钮单次触发、计数、模式切换下降沿--|N|--F_TRIG实例变量从TRUE变为FALSE的瞬间导通一个周期停止信号捕捉、物料到位后离开检测、故障恢复计数这个表不用背但建议收藏。实际写程序时你至少要知道自己在找“读取一个高电平有效信号”还是“读取一个低电平有效信号”这样才能选对指令。2. 常开与常闭接线、扫描和“故障安全”的完整链路2.1 程序里的常开/常闭和物理触点到底什么关系很多人学PLC第一步就卡在“常开常闭”上因为这里有两套概念叠加在了一起。第一套是物理层按钮、继电器、传感器输出它们的触点有常开NO和常闭NC之分。常开触点平时断开动作时闭合常闭触点平时闭合动作时断开。第二套是程序层梯形图里的常开指令和常闭指令是针对PLC输入映像区里的布尔变量来做判断的。常开指令变量为1则导通常闭指令变量为0则导通。关键来了——物理触点通过输入电路转换成PLC内部的变量时并没有一个“自动取反”的过程。你接的是物理常开触点那么不动的时候输入变量就是0接物理常闭触点那么不动的时候输入变量就是1。至于程序里用常开还是常闭指令去读这个变量完全取决于你想让这个信号在什么条件下“有效”。用大白话讲物理触点决定的是“外部电路的通断状态”程序指令决定的是“内部逻辑对状态的解释”。两套东西自由组合会产生四种情况。实际工程里最常用的组合反而是一堆人搞不懂的“物理常闭 程序常开”。2.2 为什么急停按钮必须用常闭触点接、常开指令读这是工控人绕不开的经典问题急停按钮为什么要接常闭触点为什么程序里反而用常开指令| |去读它先看物理层。急停按钮用常闭触点串联在24V回路上正常状态下回路是通的PLC输入点是ON。一旦拍下急停触点断开输入点变成OFF。如果发生断线、接线松脱、24V电源掉电这些故障输入点同样会变成OFF。这就体现了“故障安全”的核心思想用断电表示异常让任何故障都导向安全侧。如果急停用常开触点那么正常状态下输入是OFF拍下急停输入才变成ON。万一急停那根线断了PLC收不到任何信号它无法区分“没按急停”和“急停线断了”设备就可能带着安全隐患继续运行。而用常闭触点一旦断线PLC看到的是和“拍下急停”一样的OFF状态逻辑自然进入停机保护。程序层为什么用常开指令读因为PLC内部变量在正常状态下是ON1你想表达的是“急停正常、允许运行”这个条件成立所以用常开指令变量为1时导通。按下急停后变量变0常开指令断开运行条件不满足设备停机。这里用表格整理一下这个经典组合的效果外部状态物理常闭触点PLC输入变量程序用常开指令逻辑结果正常运行闭合1导通急停条件满足急停按下断开0断开急停触发线路断线无法闭合0断开急停触发你只需要记住一个工程结论带安全功能的停止回路外部接常闭程序用常开指令读。这样写断线等于急停永远朝向安全方向。2.3 断线检测一个让很多新手意外的细节顺着上面这个思路再延伸一步就涉及断线检测。用常闭触点接急停还有一个好处——系统上电后如果按钮回路断线PLC输入点根本不会亮操作员或调试人员一眼就能看出异常。如果用了常开触点断线后输入点也是灭的但你和“没按按钮”的正常状态完全区分不开只能靠程序里的逻辑去猜。在实际项目里我还习惯给急停回路增加一个“回路监视”的BOOL变量用来判断输入信号是否在“正常电平”。比如急停输入正常情况下必须是ON如果程序刚下载完或者设备上电后这个信号不是ON我会直接在触屏上弹一条“急停回路异常”的报警。这样断线、接线错、IO模块没上电都能第一时间暴露。这种“以正常电平状态作为有效性判据”的思路就是位逻辑在工程中非常典型的应用——通过一个简单的常开触点读取完成远比“通断判断”复杂的安全监控功能。2.4 INPROSHOP中的指令插入与ST写法在INPROSHOP的梯形图编辑环境里插入常开和常闭触点很简单。LD编辑界面下工具栏里直接选“常开触点”或“常闭触点”也可以在空白处右键选择插入。需要注意触点上的变量名必须是BOOL类型。很多人在这里踩坑把INT变量拖进去编译直接报类型错误。ST语言下常开就是直接引用变量名常闭就是前面加NOT。比如一个典型的电机启动自锁逻辑用ST写是IF xStart AND NOT xStop THEN xRun : TRUE; END_IF注意这里有个陷阱ST里xStart AND NOT xStop和梯形图的“启动按钮常开串接停止按钮常闭”是等价的。如果你在ST里直接把停止按钮信号写成xStop那停止按钮的状态就得反过来理解——这恰恰是很多从梯形图转ST的人频繁犯错的地方。我的经验是不管用哪种语言程序注释里明确写出“物理常开/常闭”和“逻辑有效电平”防止自己过两天就忘了当初的意图。3. 上升沿与下降沿扫描周期里的“瞬间”如何被捕捉3.1 沿检测的底层原理上一周期状态对比常开常闭很好理解就是看当前状态。上升到下降沿则完全不同——它们看的是“状态的变化过程”而不是“状态本身”。PLC程序是周期性扫描执行的一个扫描周期里依次完成读输入、执行程序、刷新输出。对PLC来说外部信号是一个一个周期地“采样”进来的。沿指令做的事情就是把这个周期的输入状态和上一个周期的输入状态做一个比较。上升沿的触发条件上一周期是0这一周期是1。 下降沿的触发条件上一周期是1这一周期是0。这里的关键在于PLC必须记住“上一周期”的状态。这就是为什么在IEC 61131-3体系里R_TRIG和F_TRIG不是普通的触点指令而是带内部状态的功能块。它们内部隐藏了一个变量专门用来存储上一次调用的输入状态。所以你在INPROSHOP里插入上升沿指令时系统会要求你给这个功能块分配一个实例名不能像常开触点那样直接扔一个变量上去。这个设计不是汇川特有的Codesys体系都这样。理解了这个内部机制你就能明白后面要讲的很多坑为什么存在。3.2 R_TRIG与F_TRIG在INPROSHOP里的实例化细节在INPROSHOP梯形图里插入上升沿指令最常见的方式是在功能区找到“R_TRIG”功能块拖到编辑区然后它会显示一个类似这样的结构R_TRIG CLK : xButton Q xPulseCLK是输入信号Q是输出。你需要在程序里先声明一个R_TRIG类型的变量比如rTrigButton然后调用它。ST写法更直观rTrigButton(CLK : xButton, Q xPulse); IF xPulse THEN iCount : iCount 1; END_IF注意几点实例必须全局唯一。同一个R_TRIG实例不要在多处调用否则它的内部状态会被交叉修改逻辑会变得不可预测。这个后面专门讲。Q输出不要直接当普通变量去写。Q是一个功能块输出它在这一周期产生一个扫描周期的脉冲然后立刻失效。你要用的通常是这个脉冲去触发一个动作而不是把它当作持续状态保持。PLC首次扫描时沿指令的初始状态。R_TRIG默认的“上一周期状态”是FALSEF_TRIG默认的“上一周期状态”是TRUE。也就是说如果程序下载后第一个扫描周期输入就是高电平R_TRIG会误触发一次。这一点在设备上电、程序热下载时要特别小心后面翻车现场再展开。3.3 沿信号的时效性过短的脉冲为什么会被漏掉很多人以为只要信号跳到1了上升沿就一定能捕捉到。实际上没这么简单。PLC对输入的采样不是连续的而是在每个扫描周期的输入刷新阶段把输入端子上的状态锁存进输入映像区。也就是说一个外部脉冲如果宽度太短短到在两次扫描之间就消失了PLC根本不知道它来过。举个例子假如PLC扫描周期是5ms外部有一个2ms的短脉冲。如果这个脉冲恰好在两次扫描之间出现那么PLC看到的是“上一周期0、这一周期也0”上升沿永远不会触发。这种问题在实际项目里最常见的场景就是高速计数信号、旋转编码器的Z相脉冲、位置传感器的瞬时信号。处理办法一般是要么把信号接到支持中断或高速计数的输入通道要么在外部加硬件滤波和展宽电路要么把扫描周期缩短。靠沿指令去抓过短的脉冲是抓不住的。沿指令能抓到的是“持续时间大于一个扫描周期”的状态变化。另外还有一种情况信号本身不短但它的变化发生在程序执行到某条指令之前却被输入刷新“等”了过去。这也是为什么有些工程师在处理快速信号时会专门把这段逻辑放到一个独立任务里或者调整输入滤波时间。INPROSHOP支持多任务配置如果你对某个输入信号的实时性有要求最好单独确认一下这个IO映射和任务周期。3.4 “沿指令能滤波器抖动”是最大误解新手最容易产生的错误认知按钮有抖动用上升沿指令就能只触发一次。真相是沿指令和抖动没什么关系。按钮按下的时候机械触点会在几毫秒到几十毫秒内反复通断。这个过程在PLC眼里就是一连串的0、1、0、1。如果你在程序里用上升沿去捕捉按钮信号PLC很可能会在抖动期间捕捉到多个上升沿导致一次按键变成了三次计数。沿指令保证的是“一个扫描周期内只导通一次”的特性但它无法区分“这次上升沿是用户真正按下按钮”还是“触点抖动造成的电平跳跃”。要消除抖动得在信号进入逻辑之前做软件滤波——最常见的就是用TON延时或者写一个简单的“连续N个扫描周期状态一致才认为有效”的判断。实际项目里我一般这样做// 按钮滤波持续5ms为高才认为真正按下 tonFilter(IN : xButtonRaw, PT : T#5MS, Q xButtonDebounced); rTrigFilter(CLK : xButtonDebounced, Q xButtonEdge); IF xButtonEdge THEN iPressCount : iPressCount 1; END_IF先滤波再取沿。这个组合才是可靠的单次触发方案。别把沿指令当滤波器用。4. 真实项目中最常见的位逻辑翻车现场与排查链路4.1 翻车现场一常闭信号接进来指令方向写反了这就是开头那个急停案例的完整版。现象急停按下设备不停。排查过程可以给各位一个标准参考。第一步看PLC输入点。用INPROSHOP在线监视功能直接观察急停输入对应的BOOL变量。急停按下时变量如果从1变0说明外部接线没问题输入信号到了PLC。第二步看程序里这个变量是怎么被使用的。把程序切到在线状态用“交叉引用”功能找出所有用到这个变量的位置。检查每个位置是常开还是常闭指令。第三步检查逻辑是否反了。如果外部接的是常闭触点程序里又用常闭指令读取那就是双重取反逻辑方向和按钮的实际动作正好相反。修正方式要么改指令方向要么换物理触点但推荐改程序因为安全回路外部接线有硬件标准不能乱改。这个排查链路看起来很简单但现场调试时往往因为旁边有人催、脑子一乱就会跳过前两步直接改程序。我自己的习惯是凡是涉及安全信号的位逻辑在线监视确认电平变化永远排在改程序前面。4.2 翻车现场二程序下载后沿指令立刻误触发一次有个设备用的汇川EASY系列PLC每次用INPROSHOP重新下载程序后气缸都会莫名其妙动作一次。查了很久发现是某个R_TRIG的问题。原因就是前面提到的初始状态R_TRIG的内部状态寄存器默认是FALSE。程序下载完成后如果输入信号恰好在第一个扫描周期就是TRUE比如某个传感器上电后常亮那么第一拍就会被判断为“上升沿”触发动作。解决办法有几个一是给沿功能块做初始化确保上电/下载后内部状态等于当前输入状态。但R_TRIG的功能块实例不方便直接强制内部变量所以更常用的方法是在程序开头做初始化把一个初始恒FALSE的信号先喂给R_TRIG跑一个周期再切入真实信号。比如// 上电后第一个周期先让xEnable为FALSE把沿功能块的状态“校准”到OFF xIn : xSystemReady AND xRawSignal; rTrigCalib(CLK : xIn, Q xPulse);这么做有点绕我的经验是在设备启动初始化段里显式地把需要捕捉沿的信号先用FALSE赋值跑一次沿指令或者干脆用脉冲信号只在特定使能条件下才接入逻辑。这个方法不复杂但能避免很多热下载后的偶发误动作。4.3 翻车现场三同一个沿实例在多处调用引发的灵异现象INPROSHOP里同一个功能块实例允许在多个位置调用但你要清楚功能块的内部状态是所有调用位置共享的。这就会引出一个非常隐蔽的bug。假设你在程序多个地方写了rTrigA(CLK : xSignal, Q xPulse_1); // 位置1 rTrigA(CLK : xSignal, Q xPulse_2); // 位置2PLC扫描是从上到下执行的。执行位置1时rTrigA看到“上一周期0、这一周期1”把内部状态更新为1Q输出1。执行位置2时rTrigA看到“上一周期1、这一周期1”Q输出0。最后xPulse_1得到一次脉冲xPulse_2什么也得不到。也就是说同一个实例被多个地方调用第二个调用点永远拿不到想要的沿脉冲。更危险的是如果两个调用点的输入信号还不一样内部状态会被第一处调用更新第二处调用的结果就完全看扫描顺序了。正确做法是一个沿功能块实例只服务一个逻辑点。如果多处都需要对同一个信号取沿就声明多个实例。这也是我在评审新同事程序时重点盯的条款。4.4 翻车现场四用沿指令做按钮计数一按蹦三下按钮计数是最常见的沿应用但也最容易出问题。表面现象是按一次按钮计数器跳了好几下。第一步基本就能锁死原因抖动。如果外部输入信号没做滤波PLC会在按钮抖动的那几毫秒里识别出多个上升沿。对PLC来说这些上升沿都是“合法的”因为每个上升沿之间可能隔了一个或几个扫描周期。解决方案就在3.4节先滤波再取沿。如果你对响应速度有要求比如按键时间原本就只有几十毫秒就需要调小滤波时间或者用输入模块自带的数字滤波参数。汇川IO模块一般都有输入滤波设置默认值可能偏大比如10ms某些高速场合要手动调整。这里还想补充一种情况计数乱跳也可能不是按钮抖动而是你的计数器变量类型溢出了。用INT计数超过32767就乱跳用UINT超过65535也乱跳。按钮计数这种场合习惯性用DINT甚至LREAL更稳妥。别看这个细节小现场排查半天最后发现是溢出的情况我见过不止一次。5. 一个能直接抄作业的完整示例启停、急停与计数组合逻辑5.1 需求与IO分配综合前面聊的所有知识点我设计一个非常典型的小控制逻辑你直接照着写就能跑通。需求一台小型设备有一个启动按钮、一个停止按钮、一个急停按钮、一个计数传感器。要求按下启动按钮设备运行有运行输出按下停止按钮设备停止拍下急停按钮设备立即停止并且逻辑上不允许再次启动直到急停复位后重新按启动传感器每检测到一个工件计数加1如果传感器信号抖动不能在计数上出现多计IO分配变量名类型对应物理信号外部接线xEStopInBOOL急停按钮常闭触点接24VxStartInBOOL启动按钮常开触点接24VxStopInBOOL停止按钮常闭触点接24VxSensorInBOOL工件检测传感器NPN/PNP根据模块类型xRunOutBOOL运行输出驱动中间继电器xFaultLampBOOL急停报警灯驱动指示灯这里要特别说一下停止按钮的接线。工业现场最常见的停止按钮也是接常闭触点逻辑上用常开指令读。原理和急停一样正常情况下停止信号是ON按下停止信号变OFF一旦断线系统默认停止。5.2 梯形图思路拆解与ST对照实现这套逻辑我用ST写一遍每一段都加上注释方便你对照梯形图理解。PROGRAM Main VAR xEStopIn : BOOL; xStartIn : BOOL; xStopIn : BOOL; xSensorIn : BOOL; xRunOut : BOOL; xFaultLamp : BOOL; xSensorOk : BOOL; xSensorEdge: BOOL; tonSensor : TON; rTrigSensor: R_TRIG; iCount : DINT; xRunReady : BOOL; END_VAR逻辑主体// 1. 急停回路物理常闭程序用常开指令读 // 正常时xEStopIn为TRUE表示急停回路正常 xFaultLamp : NOT xEStopIn; xRunReady : xEStopIn; // 2. 启动/停止/自锁 // 启动按钮用沿触发更安全避免按住按钮期间重复执行 rTrigStart(CLK : xStartIn AND xRunReady, Q xStartEdge); rTrigStop(CLK : NOT xStopIn AND xRunReady, Q xStopEdge); IF xStartEdge THEN xRunOut : TRUE; END_IF IF xStopEdge OR xFaultLamp THEN xRunOut : FALSE; END_IF // 3. 传感器信号滤波 上升沿计数 tonSensor(IN : xSensorIn, PT : T#5MS, Q xSensorOk); rTrigSensor(CLK : xSensorOk, Q xSensorEdge); IF xSensorEdge THEN iCount : iCount 1; END_IF几处设计说明启动停止都用沿触发。因为启动和停止按钮都是瞬动型的用沿触发保证“按下一次只执行一次”不会因为程序扫描快、按钮按得久造成状态反复翻转。停止逻辑用常闭触点解读。外部xStopIn常闭接法正常为TRUE取反后为FALSE所以rTrigStop的CLK在正常时是FALSE不会误触发按下停止按钮xStopIn变FALSE取反后变TRUE产生沿。急停复位后的重启问题。一旦急停触发xFaultLamp为TRUExRunOut被强制为FALSE。此时即使急停复位xRunOut也不会自动变成TRUE必须重新按启动按钮。这就是“故障复位后手动再启动”的安全要求。传感器先滤波再取沿。如果传感器本身输出很干净你可以把TON的PT设小一些甚至去掉滤波直接用R_TRIG。但实际项目里光电传感器对工件反光、毛刺边缘很敏感不滤波很容易多计。5.3 在线调试与强制操作的注意事项写完之后你用INPROSHOP连上PLC在线调试时建议按这个顺序验证先强制急停输入为TRUE确认xFaultLamp为FALSE、xRunReady为TRUE、xRunOut能正常置位。然后把急停输入强制为FALSE确认xRunOut立即变FALSExFaultLamp变TRUE。再把启动按钮的输入强制为TRUE一个扫描周期再恢复FALSE确认xRunOut变TRUE并保持。恢复启动按钮输入为FALSE后xRunOut应当保持TRUE这验证了自锁逻辑。最后强制停止按钮输入为FALSE一瞬再恢复TRUE确认xRunOut能停止。这里特别提醒一个强制操作的风险强制输入的变量时一定要记住复位所有强制值再退出现场。我就见过有人在调试时强制了启动按钮输入为TRUE忘了取消强制结果设备一上电不管有没有人按按钮设备自己就启动了。INPROSHOP里强制功能很直观但也有配套的“全部取消强制”操作调试完务必执行一遍。5.4 从位逻辑到功能封装的下一步当你把这套启停急停计数逻辑跑通之后就可以考虑把它封装成一个功能块了。INPROSHOP支持用户自定义功能块把xStartIn、xStopIn、xEStopIn、xSensorIn作为输入把xRunOut、xFaultLamp、iCount作为输出。封装好之后同类设备直接拿来复用不仅节约编程时间也可以保证不同项目里的安全逻辑行为一致。我就是这样干的把常见的“带安全回路的启停逻辑”做成了一个标准库功能块后面所有出图的项目都调用它。省下来的时间都用来处理真正头疼的问题了。最后再说一点个人体会。位逻辑看起来简单但它决定了整个设备的安全底线和操作体验。越是看起来基础的东西越值得花时间把它彻底想明白。尤其是常闭信号和沿指令的初始状态这两个细节几乎每个项目里都会碰到解决了这些你的程序稳定性和调试效率都会上一个台阶。
返回列表