| 作者 | 主题 |
|---|---|
|
Setrarin 侠士 经验值:1749 发帖数:139 精华帖:4 |
楼主
主题:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能
周末测试ModbusTCP通信时,发现MB_Client块竟然可以使用同一个实例多次无条件调用,很是惊奇。疑惑了两天,至今也没有完全想通细节,就尝试写了一个类似效果的程序,功能可以类似实现。 现发布一个编程挑战,实现图片中功能: 1.编写FB使用同一个实例在同一个周期多次无条件调用。 2.输入引脚IN触发延时,延时完成后在触发延时的那个块OUT引脚输出。 3.同时只有一个延时在工作。 4.正在执行任务的调用块BUSY引脚置True。 要求: 1.使用图片中FB块的引脚,不增加新的引脚。 2.只使用FB块内部变量。 希望各位大佬赏脸参与,编程完成跟帖上传程序,共同探讨功能实现。我将10天后上传图片中程序。
但行好事,莫问前程
|
|
Letham 至圣 经验值:14191 发帖数:2021 精华帖:43 |
1楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能这种思路本来就有问题! 1:一个MODBUS TCP 连接 只用一个背景实例 ,至于多次调了,那是受到了,西门子给做的DEMO的影响! 2:推荐做法是在西门子标准MB_CLIENT基础上再封装一层,一个MODBUS TCP连接只调一次,多个命令,轮询执行,而不是一个命令,单独调用一次。 就像第三方网关一样,配置个命令表,PLC程序内部扫描有多少MB命令需要执行,上一个执行完毕,或者超时,再执行下一个命令; 程序内部 根据命令表动态改变 MB_MODE MB_DATA_ADDR MB_DATA_LEN 三个参数类容
人生就像一场旅行!
|
|
Setrarin 侠士 经验值:1749 发帖数:139 精华帖:4 |
2楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能不能认同! 您推荐的用法是可以用,而官方给的示例不仅可以用,而且更方便,打破了以前的很多认知,说明西门子官方制作这个指令块的时候就考虑了这样的用法。 本贴是基于之前帖子讨论,希望能够通过自行编程实现功能,以讨论实现的方法,如果Letham版主感兴趣,可以一试~
但行好事,莫问前程
|
|
yming 至圣 经验值:138360 发帖数:23136 精华帖:880 |
3楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能我也没那么用过。 看了一下,逻辑上确实可行。西门子提供的功能块,能够确保同一扫描周期中,同一背景数据块下,同一FB多次调用的正确输出。 除了通讯这类程序,没遇到啥程序需要这样做?也可能复杂多变的工艺有吧。
学而时习之,不亦说乎?温故而知新,不亦乐乎?
|
|
Letham 至圣 经验值:14191 发帖数:2021 精华帖:43 |
4楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能最基本原理都是一样的,上一个命令发送完成,或者超时错误等,发送下一个命令。 这个,是我做的MB_CLIENT程序,按照市场上第三方网关的通用配置设计,一个连接,我只调用一次,有多少命令需要发送,自己配置在DB块里,包括和服务器的连接参数配置。 读过来的数据 ,要存放到什么区域(程序里我写死了,必须是数据块),或者 写命令的 数据来自与哪里,全部配置在命令表里。 下图是我们常用的一个网关配置界面。
人生就像一场旅行!
|
|
yming 至圣 经验值:138360 发帖数:23136 精华帖:880 |
5楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能楼主通过研究西门子MB_CLIENT,提出问题的真正意义是: 针对异步任务,在写功能块时,应该怎样做,才能确保不出错。 西门子功能块的这种写法,确实值得借鉴。 (每循环调用一次OK;调用数次也行。) 楼主给出的工况示例,不明显。要找个合适的示例。
学而时习之,不亦说乎?温故而知新,不亦乐乎?
|
|
kenshinguo 侠圣 经验值:2636 发帖数:719 精华帖:3 |
7楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能看下MB_Client的背景数据块,SAVED_MB_DATA_ADDR,SAVED_DATA_LEN,SAVED_MB_MODE,大致就能理解这个功能如何实现的,诚如之前大家分析的,它是通过绑定管脚来识别当前调用的实例。 这个方法是可行的,更适用于固定场景的简单通讯应用。 宝冬侠举了个例子,把这比喻成开房,但是我的理解稍微有点不同。酒店房间预约给了3拨客人,但其实同一时间只有一波客人能拿到房卡(管脚信息),房卡信息同步输入保存到系统,也就是存到了static区域saved相关的几个变量,其实这样是不会乱掉的,管脚和系统信息匹配了才能自由出入。只有这波客人走后,房卡才会在req上升沿通过管脚来更新。 |
|
周杰伦 至圣 经验值:13957 发帖数:2014 精华帖:16 |
9楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能我也习惯一个FB,然后通过外部引脚实现轮询。 当然可以一个实例,方法多次调用,但这个在高级语言比较常见,PLC上用起来比较怪。
工控毁我青春!
|
|
yming 至圣 经验值:138360 发帖数:23136 精华帖:880 |
10楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能没看出有啥弊端哦。 只能说西门子编写功能块的严谨。 按版主常规这么用可以,直接一次列出多次调用也可以。给编程者最大的自由度。
学而时习之,不亦说乎?温故而知新,不亦乐乎?
|
|
kenshinguo 侠圣 经验值:2636 发帖数:719 精华帖:3 |
11楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能逻辑是很简单,西门子功能块也很健壮,但是有些上层应用会比较复杂,譬如掉站处理,譬如写优先处理(循环读,事件触发写),譬如故障处理等等,这样的话就还得是靠包装了。 |
|
Zane 版主 经验值:85161 发帖数:21047 精华帖:399 |
13楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能楼主的第二个程序,虽未见具体程序,但从贴出的录波图上还是可以看出一些问题的 所有的延时设置都是5s,但输出的间隔却是不等的,后三个输出间隔分别为3,4,5s。 另外,楼主的MB-TCP的程序也没有贴出,就是这么一说
Zane
注册自动化系统工程师
Always save before download
|
|
Setrarin 侠士 经验值:1749 发帖数:139 精华帖:4 |
14楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能Zane大师观察仔细呀,确实是,原因是因为程序截图和Trace不是同时截的。MB_Client程序在另外一个帖子里,使用的就是官方的示例方法。
但行好事,莫问前程
|
|
Setrarin 侠士 经验值:1749 发帖数:139 精华帖:4 |
16楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能我想到的几种思路:
但行好事,莫问前程
|
|
yming 至圣 经验值:138360 发帖数:23136 精华帖:880 |
22楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能好多回帖,其实没搞明白楼主想说的是啥? 他想说明的是: 一个功能块FB,使用同一个背景数据块DB(很多情况下,过程处理通道是独占的。处理这个过程,只能用这个背景数据块DB。) 常规写法就是完成这个过程,进行下一个过程。(在一个扫描周期,只调用一次FB。完成后,赋予新的过程参数。) 若所需处理过程数量很少,(2-3个),在一个扫描周期内调用2-3次,当前被调用的FB如何正确输出!
学而时习之,不亦说乎?温故而知新,不亦乐乎?
|
|
yming 至圣 经验值:138360 发帖数:23136 精华帖:880 |
23楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能另外,举个例子看看: 驱动可以是电机、也可以是液压、气缸。 组装可以是零件,也可以装箱等等。 通常,都是完成一个过程Done。再赋予新的过程参数。 若,过程很少。在一个扫描周期中,连续三次调用(分别三套参数),过程FB的写法。
学而时习之,不亦说乎?温故而知新,不亦乐乎?
|
|
Zaxife 至圣 经验值:12614 发帖数:2450 精华帖:31 |
24楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能
这就是一个很简单的状态字编程思想而已啊,还远远没达到某标准万泉河的那种想搞PLC OS的高度。 逻辑无非就是当检En测到上升沿,那么VW0=1(当前实例),然后Done=False,这时候其它的实例因为是手拖手所以En永远是False永远不会修改VW0,所以依然还是执行VW=1的当前实例在干活。当前活干完了,VW=0且Done=True。然后下一个实例就会得到En=1,他就成为了当前实例,又是VW=1、Done=false,他后面的实例又是没得到En不会修改VW0.....整个大循环如此不停循环循环循环。 讲真,这逻辑是很简单的啊,你们为啥会想得这么复杂呢?这都还没牵扯到RTOS需要的程序SP指针,没牵扯到编译器的当前行号等这些RTOS层面的东西.... 这种做法的优点就是简单直观清晰明了; 缺点是逻辑固定死了不灵活,不能实现像通讯需要写优先。 |
|
Setrarin 侠士 经验值:1749 发帖数:139 精华帖:4 |
25楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能问题是,当参数是一致的两次调用,完成位如何正确的输出到对应的调用块引脚上?你如果觉得简单,可以试着把这个程序写出来,我目前还没有看到一个人完成。
但行好事,莫问前程
|
|
yming 至圣 经验值:138360 发帖数:23136 精华帖:880 |
26楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能这个场景,我倒是想到一个可能地特例。 驱动G系列(G130/150)也支持 MODBUS TCP。 当修改参数后,是保存在RAM中的。若要永久保持,需要执行P0971=1;直到自动复位0. 过程是写参数P0971=1;立即连续读P0971。(COPY RAM TO ROM过程大约十几秒。)直到P0971=0,才可以关机。 这倒是可以专门写个FC。
学而时习之,不亦说乎?温故而知新,不亦乐乎?
|
|
Setrarin 侠士 经验值:1749 发帖数:139 精华帖:4 |
30楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能
但行好事,莫问前程
|
|
Virgo_Zhao 侠客 经验值:939 发帖数:14 精华帖:0 |
34楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能你这个是每调用一次,计数加1来确定调用位置的吧,这样会有两个问题:
|
|
xinchen 侠圣 经验值:2018 发帖数:230 精华帖:1 |
37楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能16L的思路,可以设计几个测试用例进行证明: 比如执行后瞬间修改了输入参数,看能不能正确输出; 比如执行后几个周期通过使能或者 jump 等使别的FB随机不被调用,打乱统计次数; 等等; 目前虽然没测试过,但我觉得通过上面的几个测试用例,可以验证下modbus-tcp库是不是类似16L的思路实现的; 我个人是觉得不是,这个功能实现的关键点应该还是在于“真~异步”; 平常写功能时,所谓异步都是把一个计算功能分摊到多个周期,比如执行一次轮询需要对100项进行处理,为了减少扫描周期,每次执行10项,分摊到10个周期; 但指令本身在每个周期都是执行完的; 但通信不是,modbus-tcp 库从执行到输出,是真的在异步; 命令开始后进行参数校验,通信前的准备,然后开启后台线程执行通信,在通信中收发加解析花了些时间,然后切回CPU线程继续执行指令到输出状态; 虽然整个过程经过了几秒钟,但其实只执行了一次,是一条指令执行一次花了几秒,而不是每个周期执行一点点; 所以它其实不需要在输出瞬间对比当前输入和内部参数,或是计数,或是参数堆栈; 真要记录,它记录的是开始异步前后的线程上下文,这是PLC系统本身的切换线程的功能; 类比下,比如某个UI界面,点击按钮后查询数据库,需要花费很长时间,为了UI不假死,查询是在后台执行的,前台还是能正常操作刷新数据; 有些UI设计的效果可以是在未执行结束前,还是能点击按钮,提示忙碌中,和这个 FB 的 busy 类似;调用多次也是一样; 以上是我的推论,但我觉得应该接近实际了; 至于PLC,不知道有没有异步指令,如果有,倒是可以用来测试验证推论; |
|
Setrarin 侠士 经验值:1749 发帖数:139 精华帖:4 |
38楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能异步我是认可的,但是异步的结果如何正确的返回,还能输出到调用的那个块这个是我唯一不能理解的地方。 如果每个块引脚不一致,通过比较块引脚方式是可以的。神奇的是,测试发现MB_Client块允许有两次参数相同的调用,输出还不会混乱。 主楼题目中延时功能可以理解成是异步指令,我设计的这个题目也是为了探讨实现的各种可能性,但是目前还没有人把程序贴出,不要求程序十全十美,只要求能够实现题目功能,大侠可以一试
但行好事,莫问前程
|
|
xinchen 侠圣 经验值:2018 发帖数:230 精华帖:1 |
39楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能确认了有异步指令,那就简单了,直接使用异步指令就完事了,之后有空了我也会研究学习; 不用纠结异步怎样正确输出,它也是一条指令,内部按照代码一句句执行,只是执行在另一个线程,多花费N个周期,执行到通信时收发加解析,完成后执行下面的指令输出结果; 本质上,它和别的函数调用一样,调用前后的入栈出栈,这个看看c/汇编的函数调用相关知识了解下(不清楚plc底层调用约定是啥,stdcall,fastcall,cdecl,还是别的); 异步执行,参考比如 C# async 相关执行顺序; 注意事项应该就是 考量执行过程中的其他调用的输出和 内部执行完成后的输出 能不能被覆盖,就像 只在发起通信时复位done,busy为true时 任意时候调用都不会赋 done 为 false,直到发起通信的那次完成,置位done; |
|
kkss 侠客 经验值:953 发帖数:44 精华帖:0 |
42楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能帖子看完了,还翻到MB_Client那个帖子里了,别被EN都有骗到了,TSEND触发是REQ给的,没有REQ时候TSEND不执行 ,TRCV接收到数据后靠SAVED变量判断接收到的数据应该写在哪里 推荐下赵欣老师的通信课,看完应该会更好理解通信的问题 |
|
Hujs 游民 经验值:69 发帖数:2 精华帖:0 |
43楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能这个看实际需要,我之前一个项目1500配了一个485模块,下面带了几个设备,开始我是用的多重背景实例的,发现循环处理一圈下来需要2秒刷新完毕,后来优化了一下,只读设备的状态,只有需要给设备下发命令时才进行写操作,在块处理完毕的时候在本周期立即执行下一个任务(重新执行跳转),发现还是慢。后来单独弄了个1200plc挂个485负责通讯循环周期5ms,立马几百毫秒刷新完毕了,效果杠杠的。如果有要求可以多配几个485模块,完全可以满足要求。另外西门子很多通讯块的调用,多数都是异步调用的,tcp和串口之类的都是 |
|
Zane 版主 经验值:85161 发帖数:21047 精华帖:399 |
45楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能三个灯,三个背景实例,灯之间完全没有耦合关系,随便怎么玩。 楼主的做法,却是用一个背景实例,把三个灯强行地耦合起来了,耦合就耦合了吧,在完成三次调用之前,完全无法知道知道三个灯之间的逻辑时序。不是说做不了,一堆的无用功啊。 当小兵的管好自己就可以了,小兵与小兵之间应该是班长去协调,编程也是一样,要分层次。 呵呵,某些所谓的大法,多好的机会来验证自己呀,屁都没放一个。
Zane
注册自动化系统工程师
Always save before download
|
|
坏笨笨 侠士 经验值:1689 发帖数:402 精华帖:4 |
47楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能虽然我觉得异步程序不是像楼主那样的调用法,,刚开始没理解楼主思路,后来想了下,写了一个,和楼主不同的是,电平触发。楼主也不需要藏着掖着,这个程序没必要加个密 FUNCTION_BLOCK "PulseGen" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 VAR_INPUT bIn : Bool; tDelay : Time; END_VAR VAR_OUTPUT bDone : Bool; bBusy : Bool; END_VAR VAR Ton {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME; RTrigger {InstructionName := 'R_TRIG'; LibVersion := '1.0'} : R_TRIG; sout : Bool; sDelay : Time; STAT : UInt; END_VAR VAR CONSTANT IDLE : UInt; BUSY : UInt := 1; DONE : UInt := 2; END_VAR BEGIN
CASE #STAT OF #IDLE: IF #bIn THEN #sDelay := #tDelay; #STAT := #BUSY; #Ton(IN := false, PT := #sDelay ); END_IF; #bDone := false; #sout := false; #bBusy := false; ; #BUSY: #bBusy := true; #Ton(IN := true, PT := #sDelay, Q => #sout); IF #sout THEN #bBusy := false; #bDone := #tDelay =#sDelay; IF #bDone THEN #STAT := #IDLE; END_IF; END_IF; ;
END_CASE;
//#bOut := #sout; END_FUNCTION_BLOCK |
|
坏笨笨 侠士 经验值:1689 发帖数:402 精华帖:4 |
48楼
主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能同时,这个程序最大的问题是需要判断参数,这在真正的异步中是不可以这样做得。 当然,还是强调下,楼主的这种调用异步是有问题的,异步需要配合外部状态机,分层次构筑程序,而不是葫芦串调用。 |