Modbus协议在应用中一般用来与PLC或者其他硬件设备通讯,Modbus集成到IoTBrowser使用串口插件模式开发,不同的是采用命令函数,具体可以参考前面几篇文章。目前示例实现了Modbus-Rtu和Modbus-Tcp两种,通过js可以与Modbus进行通讯控制。
一、开发插件
-
添加引用
-
添加NModbus4,在NuGet搜索NModbus4
-
添加Core,路径:\IoTBrowser\src\app_x64\Core.dll
-
添加Infrastructure,路径:\IoTBrowser\src\app_x64\Infrastructure.dll
-
添加Newtonsoft,路径:\IoTBrowser\src\app_x64\Newtonsoft.Json.dll
-
开发ModbusRtu和ModbusTcp插件
-
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"://01var 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"://02readData = ModbusRtuService.ReadInputs(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.numberOfPoints.ToString()));outData = ModbusHelper.ToString(readData);break;case "ReadHoldingRegisters"://03readData = ModbusRtuService.ReadHoldingRegisters(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.numberOfPoints.ToString()));outData = ModbusHelper.ToString(readData);break;case "ReadInputRegisters"://04readData = ModbusRtuService.ReadInputRegisters(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.numberOfPoints.ToString()));outData = ModbusHelper.ToString(readData);break;case "WriteSingleCoil"://05ModbusRtuService.WriteSingleCoil(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ModbusHelper.BoolParse(dataObj.value.ToString()));break;case "WriteSingleRegister"://06ModbusRtuService.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;}}
-
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"://01var 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"://02readData = ModbusTcpService.ReadInputs(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.numberOfPoints.ToString()));outData = ModbusHelper.ToString(readData);break;case "ReadHoldingRegisters"://03readData = ModbusTcpService.ReadHoldingRegisters(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.numberOfPoints.ToString()));outData = ModbusHelper.ToString(readData);break;case "ReadInputRegisters"://04readData=ModbusTcpService.ReadInputRegisters(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ushort.Parse(dataObj.numberOfPoints.ToString()));outData = ModbusHelper.ToString(readData);break;case "WriteSingleCoil"://05ModbusTcpService.WriteSingleCoil(byte.Parse(dataObj.slaveAddress.ToString()), ushort.Parse(dataObj.startAddress.ToString()), ModbusHelper.BoolParse(dataObj.value.ToString()));break;case "WriteSingleRegister"://06ModbusTcpService.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.功能
-
读单个线圈
读取输入线圈/离散量线圈
读取保持寄存器
读取输入寄存器
写单个线圈
写单个输入线圈/离散量线圈
写一组线圈
写一组保持寄存器
源代码位置:\Plugins\DDS.IoT.Modbus
二、本机测试
1.测试前准备
需要安装虚拟串口和modbusslave,可以在源代码中下载:
物联网浏览器: IoTBrowser用于开发人机界面(HMI)或数据采集与监督控制系统(SCADA) 的工具,使用HTML或Vue前端技术开发物联网终端用户界面,支持串口、RFID、电子秤等硬件协议,支持js控制关机、全屏等工控操作。 - Gitee.com
2.串口测试
3.TCP测试
三、部署到IoTBrowser
1.编译
(建议生产环境使用Release模式)
2.拷贝到Plugins文件夹
也可以放到com文件夹。
注意:需要拷贝NModbus4.dll到\IoTBrowser\src\app_x64目录下
四、IoTBrowser集成测试
1.串口测试
写入多个数据写入以空格分割,写入线圈数据支持0/1或false/true。
2.TCP测试
TCP注意ip地址通过扩展数据传入,端口号就是串口号。
文章转载自:木子清
原文链接:https://www.cnblogs.com/yizhuqing/p/17997593
体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构