技术论坛

 【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

返回主题列表
作者 主题
Setrarin
侠士

经验值:1628
发帖数:139
精华帖:4
楼主    2022-07-05 18:04:12
主题:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能 精华帖  精编帖 

周末测试ModbusTCP通信时,发现MB_Client块竟然可以使用同一个实例多次无条件调用,很是惊奇。疑惑了两天,至今也没有完全想通细节,就尝试写了一个类似效果的程序,功能可以类似实现。


现发布一个编程挑战,实现图片中功能:

    1.编写FB使用同一个实例在同一个周期多次无条件调用。

    2.输入引脚IN触发延时,延时完成后在触发延时的那个块OUT引脚输出。

    3.同时只有一个延时在工作。

    4.正在执行任务的调用块BUSY引脚置True。


要求:

    1.使用图片中FB块的引脚,不增加新的引脚。

    2.只使用FB块内部变量。



希望各位大佬赏脸参与,编程完成跟帖上传程序,共同探讨功能实现。我将10天后上传图片中程序。

公众号"worksway工方工园",欢迎关注~
Letham
版主

经验值:13009
发帖数:1866
精华帖:41
1楼    2022-07-07 08:27:33
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

这种思路本来就有问题!

1:一个MODBUS TCP 连接 只用一个背景实例 ,至于多次调了,那是受到了,西门子给做的DEMO的影响!

2:推荐做法是在西门子标准MB_CLIENT基础上再封装一层,一个MODBUS TCP连接只调一次,多个命令,轮询执行,而不是一个命令,单独调用一次。

就像第三方网关一样,配置个命令表,PLC程序内部扫描有多少MB命令需要执行,上一个执行完毕,或者超时,再执行下一个命令;

程序内部 根据命令表动态改变

MB_MODE

MB_DATA_ADDR

MB_DATA_LEN

三个参数类容

人生就像一场旅行!
Setrarin
侠士

经验值:1628
发帖数:139
精华帖:4
2楼    2022-07-07 13:19:36
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

不能认同!

您推荐的用法是可以用,而官方给的示例不仅可以用,而且更方便,打破了以前的很多认知,说明西门子官方制作这个指令块的时候就考虑了这样的用法。

本贴是基于之前帖子讨论,希望能够通过自行编程实现功能,以讨论实现的方法,如果Letham版主感兴趣,可以一试~


公众号"worksway工方工园",欢迎关注~
yming
至圣

经验值:106636
发帖数:20227
精华帖:726
3楼    2022-07-07 18:12:25
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

我也没那么用过。

看了一下,逻辑上确实可行。西门子提供的功能块,能够确保同一扫描周期中,同一背景数据块下,同一FB多次调用的正确输出。


除了通讯这类程序,没遇到啥程序需要这样做?也可能复杂多变的工艺有吧。


学而时习之,不亦说乎?温故而知新,不亦乐乎?
Letham
版主

经验值:13009
发帖数:1866
精华帖:41
4楼    2022-07-08 09:04:08
精华帖  精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

最基本原理都是一样的,上一个命令发送完成,或者超时错误等,发送下一个命令。
但是西门子提供的DEMO,如果 读写多个寄存器,线圈等,那么需要自己 更改代码,一个命令使用同样背景实例调用一次,它只是提供了一种可行方法的最基本原理。



这个,是我做的MB_CLIENT程序,按照市场上第三方网关的通用配置设计,一个连接,我只调用一次,有多少命令需要发送,自己配置在DB块里,包括和服务器的连接参数配置。

读过来的数据 ,要存放到什么区域(程序里我写死了,必须是数据块),或者 写命令的 数据来自与哪里,全部配置在命令表里。

下图是我们常用的一个网关配置界面。



人生就像一场旅行!
yming
至圣

经验值:106636
发帖数:20227
精华帖:726
5楼    2022-07-08 10:04:18
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

楼主通过研究西门子MB_CLIENT,提出问题的真正意义是:

针对异步任务,在写功能块时,应该怎样做,才能确保不出错。

西门子功能块的这种写法,确实值得借鉴。

(每循环调用一次OK;调用数次也行。)


楼主给出的工况示例,不明显。要找个合适的示例。

学而时习之,不亦说乎?温故而知新,不亦乐乎?
kenshinguo
侠圣

