构建Modbus TCP写多个寄存器指令详解

构建Modbus TCP写多个寄存器指令详解

在Modbus TCP通信中,构建正确的指令对于实现设备间的数据交换至关重要。本文将详细解释如何构建一个Modbus TCP指令,用于向设备地址为1的从站,从地址200(0xC8)开始,连续写入8个寄存器,其中前4个寄存器写入值1,后4个寄存器写入值2。

一、Modbus TCP帧结构

Modbus TCP帧由两部分组成:

  1. MBAP头(Modbus Application Protocol Header):7个字节
  2. PDU(Protocol Data Unit):功能码及其相关数据

1.1 MBAP头结构

字节序号字段名称长度描述
0-1事务标识符2匹配请求与响应的唯一标识符
2-3协议标识符2固定为0x0000,表示使用Modbus协议
4-5长度字段2后续PDU部分的字节数,包括单元标识符
6单元标识符1从设备的地址(这里为1)

1.2 PDU结构

字节序号字段名称长度描述
0功能码1指示操作类型(写多个寄存器为0x10)
1-2起始地址2要写入的第一个寄存器地址(0x00C8)
3-4寄存器数量2要写入的寄存器数量(8个)
5字节计数1后续数据部分的字节数(8个寄存器 × 2 = 16)
6-21寄存器值16要写入的寄存器值,每个寄存器2字节

二、构建指令步骤

2.1 确定各字段值

  1. 事务标识符(Transaction Identifier):任意选择一个唯一值,例如0x0001
  2. 协议标识符(Protocol Identifier):固定为0x0000
  3. 长度字段(Length Field)
    • PDU部分包括:单元标识符(1) + 功能码(1) + 起始地址(2) + 寄存器数量(2) + 字节计数(1) + 寄存器值(16) = 23字节
    • 因此,长度字段为0x0017(23)
  4. 单元标识符(Unit Identifier):1(目标从设备地址)
  5. 功能码(Function Code):0x10(写多个寄存器)
  6. 起始地址(Starting Address):0x00C8(200)
  7. 寄存器数量(Quantity of Registers):0x0008(8)
  8. 字节计数(Byte Count):0x10(16)
  9. 寄存器值(Register Values)
    • 前4个寄存器值:0x0001, 0x0001, 0x0001, 0x0001
    • 后4个寄存器值:0x0002, 0x0002, 0x0002, 0x0002

2.2 构建完整指令

将上述字段按顺序排列,得到完整的Modbus TCP指令:

[0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x01,0x10, 0x00, 0xC8, 0x00, 0x08, 0x10,0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02]

2.3 字节分解

字节序号字节值描述
0-10x00 0x01事务标识符(1)
2-30x00 0x00协议标识符(0)
4-50x00 0x17长度字段(23)
60x01单元标识符(从设备地址1)
70x10功能码(写多个寄存器)
8-90x00 0xC8起始地址(200)
10-110x00 0x08寄存器数量(8)
120x10字节计数(16)
13-280x00 0x01, 0x00 0x01, 0x00 0x01, 0x00 0x01, 0x00 0x02, 0x00 0x02, 0x00 0x02, 0x00 0x02寄存器值(前4个为1,后4个为2)

三、示例代码实现

以下是使用Python和pymodbus库构建并发送上述Modbus TCP指令的示例代码:

3.1 安装pymodbus

首先,确保已安装pymodbus库:

pip install pymodbus

3.2 实现Modbus TCP客户端

from pymodbus.client.sync import ModbusTcpClient
from pymodbus.payload import BinaryPayloadBuilder
from pymodbus.constants import Endian# 创建Modbus TCP客户端并连接到服务器
client = ModbusTcpClient('192.168.1.100', port=502)  # 替换为实际服务器IP和端口
connection = client.connect()
if connection:print("连接成功")# 构建寄存器值:前4个寄存器为1,后4个寄存器为2builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big)for _ in range(4):builder.add_16bit_uint(1)for _ in range(4):builder.add_16bit_uint(2)payload = builder.to_registers()# 执行写多个寄存器操作starting_address = 200  # 起始地址register_values = payload  # 寄存器值列表result = client.write_registers(address=starting_address, values=register_values, unit=1)if not result.isError():print("写入成功")else:print("写入失败:", result)# 关闭连接client.close()
else:print("连接失败")

代码解析:

  1. 连接服务器:使用ModbusTcpClient连接到目标Modbus TCP服务器。
  2. 构建寄存器值:使用BinaryPayloadBuilder按照大端字节序(Endian.Big)依次添加寄存器值。
  3. 写入寄存器:调用write_registers方法,指定起始地址、寄存器值列表和从设备地址(1)。
  4. 处理响应:检查写入操作是否成功。
  5. 关闭连接

3.3 构建手动指令

如果需要手动构建上述Modbus TCP指令,可以参考以下Python代码:

