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

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,可以在源代码中下载:

物联网浏览器: 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快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

相关推荐
Cikiss9 分钟前
微服务实战——平台属性
java·数据库·后端·微服务
小小不董23 分钟前
《Linux从小白到高手》理论篇:深入理解Linux的网络管理
linux·运维·服务器·数据库·php·dba
无敌少年小旋风1 小时前
MySQL 内部优化特性:索引下推
数据库·mysql
柒小毓1 小时前
将excel导入SQL数据库
数据库
bug菌¹1 小时前
滚雪球学Oracle[2.5讲]:数据库初始化配置
数据库·oracle·数据库初始化·初始化配置
一休哥助手1 小时前
Redis 五种数据类型及底层数据结构详解
数据结构·数据库·redis
翔云1234561 小时前
MVCC(多版本并发控制)
数据库·mysql
代码敲上天.2 小时前
数据库语句优化
android·数据库·adb
盒马盒马2 小时前
Redis:zset类型
数据库·redis
静听山水2 小时前
mysql语句执行过程
数据库·mysql