• 物联网浏览器(IoTBrowser)-Modbus协议集成和测试


    Modbus协议在应用中一般用来与PLC或者其他硬件设备通讯,Modbus集成到IoTBrowser使用串口插件模式开发,不同的是采用命令函数,具体可以参考前面几篇文章。目前示例实现了Modbus-Rtu和Modbus-Tcp两种,通过js可以与Modbus进行通讯控制。

     

     

     

    一、开发插件

      1. 添加引用
        1. 添加NModbus4,在NuGet搜索NModbus4
        2. 添加Core,路径:\IoTBrowser\src\app_x64\Core.dll
        3. 添加Infrastructure,路径:\IoTBrowser\src\app_x64\Infrastructure.dll
        4. 添加Newtonsoft,路径:\IoTBrowser\src\app_x64\Newtonsoft.Json.dll
      2. 开发ModbusRtu和ModbusTcp插件
        1. ModbusRtu

     

    复制代码
        public class ModbusRtuCom : ComBase
        {
            public override string Type => "modbusRtuCom";
    
            public override string Name => "ModbusRtuCom";
            private object _locker = new object();
    
            public override bool Init(int port, int baudRate = 9600, string extendData = null)
            {
                this.Port = port;
                var portName = "COM" + port;
                base.PortName = portName;
                ModbusRtuService.Init(portName, baudRate);
                Console.WriteLine("初始化ModbusRtuCom驱动程序成功!");
                return true;
            }
            public override event PushData OnPushData;
    
            public override bool Open()
            {
                var b = false;
                try
                {
                    ModbusRtuService.Open();
                    b = true;
                    IsOpen = true;
                }
                catch (Exception ex)
                {
    
                    string msg = string.Format("ModbusRtuCom串口打开失败:{0} ", ex.Message);
                    Console.WriteLine(msg);
                }
                return b;
            }
    
            public override bool Close()
            {
                ModbusRtuService.Close();
                IsOpen = false;
                OnPushData = null;
                return true;
            }
    
            public override string Command(string name, string data)
            {
                var outData = string.Empty;
                var dataObj = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(data);
                switch (name)
                {
                    case "ReadCoils":
                        //01
                        var readData = ModbusRtuService.ReadCoils(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.numberOfPoints.ToString()));
                        outData = ModbusHelper.ToString(readData);
                        break;
                    case "ReadInputs":
                        //02
                        readData = ModbusRtuService.ReadInputs(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.numberOfPoints.ToString()));
                        outData = ModbusHelper.ToString(readData);
                        break;
                    case "ReadHoldingRegisters":
                        //03
                        readData = ModbusRtuService.ReadHoldingRegisters(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.numberOfPoints.ToString()));
                        outData = ModbusHelper.ToString(readData);
                        break;
                    case "ReadInputRegisters":
                        //04
                        readData = ModbusRtuService.ReadInputRegisters(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.numberOfPoints.ToString()));
                        outData = ModbusHelper.ToString(readData);
                        break;
                    case "WriteSingleCoil":
                        //05
                        ModbusRtuService.WriteSingleCoil(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ModbusHelper.BoolParse(dataObj.value.ToString()));
                        break;
                    case "WriteSingleRegister":
                        //06
                        ModbusRtuService.WriteSingleRegister(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.value.ToString()));
                        break;
                    case "WriteMultipleCoils":
                        //0F 写一组线圈
                        var values = dataObj.value.ToString().Split(' ');
                        var datas = new bool[values.Length];
                        for (var i = 0; i < values.Length; i++)
                        {
                            datas[i] = ModbusHelper.BoolParse(values[i]);
                        }
                        ModbusRtuService.WriteMultipleCoils(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), datas);
                        break;
                    case "WriteMultipleRegisters":
                        // 10 写一组保持寄存器
                        values = dataObj.value.ToString().Split(' ');
                        var udatas = new ushort[values.Length];
                        for (var i = 0; i < values.Length; i++)
                        {
                            udatas[i] = ushort.Parse(values[i]);
                        }
                        ModbusRtuService.WriteMultipleRegisters(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), udatas);
                        break;
    
                }
                return outData;
            }
        }
    复制代码

     

     

     

                 b.ModbusTcp

     

    复制代码
        public class ModbusTcpCom : ComBase
        {
            public override string Type => "modbusTcpCom";
    
            public override string Name => "ModbusTcpCom";
            private object _locker = new object();
    
            public override bool Init(int port, int baudRate = 9600, string extendData = null)
            {
                this.Port = port;
                ModbusTcpService.Init(extendData, port);
                Console.WriteLine("初始化ModbusTcpCom驱动程序成功!");
                return true;
            }
            public override event PushData OnPushData;
    
            public override bool Open()
            {
                var b = false;
                try
                {
                    ModbusTcpService.Open();
                    b = true;
                    IsOpen = true;
                }
                catch (Exception ex)
                {
    
                    string msg = string.Format("ModbusTcpCom串口打开失败:{0} ", ex.Message);
                    Console.WriteLine(msg);
                }
                return b;
            }
    
            public override bool Close()
            {
                ModbusTcpService.Close();
                IsOpen = false;
                OnPushData = null;
                return true;
            }
    
            public override string Command(string name, string data)
            {
                var outData = string.Empty;
                var dataObj = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(data);
                switch (name)
                {
                    case "ReadCoils":
                        //01
                        var readData = ModbusTcpService.ReadCoils(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.numberOfPoints.ToString()));
                        outData = ModbusHelper.ToString(readData);
                        break;
                    case "ReadInputs":
                        //02
                        readData = ModbusTcpService.ReadInputs(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.numberOfPoints.ToString()));
                        outData = ModbusHelper.ToString(readData);
                        break;
                    case "ReadHoldingRegisters":
                        //03
                        readData = ModbusTcpService.ReadHoldingRegisters(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.numberOfPoints.ToString()));
                        outData = ModbusHelper.ToString(readData);
                        break;
                    case "ReadInputRegisters":
                        //04
                        readData=ModbusTcpService.ReadInputRegisters(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.numberOfPoints.ToString()));
                        outData = ModbusHelper.ToString(readData);
                        break;
                    case "WriteSingleCoil":
                        //05
                        ModbusTcpService.WriteSingleCoil(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ModbusHelper.BoolParse(dataObj.value.ToString()));
                        break;
                    case "WriteSingleRegister":
                        //06
                        ModbusTcpService.WriteSingleRegister(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.value.ToString()));
                        break;
                    case "WriteMultipleCoils":
                        //0F 写一组线圈
                        var values = dataObj.value.ToString().Split(' ');
                        var datas =new bool[values.Length];
                        for(var i=0;i< values.Length;i++)
                        {
                            datas[i] = ModbusHelper.BoolParse(values[i]);
                        }
                        ModbusTcpService.WriteMultipleCoils(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), datas);
                        break;
                    case "WriteMultipleRegisters":
                        // 10 写一组保持寄存器
                        values = dataObj.value.ToString().Split(' ');
                        var udatas = new ushort[values.Length];
                        for (var i = 0; i < values.Length; i++)
                        {
                            udatas[i] = ushort.Parse(values[i]);
                        }
                        ModbusTcpService.WriteMultipleRegisters(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), udatas);
                        break;
                        
                }
                return outData;
            }
        }
    复制代码

     

     

     

        3.功能

          1. 读单个线圈
          2. 读取输入线圈/离散量线圈
          3. 读取保持寄存器
          4. 读取输入寄存器
          5. 写单个线圈
          6. 写单个输入线圈/离散量线圈
          7. 写一组线圈
          8. 写一组保持寄存器

    源代码位置:\Plugins\DDS.IoT.Modbus

    二、本机测试

    1.测试前准备

    需要安装虚拟串口和modbusslave,可以在源代码中下载:

    https://gitee.com/yizhuqing/IoTBrowser/tree/master/soft

    2.串口测试

    modbus03modbus04

    3.TCP测试

    modbus02modbus01

    三、部署到IoTBrowser

    1.编译

    (建议生产环境使用Release模式)

    2.拷贝到Plugins文件夹

    也可以放到com文件夹。

    注意:需要拷贝NModbus4.dll到\IoTBrowser\src\app_x64目录下

    四、IoTBrowser集成测试

    1.串口测试

    modbus05

    写入多个数据写入以空格分割,写入线圈数据支持0/1或false/true。

    modbus06

    2.TCP测试

    modbus07

    TCP注意ip地址通过扩展数据传入,端口号就是串口号。

  • 相关阅读:
    编写云计算计费系统
    GlusterFS企业分布式存储
    Java线程中sleep()、wait()、yield()、join()方法的使用
    Spring中Endpoint、HasFeatures、NamedFeature和Actuator的关系及实现原理
    住宅IP与普通IP的区别
    spingboot按照依赖包除了maven还有Gradle,两者的区别?
    万字泣血解析割韭菜内情,程序员别老想着做副业
    c++ debug目录获取文件名及文件夹
    【ACM算法竞赛日常训练】DAY10题解与分析【月月给华华出题】【华华给月月出题】| 筛法 | 欧拉函数 | 数论
    springboot中的线程池
  • 原文地址:https://www.cnblogs.com/yizhuqing/p/17997593