回复:Modbus设备FB接口设计背后的理念

已锁定

宝冬

  • 帖子

    423
  • 精华

    28
  • 被关注

    256

论坛等级:至圣

注册时间:2016-07-06

钻石 钻石 如何晋级?

发布于 2022-12-04 18:39:33

25楼

如何把本帖案例,改写成任意其它种类的串口Modbus设备以便于应用?


下图把连接到一个CB1241的5个温控器实例的管脚都展开


设备对象:作为交互载体,因为设备变了,所以这个UDT需要重新定义。但其中的Modbus的控制与反馈的子集不需要变化。任何Modbus设备,虽然它们功能不同,但是通信的控制是完全一样的。有变化的是需要操作的具体内容和读取的信息。


品牌任务通信表:这个UDT的内部格式不用动,只需要复制一个,改写每个任务的配置数据就行了。任务数组留出足够的长度即可。


公共IO的底层资源:这部分不用动。它并不是随设备的不同而变化,而是随每个案例的物理通信方式的变化而变化。比如直接走本体485,或经过以太网串口服务器中转。


公共IO的信息交换区:这个不变,它是为竞争设备之间的调度服务的,与设备种类和物理通道方式无关。


设备FB本身:这个是肯定要变化的。但是在内部分层解耦的设计下,它的内部改动并不是想象的那么大。具体来说有4个层需要变化:内外交互的功能逻辑;写任务配置;由于设备独有的工艺性特点带来的工艺性调度改变;读任务解析。除此之外完全不用动。

因为套路相似,改写代码其实很容易,甚至比其它部分都容易。因为对于特定设备来讲,这些东西的范围很窄,几乎是死的,没太多未知或需要商量的地方,都很明确。

包括大家提到的:在不同设备场景和应用下,设备modbus断线了也好,先读什么再写什么为了安全也好,这一类的,其实都是属于工艺性调度这一层中的不同元素。它们本身和通信并没有直接关系,可以随意变化。但如果你的代码结构,不是采用分层解耦模式,那么面对各种不同案例的工艺多样性变化,就会蒙圈,总要不断地调整整个FB的结构,而不是只动某一局部。这样就效率极低了,且非常容易出错不易调试。且在诸多案例之间,不易保持规范的设计一致性。

为什么采用分层解耦,原因就是为了便于改写。一种设备一个FB,拖拽实例,使用简单。内部如何去包容复杂多变的不同案例场景可能性,就是分层解耦。无论问题多复杂,对任何一个局部问题元素,它所对应的局部代码段,都足够隔离化而原子化,就成了简单问题。

对于一个物理设备,我不喜欢FB里面套FB(基础IO指令除外),因为现实中的一个物理设备就是视觉中的一个东西,手里拿的一个东西。我喜欢现实世界中的实物与代码之间的对称性,所以就不喜欢用多个软实体的叠加嵌套来对应现实中的一个设备实物。这需要程序员始终遵守面向对象的数据结构设计思路。


PLC对外交换数据区(HMI或上位机或任意第三方数据交换的接口DB):因为出现了新的设备对象,作为交互载体,一定要加入到内外数据交换的接口中去。读写分离。


HMI上的设备面板:由于每个设备的功能是不同的,所以各自的操作面板是不同的,要单独做。如果你的设备对象的构造方式是有规律,遵循相同设计理念的,那么这种单独做的过程是有很多相似的地方,有很多基本元素是可以一样的。

我在设备面板上是通过下拉列表,为每个设备实例选择它的工艺角色的。PLC中加载的是同一类或同一品牌的多个预设空实例,这些实例的构造是一样的,但它们内置了不同的场景分支。每个设备实例究竟被用于现实工艺中的哪一个地方不是预先在PLC中写死的,而是要由操作人员在触摸屏上选择,PLC中的设备实例才会走不同的场景分支逻辑,同时在HMI上表现为不同的动画交互样式。这和现实中是一样的道理,你买来的同类设备都一模一样,但用在不同的地方,它们的运行表现和数据外观是不同的,这些都要实时同步到屏幕上的视觉。

每个设备同时都有一个单独的Modbus监控面板,这个面板是可以直接复制,少做修改甚至不做修改的。前面提到设备对象中的Modbus监控结构是一样的。品牌任务通信表的内部格式也是一样的,只是各个任务不同,可以把用到任务名称的地方改一下。


实践中按照上述改写,是很快的,有章法,不易出错。主要是分层解耦架构的作用,再就是PLC内外数据交换的接口化。


如果有多个485端口(包括PLC串口模块、串口服务器),每个通道都要准备一个公共IO的信息交换区,用于所有连到这个端口的设备调度用。

