【问题标题】:C# OPC DA read valuesC# OPC DA 读取值
【发布时间】:2020-07-01 07:26:02
【问题描述】:

我试图通过 DA 协议从 OPC 读取值。我发现钛是免费的,这就是我的条件。我正在使用this 手册,其中写了如何从 OPC 服务器读取值,但只能从您在 OPC 服务器上使用您自己创建的变量创建的组中读取值。我想读取 OPC 服务器上已经存在的值并从中创建组,以便我可以读取它们的值。

已解决

解决办法

 static void Main(string[] args)
    {
        TitaniumAS.Opc.Client.Bootstrap.Initialize();

        Uri url = UrlBuilder.Build("Kepware.KEPServerEX.V6");

        using (var server = new OpcDaServer(url))
        {
            server.Connect();
            OpcDaGroup MyGroup = server.AddGroup("MyGroup");
            MyGroup.IsActive = true;
            var browser = new OpcDaBrowserAuto(server);
            OpcDaBrowseElement[] MySimulation = browser.GetElements("Simulation.Functions");
            OpcDaItemDefinition[] definitions = new OpcDaItemDefinition[MySimulation.Count()];
            for (int i = 0; i < MySimulation.Count(); i++)
            {
                definitions[i] = new OpcDaItemDefinition { ItemId = MySimulation[i].ItemId, IsActive = true };
            }
            MyGroup.AddItems(definitions);
            MyGroup.ValuesChanged += OnGroupValuesChanged;
            MyGroup.UpdateRate = TimeSpan.FromMilliseconds(100); // ValuesChanged won't be triggered if zero           
        }
    }
    static void OnGroupValuesChanged(object sender, OpcDaItemValuesChangedEventArgs args)
    {
        // Output values.
        foreach (OpcDaItemValue value in args.Values)
        {
            Console.WriteLine("ItemId: {0}; Value: {1}; Quality: {2}; Timestamp: {3}",
                value.Item.ItemId, value.Value, value.Quality, value.Timestamp);
        }
    }

对于需要像这样编辑 Program.cs 的表单

 static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// 
    /// </summary>
    //[STAThread]
    
    static void Main()
    {
        TitaniumAS.Opc.Client.Bootstrap.Initialize();
        var thread = new Thread(RunApplication);
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();  
    }
    static void RunApplication()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

非常感谢您的建议。

【问题讨论】:

  • 那么创建一个组是问题所在? docs 。好像你错过了OpcDaGroup group = server.AddGroup("MyGroup");group.IsActive = true; 之类的东西?
  • 将项目添加到组是我的问题,我不知道如何从 OPC 读取项目并将这些项目添加到我的组中
  • 看到您的代码,您甚至还没有使用MyGroup = server.AddGroup("MyGroup") 代码初始化您的组。运行时遇到什么错误?提供有关问题的更多详细信息。
  • 原谅我,我认为它不是初始化,而是向 OPC 服务器添加新组。错误在此行definitions[i].ItemId = MySimulation[i].ItemId; 它返回未设置为对象实例的对象引用。在变量MySimulation 中,我有 17 个项目,但我无法将它们转移到 definitions
  • 那么您想从服务器检索结构并读取这些值吗?为此,您需要编写一些递归方法来浏览结构树:这是一些示例代码:link。当您获得element 时,您可能可以从中获得ItemId 并创建一个新的OpcDaItemDefinition 并将其添加到您的组中。

标签: c# opc-da


【解决方案1】:

所以问题是当您迭代 definitionscollection 时,您还没有真正向其中添加任何项目:

OpcDaItemDefinition[] definitions = new OpcDaItemDefinition[MySimulation.Count()];
for (int i = 0; i < MySimulation.Count(); i++)
{
      definitions[i] = new OpcDaItemDefinition(...);
      //definitions[i].ItemId = MySimulation[i].ItemId;
      //definitions[i].IsActive = true;
}
MyGroup.AddItems(definitions);

这应该可以解决这个错误。

编辑:刚刚看到你的编辑,你也解决了。

【讨论】:

  • 是的,这是一个问题,抱歉我的愚蠢没有看到。至少也许这会对某人有所帮助。
  • 没问题,很高兴你找到了。
  • 我发现了另一个问题...如果我尝试将此解决方案移至 Windows 窗体应用程序会怎样。我找不到放置TitaniumAS.Opc.Client.Bootstrap.Initialize(); 的地方我试图放入static void Main(),但这给了我错误ExternalException: CoInitializeSecurity: Security must be initialized before any interfaces are marshalled or unmarshalled. It cannot be changed once initialized.。再次感谢您的任何建议。
  • 查看该方法的源代码,有更多关于如何使用它的信息:source file
  • 谢谢,我已经编辑了我的问题。希望我做对了
猜你喜欢
  • 2022-08-09
  • 1970-01-01
  • 1970-01-01
  • 2021-01-07
  • 2016-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-04
相关资源
最近更新 更多