首页 > 其他分享 >在PLC的扫描特性下,FOR循环里面套IF或者定时器会发生什么?

在PLC的扫描特性下,FOR循环里面套IF或者定时器会发生什么?

时间:2024-05-13 10:43:05浏览次数:23  
标签:ModbusRTUDB 定时器 END 扫描 SlaveNumber 循环 PLC BOOL ARRAY

1. 为什么会提出这个题目

  • 在PLC指令的执行过程中,FOR循环会在每个扫描周期执行完一个循环,然后程序才会接着往下扫描
  • 在PLC指令的执行过程中,IF判断会在每次扫描中判断一次条件,满足则进入执行体,不满足则跳出IF
  • 把IF放在FOR循环里面,会导致循环体执行时间过长,或者其他问题吗?(答案是不会)毕竟每个循环周期for循环的变量都要从起始值到最大值循环一遍。
  • 在FOR循环里面嵌入定时器,会导致PLC扫描时间超看门狗时间吗?(答案是不会
  • 如果把FOR循环换成REPEAT..UNTIL,程序会容易超过看门狗时间吗?(答案是会,repeat会一直循环执行体中内容,直到满足break条件;换句话说,FOR和REPEAT的工作原理不一样)

2. 从应用讲起

  • 做一个跑马灯,让PLC DQ输出从小到大依次点亮,再达到最大时再依次减少;设计思路用FOR循环去做DQ点灯的遍历,同时依靠IF去判断当前实际应该点亮的灯是哪个,IF里面再放入定时器来做点亮时间控制。
    • 虽然每一遍FOR循环都会把循环数完全跑一遍,但是仅仅只有当满足IF条件的时候才能真正进得去循环体;相当于每个扫描周期内IF被判断了FOR的循环次数那么多次。
    • 如果FOR循环的次数都结束了还没有进入IF执行体,PLC程序会卡死在这儿吗?答案是不会。FOR循环结束后程序会继续往下扫描,不会在意是否进入了IF的判断体
    • 在IF或者直接在FOR里面嵌套了长时间的定时器,会拉长FOR循环的循环时间吗?答案是不会。因为每经过一次扫描周期,PLC去检查一遍定时器时间到了没,不管定时器时间到了还是没到,程序都依旧按照设定扫描顺序依次扫描。
//循环开始
//variant "QB0_QB1" means %QW0,as a word.
IF "QB0_QB1" = 0 AND NOT #subflag_bool THEN
    #addflag_bool := TRUE;
END_IF;

IF #addflag_bool THEN
    #BOOL_ARRAY[0] := true;
    #TIME_add_ARRAY[0](IN := #BOOL_ARRAY[0],
                       PT := T#2S);
    
    FOR #FOR_I := 0 TO 8 DO
        IF #TIME_add_ARRAY[#FOR_I].Q THEN
            #BOOL_ARRAY[#FOR_I + 1] := TRUE;
            #TIME_add_ARRAY[#FOR_I + 1](IN := #BOOL_ARRAY[#FOR_I + 1],
                                        PT := T#2S);
        END_IF;
    END_FOR;
    
END_IF;

//正循环结束
IF #TIME_add_ARRAY[9].Q THEN
    
    #TIME_sub_ARRAY[9](IN := #BOOL_ARRAY[9],
                       PT := t#2s);
    IF #TIME_sub_ARRAY[9].Q THEN
        #addflag_bool := FALSE;
        #subflag_bool := true;
    END_IF;
    
END_IF;

//负循环开始
IF #subflag_bool THEN
    FOR #FOR_J := 9 TO 1 BY -1 DO
        IF #TIME_sub_ARRAY[#FOR_J].Q THEN
            #BOOL_ARRAY[#FOR_J] := false;
            #TIME_sub_ARRAY[#FOR_J - 1](IN := #BOOL_ARRAY[#FOR_J - 1],
                                        PT := T#2S);
        END_IF;
    END_FOR;
END_IF;

//全周期结束
IF #TIME_sub_ARRAY[0].Q OR "Switch" THEN
    #subflag_bool := false;
    #addflag_bool := FALSE;
    FOR #FOR_K := 0 TO 9 DO
        RESET_TIMER(#TIME_add_ARRAY[#FOR_K]);
        RESET_TIMER(#TIME_sub_ARRAY[#FOR_K]);
        #BOOL_ARRAY[#FOR_K] := FALSE;
    END_FOR;
END_IF;

//赋值
"Q0.0" := #BOOL_ARRAY[0];
"Q0.1" := #BOOL_ARRAY[1];
"Q0.2" := #BOOL_ARRAY[2];
"Q0.3" := #BOOL_ARRAY[3];
"Q0.4" := #BOOL_ARRAY[4];
"Q0.5" := #BOOL_ARRAY[5];
"Q0.6" := #BOOL_ARRAY[6];
"Q0.7" := #BOOL_ARRAY[7];
"Q1.0" := #BOOL_ARRAY[8];
"Q1.1" := #BOOL_ARRAY[9];

3. 这种嵌套模式的应用设想

  • 在做MODBUS轮询的时候,有些时候我们需要调用很多次功能块,那么能不能利用上述方法,然调用块只被写一次,从而提高效率呢?
    • 下例中,主要注意点都写在注释中了
    • 下例中,ModbusMaster块没有以ARRAY..OF iDB的方式去做多个iDB是因为轮询的方式其实在同一时刻只会调用一次MobusMaster,不必浪费内存去重复做存储区。共用存储区也是可以的。(当然做成iDB数组动态调用也是可以的)
    • 下例中,代码没有被调试过,只是用来做一种ModBus轮询思路的探讨
//1.通讯数量的问题
//来自于西门子官方文档:
//Modbus 寻址支持最多 247 个从站(从站编号 1 到 247)。每个 Modbus 网段最多可以有 32 个设备,具体取决于 RS485 接口的负载和驱动能力。当达到 32 个设备的限制时,必须使用中继器来扩展到下一个网段。需要七个中继器才能将 247 个从站连接到同一个主站的 RS485 接口。
//Siemens 中继器仅支持 PROFIBUS;其功能为监视 PROFIBUS 令牌传递。Siemens 中继器不支持其它协议。因此,需要第三方 Modbus 中继器。
//Modbus 超时默认较长;使用多个中继器不会产生延时问题。Modbus 主站不关心从站是否响应慢或者多个中继器是否延迟了响应。
//2.思路:若要想要只调用一次Modbus_master指令。我想到的方法是用smart200的子程序编程思路去实现(摒弃背景DB的方法来实现只把逻辑写一遍)。
//程序如下:
//********************************************************START****************************************************//

//用for执行程序,做轮询!切记同一时间只能访问一个从站,其他从站需要排队!
FOR #SlaveNumber := 0 TO 40 DO
    //主执行逻辑
    //req逻辑依据实际情况在外部写逻辑
    IF "ModbusRTUDB".modbusMasterArray[#SlaveNumber].req AND NOT "ModbusRTUDB".modbusMasterArray[#SlaveNumber].done THEN
        //调用一次初始化块,MB_DB接口用array间接寻址
        #Modbus_Comm_Load_Instance(REQ := "FirstScan",
                                   "PORT" := 261,
                                   BAUD := 9600,
                                   PARITY := 0,
                                   MB_DB := #MB_MASTER[#SlaveNumber].MB_DB);
        
        //调用一次Master块,背景DB用ARRAY序列化,接口参数用UDT封装后用globleDB序列化
        #commMB_MASTER(REQ := "ModbusRTUDB".modbusMasterArray[#SlaveNumber].req,
                      MB_ADDR := "ModbusRTUDB".modbusMasterArray[#SlaveNumber].mb_addr,
                      MODE := "ModbusRTUDB".modbusMasterArray[#SlaveNumber].mode,
                      DATA_ADDR := "ModbusRTUDB".modbusMasterArray[#SlaveNumber].data_addr,
                      DATA_LEN := "ModbusRTUDB".modbusMasterArray[#SlaveNumber].data_len,
                      DONE => "ModbusRTUDB".modbusMasterArray[#SlaveNumber].done,
                      BUSY => "ModbusRTUDB".modbusMasterArray[#SlaveNumber].busy,
                      ERROR => "ModbusRTUDB".modbusMasterArray[#SlaveNumber].error,
                      STATUS => "ModbusRTUDB".modbusMasterArray[#SlaveNumber].statrus,
                      DATA_PTR := "ModbusRTUDB".modbusMasterArray[#SlaveNumber].data_ptr);
    END_IF;
END_FOR;

//********************************************************END****************************************************//
//3.总结:毕竟PLC是结构化编程而不是面向对象编程,所以要想做到继承父类就能直接调用所有父类方法的思想不容易,
//其实西门子官方也不建议向上面这么玩,因为数据安全和数据稳定问题。为每个对象均分配一个专有的背景DB才是西门子的思想所在。
//这种玩法参考了没有背景DB思想的SMART200程序,SMART200里面子程序是common的,所有重复调用必须满足异步调用,这很重要,否则数据要出错。
//4.缺点:这个方法属于轮询方法,同一时间只会有一个从站设备在通信!数据传输可能会出现排队现象,必须处理好req逻辑!
//串行传输,传输效率极其低下。

标签:ModbusRTUDB,定时器,END,扫描,SlaveNumber,循环,PLC,BOOL,ARRAY
From: https://www.cnblogs.com/xiacuncun/p/18188761

相关文章

  • PLC的开放式用户协议
    1.OUC开放式用户协议,包括ISO,ISO-on-TCP,TCP/IP,UDP四种。西门子PLC中有多种不同的方式建立连接。2.在硬件组态中建立TCP通信打开硬件组图,网络视图添加新连接填入本地ID,关于本地ID:针对1513实测过,ID的取值范围从16#01到16#999,但是16#01-16#99大概率被系统占用了,可用范围从1......
  • LwRB - 一款适用嵌入式系统的轻量级 RingBuffer+MultiTimer - 超精简的纯软件定时器驱
    1、MicroMagic发布世界上最快的64-bitRISC-V核近日,一家位于美国加州森尼维尔的小型电子设计公司MicroMagic宣称设计、生产出了全世界最快的64位RISC-V内核,比苹果的M1芯片和ArmCortex-A9表现还要出色。消息源: http://www.micromagic.com/news/RISCv-Fastest_PR.pdf这......
  • 为什么要用setTimout来做定时器?
    Q:再js中定时任务我们为什么要用setTimeout模拟,而不直接用setIntervalA:以下为详细答案精确控制时间间隔:使用setTimeout可以更精确地控制每次任务执行的时间间隔。因为在任务执行完成之后,我们可以根据需要再次设置下一个任务执行的时间,从而避免了可能因任务执行时间过长而......
  • Nexpose v6.6.250 for Linux & Windows - 漏洞扫描
    Nexposev6.6.250forLinux&Windows-漏洞扫描Rapid7VulnerabilityManagement,ReleaseMay02,2024请访问原文链接:Nexposev6.6.250forLinux&Windows-漏洞扫描,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org您的本地漏洞扫描程序搜集通过实时......
  • sonar(二)扫描配置
    1.配置导出pdf的报告下载jar包:链接:https://pan.baidu.com/s/1zZUPYoCx9-ssrvyxprS6RA提取码:9999放入目录: 在sonar页面上配置插件pdf的用户名和密码配置sonar的配置文件: 2.idea增加sonarline插件3.sonar界面新增项目,记住token修改项目的build节点,增加sonar-maven-pl......
  • 232自由口转Profinet网关接基恩士扫码枪与PLC通讯案例
     232自由口转Profinet网关(XD-PNR100/300)是一款作用于将232自由口转换为Profinet协议,实现不同网络之间的无缝通信和数据交换。232自由口转Profinet网关具有极高的灵活性和可靠性,为工业控制系统提供了强大的支持。通过将自由口信号转换为Profinet协议,可以轻松实现不同设备之间的......
  • snap7读写PLC变量
    1.读DB'''#copysnap7.dll&snap7.libfilestopythonrootpathfirstpipinstallsnap7'''importsnap7importstructfromsnap7importutil#创建通讯客户端实例plc=snap7.client.Client()#连接至PLCplc.connect('192.1......
  • C#与PLC变量在数据交互上的一些探索
    1.基于C#的数据交互A.S7,usingS7.Net,后文读写数据时二次封装过S7协议,这里暂且不表,只列举S7协议最原始的应用。new一个PLC对象//idenfybasiclinkparamsprivatestringplc_ip;privateCpuTypeplc_type;privateshortplc_rack,plc......
  • 扫描版PDF电子书目录制作方法
    前置条件书籍:扫描版《软件调试》(请支持正版......
  • 安全扫描_ZAP
    ZAP提供了两种扫描方式,AutomatedScan(自动扫描)和 ManualExplore(手动扫描),如下图:   AutomatedScan(自动扫描)点击“AutomatedScan”进入自动扫描配置界面,只需要配置待攻击的网址,然后点击“Attack”执行傻瓜式的渗透测试。自动扫描无需配置代理。自动扫描结束后可点击“A......