如果有多个种类的设备,且每类数量都不同,那就要为每类建一个设备对象数组,作为交互载体。且为每种设备改写出自己的设备FB。每个品牌的设备有自己的品牌任务通信表

多个不同种类不同数量的设备FB实例,根据各自连接的485端口不同,分别连接管脚参数,都放进一个FB即可。


---------------------------------------------------------------------------------

有一种设计是:485端口也都参数化,在屏幕上为每个设备单独设定。


比如:你在写程序的时候,不确定到底哪些设备,是连到CB1241或哪个CM1241或哪个串口服务器的哪个串口(一个串口服务器有多个串口)。一切都等到了现场再说,根据实际情况从屏幕配置参数。


再比如:你给一个Modbus设备写FB,不止针对眼前案例的PLC本体485模块,也考虑到未来的以太网途径,想一并解决,而不是到时候再为同一个设备写另一种FB。因为没有规定,一个串口modbus设备只能接在PLC本体485模块上,而不是串口服务器的更多485口。


这些参数一定是从屏幕经过设备对象进入PLC中每个实例的。这时候就不要为每个通道都分别准备一个公共IO信息交换区且分别连到不同的实例管脚上,因为你不知道谁会连着谁。


所有的设备实例都只需要一个公共IO信息交换区。在信息交换区内部,根据屏幕设定不同,再把这些实例在逻辑上分成不同的竞争协同组,就把大区分成小区。每个物理通路的协同调度都在组内发生。


这时候在屏幕上需要为每个设备设定的参数包括:

  • 每个设备实例的工艺角色选择;(确定它在具体工艺中的运用方式)

  • 每个设备实例的物理通路连接;

  • 每个设备实例的从站号;

  • 每个设备实例的485波特率;

  • 每个设备实例的IP地址和端口号(如果该设备走以太网串口服务器)

这些屏幕参数,和在现场摆弄设备的物理感受是完全对称一致的。这个设备是干啥用的?它连到哪个485口了?它的菜单和内部通信参数是如何设定的?


此处我再一次提到分层解耦架构,在这样的场景中,它的现实意义再明显不过了吧。


每个FB都同时具有走串口和以太网的能力,根据屏幕选择随时切换,不同通路的调度和底层IO都是不同的。如果是传统架构,要随时在一个FB中加入这些比较大的能力,非得搞懵了。


这种场景下,前面提到的走以太网的公共IO资源就要添加到设备FB的管脚上。对于Modbus设备走串口服务器,必选UDP来传递modbus报文,比TCP好太多,类似下图。这个早起案例中的UDP Server的地址(Remote_Addr_UDP),还是在设备FB之外单独设定的,它可以封装进设备对象内部的modbus控制子集。


对于设备FB内部的分层架构,只需要在两个层中添加元素即可。

一个层是通信通道的初始化。加入与MBCommLoad平行的元素,完成UDP通道的设定。因为UDP需要一个连接,而这个连接的Socket设定是可以随时动态同步更改的,也就是可以遍历轮询多个串口的上多个设备。走串口服务器与PLC的硬件组态无关,这与增加多个CM1241需要在博图中预先组态设定完全不同。只需屏幕上输入不同的IP地址和端口号。

第二个层是通信任务执行。加入与MBMaster指令平行的MBMasterUDP。来自屏幕设备对象的选择,就决定了会执行哪个IO指令。

其它层什么都不动。如果是传统非解耦架构,会非常繁琐且肯定出错,调试费力。


解耦封层的价值在于:无论你做过多少串口Modbus设备的应用案例,这些设备有多么不同,打开它们的FB会发现,FB内部的分层可以是完全一致的,只有某些层或某些层中局部元素的内容是不同的。其实不仅限于Modbus应用,任何存在公用协同竞争的通信和IO途径,都可以用类似架构处理。如果是私有IO,那就更简单了。


程序员如何为现场留出空间,改善体验。差这一点可能就差不少价钱,和使用者对你的品牌和产品设计的喜欢。


架构设计的重要性,远远大于局部代码和算法。根本上就是你对千差万别的应用场景的共性的理解和抽象。


评论
编辑推荐: 关闭

请填写推广理由:

本版热门话题

SIMATIC S7-1200系列

共有15705条技术帖

相关推荐

热门标签

相关帖子推荐

guzhang

恭喜,你发布的帖子

评为精华帖!

快扫描右侧二维码晒一晒吧!

再发帖或跟帖交流2条,就能晋升VIP啦!开启更多专属权限!

  • 分享

  • 只看
    楼主

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