调用C#中PLC标记数据更改上的事件

本文关键字:事件 数据 PLC 调用 | 更新日期: 2023-09-27 18:29:53

每当PLC标记值发生变化时,我需要从PLC读取值并以表格形式显示。

会有我需要监控的标签列表。每当TAG值发生变化时,我都需要调用一个函数(每个标签有不同的函数)。

这就是我迄今为止为捕捉Tag值更改所做的工作。。

连接到PLC后,我将创建标记列表。

读取计时器中的TAG值。

在读取时,我将使用OLDVALUES标记进行检查,如果值有任何变化,我将引发一个事件。

这对4或5个标签都很有效。当Tag计数大于100时,某些Tag更改事件不会触发。。

这就是到目前为止我所做的。。

 public delegate void DataChangedEventHandler(string TagName, string NewValue);
    private Timer tmr = new Timer();
    public event DataChangedEventHandler OnDataChanged;
    private void StartTimer(DataTable dt)
    {
        AddTagList(dt);
        SetInitialVales();
        tmr.Tick += timerticks;
        tmr.Interval = 250;
        tmr.Enabled = true;
        tmr.Start();
    }
    private void StopTimer()
    {
        tmr.Enabled = false;
        tmr.Stop();
    }

我将添加标签列表。。

    private List<string> TagValues = new List<string>();
    private List<string> oldValues = new List<string>();
    private List<string> newValues = new List<string>();
    private void AddTagList(DataTable dt)
    {
        int ILoop = 0;
        foreach (DataRow row in dt.Rows)
        {
            TagValues.Add((string)row["Path"]);
            ILoop = ILoop + 1;
        }
    }

设置标记的初始值。

private void SetInitialVales()
    {
        int iLoop = 0;
        foreach (string vals in TagValues)
        {
            var rd = ReadTag(vals);
            oldValues.Add(rd.ToString());
            newValues.Add(rd.ToString());
            iLoop = iLoop + 1;
        }
        //newValues = oldValues
    }

以及主要的数据更改部分。

     private void timerticks(object sender, EventArgs eventArgs)
    {
        int iLoop = 0;
        foreach (string vals in TagValues)
        {
            oldValues[iLoop] = ReadTag(vals).ToString();
            if (oldValues[iLoop] != newValues[iLoop])
            {
                newValues[iLoop] = oldValues[iLoop];
                if (OnDataChanged != null)
                {
                    OnDataChanged(vals, newValues[iLoop]);
                }
            }
            iLoop = iLoop + 1;
        }
    }

我的查询:

1.如果在已经引发的事件仍在进行(子过程未完成)的情况下引发事件,会发生什么??是因为这个原因我错过了一些数据更改事件吗??

2.如何在LIST值的成员发生更改时自动引发引发事件??

3.还有其他更好的方法来处理计时器读取的问题吗?

调用C#中PLC标记数据更改上的事件

如果一个事件被引发,而已经引发的事件仍在进行,会发生什么

直到您的代码执行完上一个事件,才会引发该事件。很明显,当你发起的事件持续时间过长,超过1秒时,你会遇到麻烦。你拥有的标签越多,或者在一次扫描中可以更改的标签越多,这些事件花费1秒以上从而错过标签更改的几率就越大。

您需要将扫描与事件处理解除耦合。您可以使用一个工作线程来执行此操作,该线程只检查循环中的标记更改。如果它看到任何更新,请将更新通知放入线程安全队列中。另一个线程,如UI线程,可以清空队列并处理通知。队列现在充当了一个缓冲区,提供了足够的存储空间,以便能够跟上标签突然发生的变化。

创建一个包含新旧值的类,然后创建一个以标记为键的映射来访问新旧实例,不是更好吗?

在其他方面,你似乎有很多事情需要保持同步。