C# 简单实现OPC DA Client 转 Modbus TCP Server【浮点数为例】

1、项目背景

很多工控环境,数据集中在OPC服务器上, 终端设备需要opc_da采集,很困难,即便终端是Windows系统,OPC的环境配置也及其麻烦,而终端若非Windows系统,基本上不太可能实现。现有能找见的转换工具要么付费;要么破解的老版本,很多bug。靠人不如靠自己,还是自己写的更方便。

2、引用库

OPC库,测试多个,最终选定:OpcNetApi
Modbus库,还选用顺手的 NModbus4
Json解析 Newtonsoft

3、为以后用起来灵活方便,采用Json配置文件

{
    
    
    "opc_da_host": "192.168.100.101",
    "opc_da_server": "Kepware.KEPServerEX.V6",
    "opc_da_items": [
        "SL1.TEST.YWCCQCKYL",
        "SL1.TEST.YWCCQJKYL",
        "SL1.TEST.YWCCQYC",
        "TX1.TEST.TXSSTXHYJYL",
        "YT1.TEST.CCSSDCCQRCDL",
        "YW1.TEST.SCDJLL",
        "YW1.TEST.YSWD"
    ],
    "modbus_slave_tcp_ip": "0.0.0.0",
    "modbus_slave_tcp_port": 502,
    "modbus_slave_id": 1,
    "modbus_slave_registers": [
        3043,
        3045,
        3021,
        3027,
        3019,
        3015,
        3017
    ],
    "interval": 1000
}

4、建立Modbus TCP服务

            var jt_conf = JToken.Parse(File.ReadAllText($@"{
      
      AppDomain.CurrentDomain.BaseDirectory}config.json")); //读取上面的配置文件
            //*******************************      建立 Modbus TCP Slave       ***************************************
            byte slaveId = ((byte)jt_conf["modbus_slave_id"]);
            int port = ((int)jt_conf["modbus_slave_tcp_port"]);
            IPAddress address = IPAddress.Parse(jt_conf["modbus_slave_tcp_ip"].ToString());
            var regs = jt_conf["modbus_slave_registers"].ToArray();

            TcpListener slaveTcpListener = new TcpListener(address, port);
            slave = ModbusTcpSlave.CreateTcp(slaveId, slaveTcpListener);
            slave.DataStore = store = DataStoreFactory.CreateDefaultDataStore();
            slave.ModbusSlaveRequestReceived += Slave_ModbusSlaveRequestReceived;

            var th_0 = new Thread(() =>
            {
    
    
                slave.Listen();
            })
            {
    
    
                IsBackground = true
            };
            th_0.Start();

5、连接OPC服务器

            //*******************************     连接OPC服务器       ***************************************
            var host = jt_conf["opc_da_host"].ToString();
            var node = jt_conf["opc_da_server"].ToString();
            var keys = jt_conf["opc_da_items"].ToArray();


            Item[] items = new Item[keys.Length];
            for (int i = 0; i < keys.Length; i++)
            {
    
    
                items[i] = new Item()
                {
    
    
                    ItemName = keys[i].ToString(),
                };
            }
            server = new Server(fact, null)
            {
    
    
                Url = new Opc.URL($@"opcda://{
      
      host}/{
      
      node}")
            };
            server.Connect();

6、从读OPC服务器读取数据,并转换填充到Modbus数据块

            //*******************************     获取数据,更新数据       ***************************************

            while (true)
            {
    
    
                Console.Clear();
                try
                {
    
    
                    Console.ForegroundColor = ConsoleColor.Green;
                    var values = server.Read(items);
                    foreach (ItemValueResult itemValue in values)
                    {
    
    
                        store.HoldingRegisters[(int)regs[Array.IndexOf(keys, itemValue.ItemName)]] = BitConverter.ToUInt16(BitConverter.GetBytes((float)itemValue.Value), 2);
                        store.HoldingRegisters[(int)regs[Array.IndexOf(keys, itemValue.ItemName)] + 1] = BitConverter.ToUInt16(BitConverter.GetBytes((float)itemValue.Value), 0);
                        Console.WriteLine($@"{
      
      itemValue.ItemName}@{
      
      regs[Array.IndexOf(keys, itemValue.ItemName)]}={
      
      itemValue.Value}");
                    }
                }
                catch (Exception ex)
                {
    
    
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine(ex.Message);
                    //throw;
                }
                Thread.Sleep(((int)jt_conf["interval"]));
            }

7、跑起来看看

在这里插入图片描述

8、项目源码链接

https://www.feijix.com/s/NbBJZ4c

猜你喜欢

转载自blog.csdn.net/lzl640/article/details/126680823