经验值:2403
发帖数:722
精华帖:2
7楼    2022-07-08 14:46:45
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

看下MB_Client的背景数据块,SAVED_MB_DATA_ADDR,SAVED_DATA_LEN,SAVED_MB_MODE,大致就能理解这个功能如何实现的,诚如之前大家分析的,它是通过绑定管脚来识别当前调用的实例。

这个方法是可行的,更适用于固定场景的简单通讯应用。

宝冬侠举了个例子,把这比喻成开房,但是我的理解稍微有点不同。酒店房间预约给了3拨客人,但其实同一时间只有一波客人能拿到房卡(管脚信息),房卡信息同步输入保存到系统,也就是存到了static区域saved相关的几个变量,其实这样是不会乱掉的,管脚和系统信息匹配了才能自由出入。只有这波客人走后,房卡才会在req上升沿通过管脚来更新。

周杰伦
至圣

经验值:13150
发帖数:1984
精华帖:16
9楼    2022-07-08 16:35:35
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

我也习惯一个FB,然后通过外部引脚实现轮询。

当然可以一个实例,方法多次调用,但这个在高级语言比较常见,PLC上用起来比较怪。

工控毁我青春!
yming
至圣

经验值:106636
发帖数:20227
精华帖:726
10楼    2022-07-08 16:39:26
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

没看出有啥弊端哦。

只能说西门子编写功能块的严谨。

按版主常规这么用可以,直接一次列出多次调用也可以。给编程者最大的自由度。

学而时习之,不亦说乎?温故而知新,不亦乐乎?
kenshinguo
侠圣

经验值:2403
发帖数:722
精华帖:2
11楼    2022-07-08 16:48:48
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

逻辑是很简单,西门子功能块也很健壮,但是有些上层应用会比较复杂,譬如掉站处理,譬如写优先处理(循环读,事件触发写),譬如故障处理等等,这样的话就还得是靠包装了。

Zane
版主

经验值:65276
发帖数:17857
精华帖:349
13楼    2022-07-09 10:22:02
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

楼主的第二个程序,虽未见具体程序,但从贴出的录波图上还是可以看出一些问题的


所有的延时设置都是5s,但输出的间隔却是不等的,后三个输出间隔分别为3,4,5s。


另外,楼主的MB-TCP的程序也没有贴出,就是这么一说



Zane 注册自动化系统工程师 Always save before download
Setrarin
侠士

经验值:1628
发帖数:139
精华帖:4
14楼    2022-07-09 13:31:14
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

Zane大师观察仔细呀,确实是,原因是因为程序截图和Trace不是同时截的。MB_Client程序在另外一个帖子里,使用的就是官方的示例方法。

为什么MB_Client块可以使用同一个背景数据块多次调用,如何实现的?

公众号"worksway工方工园",欢迎关注~
Setrarin
侠士

经验值:1628
发帖数:139
精华帖:4
16楼    2022-07-11 08:47:31
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能


我想到的几种思路:

  • 参数比较。

    每次调用参数均不同,比较当前任务与输入参数,可以正常输出。

  • 调用次数计数   

    核心问题是如何在块内判断调用属于同一周期。 记忆任务触发时的调用序号,也可以实现功能。

  • 参数堆栈

     核心问题也是如何在块内判断调用属于同一周期。 这种方法可以实现Mod_Client块测试中看到的效果,但是其背景数据块并没有看到相应的存储变量。





公众号"worksway工方工园",欢迎关注~
yming
至圣

经验值:106636
发帖数:20227
精华帖:726
22楼    2022-07-14 10:30:23
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

好多回帖,其实没搞明白楼主想说的是啥?

他想说明的是:

一个功能块FB,使用同一个背景数据块DB(很多情况下,过程处理通道是独占的。处理这个过程,只能用这个背景数据块DB。)

常规写法就是完成这个过程,进行下一个过程。(在一个扫描周期,只调用一次FB。完成后,赋予新的过程参数。)

若所需处理过程数量很少,(2-3个),在一个扫描周期内调用2-3次,当前被调用的FB如何正确输出!


学而时习之,不亦说乎?温故而知新,不亦乐乎?
yming
至圣

经验值:106636
发帖数:20227
精华帖:726
23楼    2022-07-14 11:58:19
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

另外,举个例子看看:




