写点什么

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

  • 2024-02-01
    福建
  • 本文字数:5274 字

    阅读完需:约 17 分钟

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

 


一、开发插件


  1. 添加引用


  • 添加 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


  1. 开发 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": //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; } }
复制代码


  • 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. 读单个线圈

    读取输入线圈/离散量线圈

    读取保持寄存器

    读取输入寄存器

    写单个线圈

    写单个输入线圈/离散量线圈

    写一组线圈

    写一组保持寄存器


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


二、本机测试


1.测试前准备


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


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


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

体验地址:http://www.jnpfsoft.com/?from=001

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
物联网浏览器(IoTBrowser)-Modbus协议集成和测试_浏览器_快乐非自愿限量之名_InfoQ写作社区