def build_modbus_tcp_write_multiple_registers(transaction_id, unit_id, start_address, register_values):protocol_id = 0x0000function_code = 0x10quantity = len(register_values)byte_count = quantity * 2# MBAP头mbap = [(transaction_id >> 8) & 0xFF,transaction_id & 0xFF,(protocol_id >> 8) & 0xFF,protocol_id & 0xFF,((6 + byte_count) >> 8) & 0xFF,  # Length high byte(6 + byte_count) & 0xFF,         # Length low byteunit_id]# PDUpdu = [function_code,(start_address >> 8) & 0xFF,start_address & 0xFF,(quantity >> 8) & 0xFF,quantity & 0xFF,byte_count]# 寄存器值for value in register_values:pdu.append((value >> 8) & 0xFF)pdu.append(value & 0xFF)# 合并MBAP头和PDUmessage = mbap + pdureturn message# 示例参数
transaction_id = 1
unit_id = 1
start_address = 200
register_values = [1, 1, 1, 1, 2, 2, 2, 2]# 构建指令
instruction = build_modbus_tcp_write_multiple_registers(transaction_id, unit_id, start_address, register_values)
print("Modbus TCP指令:", [hex(byte) for byte in instruction])

输出结果:

Modbus TCP指令: ['0x0', '0x1', '0x0', '0x0', '0x0', '0x17', '0x1', '0x10', '0xc8', '0x0', '0x8', '0x10', '0x0', '0x1', '0x0', '0x1', '0x0', '0x1', '0x0', '0x1', '0x0', '0x2', '0x0', '0x2', '0x0', '0x2', '0x0', '0x2']

这与前述手动构建的指令一致。

四、总结

通过上述步骤,我们成功构建了一个Modbus TCP指令,用于向从设备地址为1的从站,从地址200开始,连续写入8个寄存器,其中前4个寄存器写入值1,后4个寄存器写入值2。确保每个字段的正确性,特别是MBAP头中的长度字段,是实现成功通信的关键。

在实际应用中,推荐使用现有的Modbus库(如pymodbus)来简化指令的构建和发送过程,减少手动错误。同时,使用网络抓包工具(如Wireshark)可以帮助调试和验证Modbus TCP通信的正确性。

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

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

相关文章

【Golang】Go语言编程思想(六):Channel,第三节,使用Channel实现树的遍历

使用 Channel 实现树的遍历 tree 在此处简单回顾一下之前学过的二叉树遍历,首先新建一个名为 tree 的目录,并在其下对文件和子目录进行如下组织: 其中 node.go 存放的是 Node 的定义: package treeimport "fmt"type…

IDEA 2024 版本配置热部署

在实际开发过程中,每次修改代码就得将项目重启,重新部署,对于一些大型应用来说,重启时间需要花费大量的时间成本。对于一个后端开发者来说,重启过程确实很难受啊 采用下面三步骤可以完成 1.在IDEA中settings中搜索Debb…

【目标跟踪】DUT Anti-UAV数据集详细介绍

DUT Anti-UAV数据集是大连理工大学的团队公开的数据集(DUT是他们学校的简称),其中包括了两个子数据集:目标检测和目标跟踪(也就是说,目标检测和目标跟踪都可以用这个数据集)。该数据集为可见光模…

经典多模态模型CLIP - 直观且详尽的解释

阅读原文 在本文中,您将了解“contrastive language-image pre-training”(CLIP),这是一种创建视觉和语言表示的策略,效果非常好,可用于制作高度特定且性能卓越的分类器,而无需任何训练数据。本…

探索云原生安全解决方案的未来

我们是否充分意识到云端所面临的网络安全威胁? 在当今互联互通的世界中,维护安全的环境至关重要。云的出现扩大了潜在威胁的范围,因为它催生了机器身份(称为非人类身份 (NHI))及其秘密。随着组织越来越多地转向云原生…

项目组件框架介绍[etcd]

文章目录 前言etcd安装Ubuntu 上通过包管理器安装通过源码安装配置 客户端开发包开发包的安装接口介绍添加一个键值对获取一个键值对租约保活机制监听 封装服务注册与发现服务注册服务发现 前言 Etcd 是一个 golang 编写的分布式、高可用的一致性键值存储系统,用于配…

在Windows 10中使用SSH远程连接服务器(附花生壳操作方法)

SSH 在 linux 中是一种重要的系统组件,用户可以使用 SSH 来远程连接 linux 系统的计算机,或者传输文件。不过在 win10 以前,windows 并不原生支持 SSH,需要借助第三方工具来使用 SSH 功能。而实际上,微软在 2015 年就曾…

【环境搭建】Jeecg-Boot v3.5.0 Docker搭建

前言 最近需要复现JeecgBoot的SQL注入漏洞,必须要搭建JeecgBoot v3.5.0这个版本才行,DockerHub没人push这个版本的,相关博客也比较少,所以自己来搭建,记录一下过程。 前置环境 Ubuntu 20.04Docker version 27.3.1do…