驱动可以是电机、也可以是液压、气缸。

组装可以是零件,也可以装箱等等。

通常,都是完成一个过程Done。再赋予新的过程参数。

若,过程很少。在一个扫描周期中,连续三次调用(分别三套参数),过程FB的写法。






学而时习之,不亦说乎?温故而知新,不亦乐乎?
Zaxife
至圣

经验值:12432
发帖数:2502
精华帖:31
24楼    2022-07-14 12:55:09
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

我好像没理解错啊,这就是类似Smart200的Modbus的MSG指令,上一个的Done触发下一个的En啊。

这就是一个很简单的状态字编程思想而已啊,还远远没达到某标准万泉河的那种想搞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
侠士

经验值:1628
发帖数:139
精华帖:4
25楼    2022-07-14 13:14:07
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

问题是,当参数是一致的两次调用,完成位如何正确的输出到对应的调用块引脚上?你如果觉得简单,可以试着把这个程序写出来,我目前还没有看到一个人完成。

公众号"worksway工方工园",欢迎关注~
yming
至圣

经验值:106636
发帖数:20227
精华帖:726
26楼    2022-07-14 17:01:25
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

这个场景,我倒是想到一个可能地特例。

驱动G系列(G130/150)也支持 MODBUS TCP。

当修改参数后,是保存在RAM中的。若要永久保持,需要执行P0971=1;直到自动复位0.

过程是写参数P0971=1;立即连续读P0971。(COPY RAM TO ROM过程大约十几秒。)直到P0971=0,才可以关机。

这倒是可以专门写个FC。

学而时习之,不亦说乎?温故而知新,不亦乐乎?
Setrarin
侠士

经验值:1628
发帖数:139
精华帖:4
30楼    2022-07-15 09:02:09
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

今天是发布帖子的第10天,没有看到一位完成,很是遗憾。我先上传个加密版本的供大家测试,再等各位10天。

OnlyOneInstance(Encrypted).zip


公众号"worksway工方工园",欢迎关注~
Virgo_Zhao
侠客

经验值:618
发帖数:14
精华帖:0
34楼    2022-07-15 13:21:25
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

你这个是每调用一次,计数加1来确定调用位置的吧,这样会有两个问题:

  1. 程序运行过程中修改调用顺序,会导致程序跑飞

  2. 如果调用了8次,运行到了第6次,这个时候删除3次调用,程序会卡死

xinchen
游侠

经验值:529
发帖数:80
精华帖:0
37楼    2022-07-27 09:56:22
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

16L的思路,可以设计几个测试用例进行证明:

比如执行后瞬间修改了输入参数,看能不能正确输出;

比如执行后几个周期通过使能或者 jump 等使别的FB随机不被调用,打乱统计次数;

等等;


目前虽然没测试过,但我觉得通过上面的几个测试用例,可以验证下modbus-tcp库是不是类似16L的思路实现的;


我个人是觉得不是,这个功能实现的关键点应该还是在于“真~异步”;

平常写功能时,所谓异步都是把一个计算功能分摊到多个周期,比如执行一次轮询需要对100项进行处理,为了减少扫描周期,每次执行10项,分摊到10个周期;

但指令本身在每个周期都是执行完的;


但通信不是,modbus-tcp 库从执行到输出,是真的在异步;

命令开始后进行参数校验,通信前的准备,然后开启后台线程执行通信,在通信中收发加解析花了些时间,然后切回CPU线程继续执行指令到输出状态;

虽然整个过程经过了几秒钟,但其实只执行了一次,是一条指令执行一次花了几秒,而不是每个周期执行一点点;

所以它其实不需要在输出瞬间对比当前输入和内部参数,或是计数,或是参数堆栈;

真要记录,它记录的是开始异步前后的线程上下文,这是PLC系统本身的切换线程的功能;


类比下,比如某个UI界面,点击按钮后查询数据库,需要花费很长时间,为了UI不假死,查询是在后台执行的,前台还是能正常操作刷新数据;

有些UI设计的效果可以是在未执行结束前,还是能点击按钮,提示忙碌中,和这个 FB 的 busy 类似;调用多次也是一样;


以上是我的推论,但我觉得应该接近实际了;

至于PLC,不知道有没有异步指令,如果有,倒是可以用来测试验证推论;






