python modbus 实现RTU 通信

python modbus 实现RTU 通信pythonmodbus tk 实现 RTU 通信下载对应 pip 由于没有硬件设备 采用软件模拟 软件下载地址为安装 vspd exe 用于模拟串口在没有安装前可以看到我们电脑没有对应的串口安装好通过 vspd 添加串口下载安装好开始连接 第一次连接需要激活模拟创建一个 HOLDING REGISTERS 点击左上角 file new 依次创建以下模拟器点击 Display communicatio 开始显示协

下载对应pip

pip install modbus_tk 

在通过rtu通信的时候我们需要下载modbusslave和modbuspol和vspd.exe

安装vspd.exe 用于模拟串口

在没有安装前可以看到我们电脑没有对应的串口

在这里插入图片描述

安装好通过vspd添加串口

在这里插入图片描述
可以看见电脑上多了两个端口
在这里插入图片描述




下载安装modbus slave好开始连接,第一次连接需要激活

模拟创建一个HOLDING_REGISTERS

在这里插入图片描述
简单修改设备id为1,function为03 Holding Register,点击ok

点击左上角file-new依次创建 以下 模拟器

在这里插入图片描述在这里插入图片描述在这里插入图片描述

点击Display-communication开始显示协议传输信息

在这里插入图片描述

编写python代码

# -*- coding: utf_8 -*- import serial import modbus_tk import modbus_tk.defines as cst from modbus_tk import modbus_rtu def mod(PORT="com2"): red = [] alarm = "" try: # 设定串口为从站 master = modbus_rtu.RtuMaster(serial.Serial(port=PORT, baudrate=9600, bytesize=8, parity='N', stopbits=1)) master.set_timeout(5.0) master.set_verbose(True) # 读保持寄存器 red = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 9) # 这里可以修改需要读取的功能码 print(red) alarm = "正常" return list(red), alarm except Exception as exc: print(str(exc)) alarm = (str(exc)) return red, alarm 如果异常就返回[],故障信息 if __name__ == "__main__": mod() 

运行结果

在这里插入图片描述

modbus slave监听到的数据如下

在这里插入图片描述

000080-Rx:01 03 00 00 00 09 85 CC 000081-Tx:01 03 12 00 14 00 15 00 16 00 17 00 00 00 00 00 00 00 00 00 00 11 6B 

对数据进行分析

000080-Rx:01 03 00 00 00 09 85 CC 000081-Tx:01 03 12 00 14 00 15 00 16 00 17 00 00 00 00 00 00 00 00 00 00 11 6B 

详细的报文分析见

https://blog.csdn.net/ouyangxin95/article/details// https://blog.csdn.net/_/article/details/ 

读寄存器

请求

01 从机地址 03 功能码 00 00 起始寄存器 00 09 读取寄存器个数 85 cc CRC校验 

响应

01 从机地址 03 功能码 12 返回数据个数,16进制12表示18, 每两位16进制表示一个数,共有9个数 00 14 表示20 00 15 表示21 ..... 这些数据和python程序返回的一样 11 6B CRC校验 

读线圈的和输入状态的分析一样

000660-Rx:02 01 00 00 00 02 BD F8 000661-Tx:02 01 01 03 11 CD 

请求

02 从机地址 01 功能码 00 00 起始寄存器 00 02 读取寄存器个数 BD F8 CRC校验 

响应

02 从机地址 01 功能码 01 返回数据个数 03 返回数据 03 起始代表读取了两个寄存器值都为1 显示为11, (3F 02 为数据 代表1111 1100 0100 0000 每四位逆序组成一位16进制, 每两位16进制组成一组数据,组成的数据线先组成的16进制在后面, 例如1111 1100的逆序是1111(F) 0011(3) 最后组成数据为3F) 

读寄存器里面小数数据

000004-Rx:01 03 00 00 00 04 44 09 000005-Tx:01 03 08 38 86 40 4E C6 A8 40 91 5B 67 

请求

01 从机地址 03 功能码 00 00 起始寄存器 00 04 读取寄存器个数 44 09 CRC校验 

响应

01 从机地址 03 功能码 08 返回数据个数 38 86 40 4E 第一个小数值因为一个浮点数占4个字节,而一个寄存器只能保存两个字节的数据,,因此使用两个寄存器保存一位小数 C6 A8 40 91 第二个小数值 5B 67 CRC校验 

