Delphi OmniThreadLibrary + OPC客户端 [英] Delphi OmniThreadLibrary + OPC Client

查看:237
本文介绍了Delphi OmniThreadLibrary + OPC客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理一个单线程OPC客户端程序,该程序管理着3个由西门子连接到同一OPC服务器的不同西门子PLC.

I am working in a single-thread OPC client program managing 3 different Siemens PLCs connected to the same OPC Server, also by Siemens.

单线程客户端如下所示:

The single-threaded client looks like this:

loop
 begin
  processPLC1;
  processPLC2;
  processPLC3;
end;

每个processPLC过程都调用底层的OPC库,例如:

Each processPLC procedures make calls to the underlying OPC library, such as:

 OPCutils.WriteOPCGroupItemValue(FGroupIf, FHandleItemOpc, Value);

好吧,现在我想在不同的线程中调用每个processPLC并并行工作.

Ok, now I want to call each processPLC in a different thread and work in parallel.

我做了一些研究,并使用OmniThreadLibrary开始了一些代码,但是我认为OPC代码不是多线程安全的.是吗?

I did some research and started some code using OmniThreadLibrary, but I don't think the OPC code is multithread-safe. Is it?

我应该使用task.Invoke还是类似的东西? ReadOPC函数如何返回PLC变量的值呢? 这里的最佳做法是什么?

Should I use task.Invoke or something like that? How about ReadOPC functions, which return the value of the PLC tag? What would be the best practices here?

谢谢!!!

推荐答案

我通常以两种方式完成此操作:

I've generally seen this done in two ways :

1)应用程序具有单个线程拥有的单个OPC客户端实例.在读取/写入OPC值时,由客户端应用程序自动执行的所有并行进程都将使用某种消息传递或与拥有OPC客户端的线程进行同步.

1) Application has a single OPC client instance owned by a single thread. All parallel processes being automated by the client application then use some sort of messaging or synchronization with the thread owning the OPC client when reading/writing OPC values.

2)每个线程拥有自己的专用OPC客户端,每个客户端都与OPC服务器独立通信.

2) Each thread owns its own private OPC client, each of which communicates independently with the OPC server.

我个人发现,最常用的方案是前者.一个OPC(或其他专有)客户端对象,该对象具有对客户端进行同步调用的线程.实际上,在几乎所有过程控制情况下,您都在使用多线程,目的是优雅地封装逻辑现实任务并将其与UI隔离,而不是为了任何性能.这些线程可以承受相对较长的等待数据的时间-如果需要,PLC会很高兴地按住堡垒100毫秒.

Personally, I've found that the most used scheme is the former; one OPC (or other proprietary) client object with threads making synchronized calls to the client. Really, in almost all process control situations you are multithreading for the purpose of elegantly encapsulating a logical real-world task and segregating it from the UI, not at all for any sort of performance. Those threads can afford to block for comparatively "long" periods waiting for data - the PLC will happily hold down the fort for a hundred milliseconds if it needs to.

选择哪种,很大程度上取决于应用程序的规模和性质.对于花费大量时间等待外部实时事件的许多轻量级线程,将单个OPC客户端实例保留在应用程序中并节省大量独立连接的开销是有意义的.对于少量繁重,快速移动的,OPC密集型线程,也许有意义,而是为每个线程分配自己的OPC客户端.

Which one you choose depends largely on the scale and nature of your application. For lots of light-weight threads which spend a long time waiting for external real-time events it makes sense to keep a single OPC client instance in the application and save the overhead of a large number of independent connections. For a small number of heavy, fast moving, OPC intensive threads it maybe makes sense to give each one its own OPC client instead.

还要记住OPC标签的刷新率-很多时候服务器仅以每100ms左右的顺序更新它们.即使执行一次扫描,您的PLC可能也要花费至少10毫秒的时间.当数据永远不会快速刷新时,让大量线程每秒独立地轮询服务器一百次是没有意义的.

Also keep in mind the refresh rate of your OPC tags - lots of times the server is only updating them on the order of every ~100ms or so. It's probably taking your PLC at least 10ms just to perform a single scan, even. It doesn't make sense to have a huge number of threads independently polling the server a hundred times per second when the data is never going to refresh that quickly.

对于过程控制软件,您真正想要的是拥有大量的空闲或低负载CPU时间-线程越轻越好.总体系统响应能力是关键,并且具有使您的软件处理高负载情况的能力(突然之间,大量任务会聚,而OS决定是时候对HDD进行索引了……净空可以保持嵌齿轮的润滑).您的大多数线程可能大部分时间都在等待.通常,事件和回调在这里最有意义.

For process control software what you really want is to have a lot of idle or low-load CPU time - the lighter your threads are the better. Total system responsiveness is key and the ability to have your software handle high load situations (suddenly a large number of tasks converge while the OS decides it is time to index the HDD... headroom keeps the cogs greased, so to speak). Most of your threads should probably be just waiting most of the time. Events and callbacks generally make most sense here.

此外,在这里考虑PLC编程也很重要.例如,在我的机器中,我有一些非常关键的时间操作,同时每次运行它们都具有唯一的时间-这些过程持续时间大约为几分钟,时间不到十分之一.一秒或更长时间,每天重复数百到数千次,并且每次运行的时间都是至关重要的,但持续时间却有所不同.我已经看到这些方法有两种处理方式-一种是软件方式,一种是PLC方法.对于前一种情况,软件会告诉PLC何时启动,然后运行直到软件指示其停止为止.这有明显的陷阱.在这种情况下,最好将时间间隔简单地发送到PLC并让其进行计时会更好.突然,所有时间/轮询压力都从软件中消除了,该过程可以很好地处理诸如自动化计算机崩溃之类的事情.如果您想对时间紧迫的数据给OPC服务器施加沉重压力,通常会付出很多代价.重新评估整个系统的设计-软件和PLC.

Also, thinking about the PLC programming is important here too. For example, in my machines I have a few very time-critical operations that are, at the same time, uniquely timed every time they are run - these are processes that are on the order of minutes in duration, timed to under a tenth of a second or better, repeated hundreds to thousands of times per day, and are of a critical but different duration each time they are run. I've seen these handled two ways - one in software, one in the PLC. For the former case the software tells the PLC when to start and then it goes until the software tells it to stop. This has obvious pitfalls; it's much better in this case to simply send the time interval to the PLC and let it do the timing. Suddenly all time/polling pressure is taken away from the software and the process can gracefully handle things like the automation computer crashing, etc. In cases where you are tempted to put heavy pressure on your OPC server for time-critical data it often pays to re-evaluate the design of the whole system - software and PLC.

这篇关于Delphi OmniThreadLibrary + OPC客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