Setrarin
侠士

经验值:1628
发帖数:139
精华帖:4
38楼    2022-07-27 13:51:19
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

异步我是认可的,但是异步的结果如何正确的返回,还能输出到调用的那个块这个是我唯一不能理解的地方。

如果每个块引脚不一致,通过比较块引脚方式是可以的。神奇的是,测试发现MB_Client块允许有两次参数相同的调用,输出还不会混乱。

主楼题目中延时功能可以理解成是异步指令,我设计的这个题目也是为了探讨实现的各种可能性,但是目前还没有人把程序贴出,不要求程序十全十美,只要求能够实现题目功能,大侠可以一试


公众号"worksway工方工园",欢迎关注~
xinchen
游侠

经验值:529
发帖数:80
精华帖:0
39楼    2022-07-28 09:01:19
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

确认了有异步指令,那就简单了,直接使用异步指令就完事了,之后有空了我也会研究学习;


不用纠结异步怎样正确输出,它也是一条指令,内部按照代码一句句执行,只是执行在另一个线程,多花费N个周期,执行到通信时收发加解析,完成后执行下面的指令输出结果;


本质上,它和别的函数调用一样,调用前后的入栈出栈,这个看看c/汇编的函数调用相关知识了解下(不清楚plc底层调用约定是啥,stdcall,fastcall,cdecl,还是别的);


异步执行,参考比如 C# async 相关执行顺序;


注意事项应该就是 考量执行过程中的其他调用的输出和 内部执行完成后的输出 能不能被覆盖,就像 只在发起通信时复位done,busy为true时 任意时候调用都不会赋  done 为 false,直到发起通信的那次完成,置位done;

kkss
游侠

经验值:322
发帖数:5
精华帖:0
42楼    2022-07-30 12:24:59
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

帖子看完了,还翻到MB_Client那个帖子里了,别被EN都有骗到了,TSEND触发是REQ给的,没有REQ时候TSEND不执行 ,TRCV接收到数据后靠SAVED变量判断接收到的数据应该写在哪里


推荐下赵欣老师的通信课,看完应该会更好理解通信的问题

Hujs
新手

经验值:49
发帖数:1
精华帖:0
43楼    2022-08-01 18:19:39
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

这个看实际需要,我之前一个项目1500配了一个485模块,下面带了几个设备,开始我是用的多重背景实例的,发现循环处理一圈下来需要2秒刷新完毕,后来优化了一下,只读设备的状态,只有需要给设备下发命令时才进行写操作,在块处理完毕的时候在本周期立即执行下一个任务(重新执行跳转),发现还是慢。后来单独弄了个1200plc挂个485负责通讯循环周期5ms,立马几百毫秒刷新完毕了,效果杠杠的。如果有要求可以多配几个485模块,完全可以满足要求。另外西门子很多通讯块的调用,多数都是异步调用的,tcp和串口之类的都是

Zane
版主

经验值:65276
发帖数:17857
精华帖:349
45楼    2022-08-02 17:28:11
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

三个灯,三个背景实例,灯之间完全没有耦合关系,随便怎么玩。

楼主的做法,却是用一个背景实例,把三个灯强行地耦合起来了,耦合就耦合了吧,在完成三次调用之前,完全无法知道知道三个灯之间的逻辑时序。不是说做不了,一堆的无用功啊。

当小兵的管好自己就可以了,小兵与小兵之间应该是班长去协调,编程也是一样,要分层次。


呵呵,某些所谓的大法,多好的机会来验证自己呀,屁都没放一个。

Zane 注册自动化系统工程师 Always save before download
坏笨笨
侠士

经验值:1415
发帖数:356
精华帖:3
47楼    2022-08-04 13:05:37
精编帖  主题:回复:【编程挑战】同一个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



坏笨笨
侠士

经验值:1415
发帖数:356
精华帖:3
48楼    2022-08-04 13:07:55
精编帖  主题:回复:【编程挑战】同一个FB使用同一个实例多次无条件调用完成功能

同时,这个程序最大的问题是需要判断参数,这在真正的异步中是不可以这样做得。 当然,还是强调下,楼主的这种调用异步是有问题的,异步需要配合外部状态机,分层次构筑程序,而不是葫芦串调用。

post_jingbian_commit.aspx
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。