对返回数据进行分析

原寄存器值为

在这里插入图片描述

38 86 40 4E

3886

00110 

404E

01110 

总数据(小端(404E 3886))

0  0 0 128 1.0 

128-127 = 1

右移一位 

最终数据,精度问题会有缺失

 11.000 3.95996 
C6 A8 40 91

这有个能直接转换,不用你分析的代码

import struct def ReadFloat(*args,reverse=False): for n,m in args: n,m = '%04x'%n,'%04x'%m if reverse: v = n + m else: v = m + n y_bytes = bytes.fromhex(v) y = struct.unpack('!f',y_bytes)[0] y = round(y,6) return y def WriteFloat(value,reverse=False): y_bytes = struct.pack('!f',value) # y_hex = bytes.hex(y_bytes) y_hex = ''.join(['%02x' % i for i in y_bytes]) n,m = y_hex[:-4],y_hex[-4:] n,m = int(n,16),int(m,16) if reverse: v = [n,m] else: v = [m,n] return v def ReadDint(*args,reverse=False): for n,m in args: n,m = '%04x'%n,'%04x'%m if reverse: v = n + m else: v = m + n y_bytes = bytes.fromhex(v) y = struct.unpack('!i',y_bytes)[0] return y def WriteDint(value,reverse=False): y_bytes = struct.pack('!i',value) # y_hex = bytes.hex(y_bytes) y_hex = ''.join(['%02x' % i for i in y_bytes]) n,m = y_hex[:-4],y_hex[-4:] n,m = int(n,16),int(m,16) if reverse: v = [n,m] else: v = [m,n] return v if __name__ == "__main__": print(ReadFloat((14470, 16462))) print(ReadFloat(( 50856, 16529))) print(WriteFloat(3.2222)) print(ReadDint((1734,6970))) print(WriteDint()) 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/217721.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 上午8:55
下一篇 2026年3月18日 上午8:55


相关推荐

  • 13 MATLAB 三维图形绘制

    13 MATLAB 三维图形绘制在实际工程应用中 常常遇到三维甚至更多维的数据 需要在图形中表示出来 MATLAB 中提供了相应的三维图形绘制功能 这些绘制功能与二维图形的绘制十分类似 特别是曲线的属性 例如线型 颜色等的设置 是完全相同的 最常用的三维绘图有三维曲线图 三维网格图和三维曲面图这 3 中基本类型 相应的 MATLAB 指令分别为 plot3 mesh 和 surf 1 曲线图绘制在已经学习了 plot 指令的基础上

    2026年3月18日
    2
  • 鼠标悬停下划线显示特效,html鼠标悬停显示下划线

    鼠标悬停下划线显示特效,html鼠标悬停显示下划线html:(index.html)<!DOCTYPEhtml><htmllang=”en”><head><metacharset=”UTF-8″><title>鼠标悬停下划线</title><linkrel=”stylesheet”href=”css/style.css”>&l…

    2022年5月16日
    52
  • painless数字类型转换_painless获取doc字段的方式「建议收藏」

    如果你写painless脚本的时候,发现对不同结构的字段获取有点困惑,那么本文可能会帮助你。取普通字段默认ES会把非text、非nested的字段存到docvalues列存储中,方便单独获取,而不用取_source里取,这样IO性能就很好。假设你有一个字段:”a”:1。那么doc[‘a’]返回的是[1],是一个数组。doc[‘a’].value返回的是1,也就是取第一个元素。doc[‘a’]….

    2022年4月17日
    64
  • Python递归算法解决斐波那契数列

    Python递归算法解决斐波那契数列**Python递归算法解决斐波那契数列**斐波那契数列指的是这样一个数列1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368…这个数列从第3项开始,每一项都等于前两项之和。递归算法定义:就是一个函数直接或间接调用自身的一种方法,他…

    2022年6月22日
    37
  • pytorch 查看cuda 版本

    pytorch 查看cuda 版本由于pytorch的whl安装包名字都一样,所以我们很难区分到底是基于cuda的哪个版本。有一条指令可以查看importtorchprint(torch.version.cuda)

    2022年6月4日
    48
  • sigsuspend的用法

    sigsuspend的用法include include includevoidm op int main nbsp nbsp nbsp nbsp nbsp nbsp nbsp sigset tnew mask nbsp nbsp nbsp nbsp nbsp nbsp nbsp structsigact

    2026年3月19日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号