物联网浏览器(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"://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.功能

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/661394.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第三十六天| 435. 无重叠区间、763.划分字母区间、56. 合并区间

435. 无重叠区间 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 解题思路&#xff1a;按左边界进行由小到大排序&#xff0c;然后前一个的右边界和后一个的左边界相比&#xff0c;看是否相交&#xff0c;如果相交&#xff0c;…

【EI会议征稿中|ACM出版】#先投稿,先送审#第三届网络安全、人工智能与数字经济国际学术会议(CSAIDE 2024)​

#先投稿&#xff0c;先送审#ACM出版#第三届网络安全、人工智能与数字经济国际学术会议&#xff08;CSAIDE 2024&#xff09; 2024 3rd International Conference on Cyber Security, Artificial Intelligence and Digital Economy 2024年3月8日-10日 | 中国济南 会议官网&…

oracle数据库慢查询SQL

目录 场景&#xff1a; 环境&#xff1a; 慢SQL查询一&#xff1a; 问题一&#xff1a;办件列表查询慢 分析&#xff1a; 解决方法&#xff1a; 问题二&#xff1a;系统性卡顿 分析&#xff1a; 解决方法&#xff1a; 慢SQL查询二 扩展&#xff1a; 场景&#xff1a; 线…

CXO清单:低代码平台必备的16个基本功能:从需求到实现的全面指南

对于 CIO、CTO 和 CDO&#xff08;在此统称为 CXO&#xff09;来说&#xff0c;认识到快速变化的技术和竞争格局以及他们在组织中的角色变化至关重要。处理持续不断的软件开发请求、考虑不断变化的业务流程、提高客户和法规的透明度、提高企业数据安全性以及在短时间内扩展基础…

精酿啤酒:麦芽汁的煮沸与沸腾时间的影响

在啤酒酿造过程中&#xff0c;麦芽汁的煮沸与沸腾时间是关键的工艺参数&#xff0c;对啤酒的品质和口感具有显著影响。对于Fendi Club啤酒来说&#xff0c;合理控制煮沸与沸腾时间更是重要。 首先&#xff0c;麦芽汁的煮沸时间对啤酒的口感和稳定性有重要影响。煮沸时间过短&am…

如何使用宝塔面板搭建MySQL 5.5数据库并实现公网远程连接

文章目录 前言1.Mysql服务安装2.创建数据库3.安装cpolar3.2 创建HTTP隧道 4.远程连接5.固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 宝塔面板的简易操作性,使得运维难度降低,简化了Linux命令行进行繁琐的配置,下面简单几步,通过宝塔面板cp…

详解Keras3.0 Layer API: Base RNN layer

RNN layer keras.layers.RNN(cell,return_sequencesFalse,return_stateFalse,go_backwardsFalse,statefulFalse,unrollFalse,zero_output_for_maskFalse,**kwargs ) 参数说明 cell: 这是循环神经网络的单元类型&#xff0c;可以是LSTM、GRU等。它定义了循环神经网络的基本单…

linux系统上C程序的编译、运行及调试-gcc

gcc -o timer timer.c &#xff1a;生成可执行文件main&#xff0c;依托main.c,也可依托多个文件./timer :运行代码

【0254】深入分析Query Execution(二)

上一篇:【0253】深入分析Query Execution(一) 1. 转换(Transformation) 在下一阶段,可以对查询进行转换(重写, rewritten)。 PostgreSQL核心使用转换有几个目的。其中之一是将解析树中的视图名称替换为与该视图的基本查询相对应的子树。 使用转换的另一种情况是行级…

Skywalking的Trace Profiling 代码级性能剖析功能应用详解

代码级性能剖析 Skywalking 提供了Trace Profiling功能对具体出现问题的span进行代码级性能剖析。 代码级性能剖析就是利用方法栈快照&#xff0c;并对方法执行情况进行分析和汇总。并结合有限的分布式追踪 span 上下文&#xff0c;对代码执行速度进行估算。性能剖析激活时&a…

[C#][opencvsharp]winform实现自定义卷积核锐化和USM锐化

【锐化介绍】 图像锐化(image sharpening)是补偿图像的轮廓&#xff0c;增强图像的边缘及灰度跳变的部分&#xff0c;使图像变得清晰&#xff0c;分为空间域处理和频域处理两类。图像锐化是为了突出图像上地物的边缘、轮廓&#xff0c;或某些线性目标要素的特征。这种滤波方法…

【Python_PySide6学习笔记(三十三)】文本编辑框QTextEdit添加图片

文本编辑框QTextEdit添加图片 文本编辑框QTextEdit添加图片前言一、创建 QTextEdit 对象二、通过 QImage 加载图片,并调整图片的大小及比例三、创建 QTextCursor 对象四、通过QTextCursor 对象的 insertImage() 将图片插入到 QTextEdit 中五、完整代码及实现效果文本编辑框QTe…

详细分析SpringSecurity中的@PreAuthorize注解

目录 1. 基本知识2. 使用方式2.1 配置类2.2 直接使用 1. 基本知识 在Java中&#xff0c;PreAuthorize 是Spring Security框架中的一个注解&#xff0c;用于在方法调用之前对用户的权限进行验证。 允许在方法级别定义访问控制规则&#xff0c;确保只有满足指定条件的用户才能调…

boost asio对于epoll关闭套接字顺序

其方法定义在 boost::system::error_code reactive_socket_service_base::close(reactive_socket_service_base::base_implementation_type& impl,boost::system::error_code& ec) {if (is_open(impl)){BOOST_ASIO_HANDLER_OPERATION(("socket", &impl,…

HarmonyOS ArkUI基础学习01

以下涉及的项目源码地址&#xff1a; https://gitee.com/jiangqianghua/harmony-test 更多学习资源资源点我获取 1. 一些常用组件方法 加载resource/base/element/string.json资源 Text($r("app.string.Username_label"))设置颜色 Color.red“#ff00ff”读取资源文…

Java基础 集合(二)List详解

目录 简介 数组与集合的区别如下&#xff1a; 介绍 AbstractList 和 AbstractSequentialList Vector 替代方案 Stack ArrayList LinkedList 前言-与正文无关 生活远不止眼前的苦劳与奔波&#xff0c;它还充满了无数值得我们去体验和珍惜的美好事物。在这个快节奏的世界…

nodejs+vue+ElementUi家庭美食菜谱分享网站_in9c2

&#xff08;设计制作有一定的安全性&#xff1b;数据库方面主要采用的是MySQL来进行开发&#xff0c;其特点是稳定性好&#xff0c;数据库存储容量大&#xff0c;处理能力快等优势&#xff1b;服务器采用的是Tomcat服务&#xff0c;能够提供稳固的运行平台&#xff0c;确保系统…

JavaSE-项目小结-IP归属地查询(本地IP地址库)

一、项目介绍 1. 背景 IP地址是网络通信中的重要标识&#xff0c;通过分析IP地址的归属地信息&#xff0c;可以帮助我们了解访问来源、用户行为和网络安全等关键信息。例如应用于网站访问日志分析&#xff1a;通过分析访问日志中的IP地址&#xff0c;了解网站访问者的地理位置分…

TCP 三次握手

三次握手&#xff08;Three-way Handshake&#xff09;其实就是指建立一个TCP连接时&#xff0c;需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接…

Duplicate entry ‘2020045-2-1‘ for key ‘index_uid‘ 解决方案

项目场景&#xff1a; 今天小编在工作中编写接口对数据库增加相同的非主键数据的时候&#xff0c;突然出现了这样的一个错误&#xff1a; 下面我来给大家解答这个错误的出现原因以及解决办法。 问题描述 Duplicate entry 2020045-2-1 for key index_uid 这个错误大概意思就是…