【人工智能基础06】人工神经网络(练习题):神经网络的计算、激活函数的选择与神经网络的退化

文章目录 1. 基于神经网络计算心理健康程度2. 添加激活函数的神经网络计算3. 使用神经网络预测小胖是否会变胖4. 激活函数选择的讨论5. 神经网络的设计6. 深度线性模型的表达能力线性模型7. 神经网络退化 主要讨论的内容 什么是人工神经网络,相关计算反向传播算法的…

STM32 串口收发文本数据包

单片机学习! 目录 前言 一、文本数据包格式 二、串口收发文本数据包代码 三、代码解析 3.1 标志位清除 3.2 数据包接收 四、代码问题改进 总结 前言 本文介绍了串口收发文本数据包程序设计的思路并详解代码作用。 一、文本数据包格式 文本数据包的格式的定义…

预言机调研

预言机 1. 概述 预言机主要承担两个工作,一是验证信息可靠性,二是传递信息。 如果没有预言机,区块链的信息来源将仅限于其内部数据,其广泛使用的潜力和可能性将会大大降低。 区块链预言机是区块链与外部世界之间的桥梁。它们使区…

【1211更新】腾讯混元Hunyuan3D-1文/图生3D模型云端镜像一键运行

目录 项目介绍 显存占用 11月21 新增纹理烘焙模块Dust3R 烘焙相关参数: AutoDL云端镜像 启动说明 标准模型下载 项目介绍 https://github.com/Tencent/Hunyuan3D-1 腾讯混元 3D 生成模型,支持文本和图像条件生成(对于文生3D,支持中/英双语生成)…

【前端】HTML标签汇总

目录 展示用户信息的标签 1.文本标签 span 2.标题标签 h1~h6 3.竖着布局的标签 div 4.段落标签 p 5.超链接标签 a 5.1跳转至网上的资源 5.2锚点 6.列表标签 6.1有序列表 ol 6.2无序列表 ul 7.图片标签 img 7.1相对路径 7.1.1兄弟关系 7.1.2叔侄关系 7.1.3表兄弟…

今天你学C++了吗?——C++中的类与对象(日期类的实现)——实践与知识的碰撞❤

♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥ ♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥ ♥♥♥我们一起努力成为更好的自己~♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥ ♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥ ✨✨✨✨✨✨ 个…

负载均衡和tomcat

一、负载均衡 1.相关概念 nginx的反向代理<-->负载均衡 负载均衡 将四层或者是七层的请求分配到多台后端的服务器上&#xff0c;从而分担整个业务的负载。提高系统的稳定性&#xff0c;也可以提供高可用&#xff08;备灾&#xff0c;其中的一台后端服务器如果发生故障…

【蓝桥杯每日一题】推导部分和——带权并查集

推导部分和 2024-12-11 蓝桥杯每日一题 推导部分和 带权并查集 题目大意 对于一个长度为 ( N ) 的整数数列 ( A 1 , A 2 , ⋯ , A N A_1, A_2, \cdots, A_N A1​,A2​,⋯,AN​ )&#xff0c;小蓝想知道下标 ( l ) 到 ( r ) 的部分和 ∑ i l r A i A l A l 1 ⋯ A r \su…

【C++】判断能否被 3, 5, 7 整除问题解析与优化

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目描述&#x1f4af;老师代码实现与分析老师代码逻辑分析优点缺点 &#x1f4af;学生代码实现与分析学生代码逻辑分析优点缺点 &#x1f4af;改进与优化优化代码实现优化…

[计算机网络]IP地址推行的“书同文,车同轨”

硬件地址无法直接转换的故事 在很久很久以前&#xff0c;网络世界就像一个庞大的帝国&#xff0c;各个村落&#xff08;网络&#xff09;都有自己的语言&#xff08;硬件地址&#xff09;。每个村落都有自己的规则和习惯&#xff0c;村里的每户人家&#xff08;设备&#xff0…

深度优先搜索(DFS)与回溯法:从全排列到子集问题的决策树与剪枝优化

文章目录 前言&#x1f384;一、全排列✨核心思路✨实现步骤✨代码✨时间和空间复杂度&#x1f381;1. 时间复杂度&#x1f381;2. 空间复杂度 &#x1f384;二、子集✨解法一&#xff1a;逐位置决策法&#x1f381;步骤分析&#x1f381;运行示例&#x1f381;代码 ✨解法二&a…

egg初始搭建

前言 egg.js 是由阿里开源的面向企业级开发的 Node.js 服务端框架&#xff0c;它的底层是由 Koa2 搭建。 Github&#xff1a;https://github.com/eggjs/egg&#xff0c;目前 14.8K Star&#xff0c;egg 很适合做中台。 安装 首先&#xff0c;你要 确保 Node 已经配置环境变量…