物联网浏览器(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.串口测试

modbus03

modbus04

3.TCP测试

modbus02

modbus01

三、部署到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地址通过扩展数据传入,端口号就是串口号。

文章转载自:木子清

原文链接:https://www.cnblogs.com/yizhuqing/p/17997593

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

相关推荐

  1. 联网Modbus 协议简介

    2024-02-02 09:08:03       39 阅读
  2. 联网之·协议·ZigBee】

    2024-02-02 09:08:03       50 阅读
  3. 联网常见协议

    2024-02-02 09:08:03       156 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-02 09:08:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-02 09:08:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-02 09:08:03       82 阅读
  4. Python语言-面向对象

    2024-02-02 09:08:03       91 阅读

热门阅读

  1. 类加载器与双亲委派模型

    2024-02-02 09:08:03       54 阅读
  2. 关于字符串的常用方法

    2024-02-02 09:08:03       46 阅读
  3. Docker进阶篇-Docker微服务实战

    2024-02-02 09:08:03       43 阅读
  4. Git提交忽略指定文件

    2024-02-02 09:08:03       47 阅读
  5. 【Git】多个托管平台Git账户配置

    2024-02-02 09:08:03       51 阅读
  6. C++ 多线程

    2024-02-02 09:08:03       40 阅读
  7. Django 中的 connection.cursor() 执行 SQL 用法

    2024-02-02 09:08:03       38 阅读