物聯網瀏覽器(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地址通過擴展數據傳入,端口號就是串口號。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章