python pymodbus库使用教程(以Modbus RTU为例)

news2024/9/29 17:34:35

文档:

https://pymodbus.readthedocs.io/en/latest/

源码:

https://github.com/riptideio/pymodbus/

文章目录

  • Python PyModbus库使用教程:以Modbus RTU为例
    • 介绍
    • 安装PyModbus
    • 配置串行连接
      • 导入必要的模块
      • 创建Modbus客户端实例
    • 建立连接
      • 连接到Modbus设备
    • 读取数据
      • 读取寄存器
    • 写入数据
      • 写入单个寄存器
      • 写入多个寄存器
    • 处理异常
    • 断开连接
    • 高级主题
      • 异步客户端(使用Twisted或Asyncio框架)
      • 自定义消息
      • 日志记录
    • 实例
    • 1. 使用RS485 modbus协议读取温度湿度传感器数据

Python PyModbus库使用教程:以Modbus RTU为例

介绍

Modbus是一种工业领域广泛使用的通信协议,而PyModbus是一个在Python中实现Modbus通信的库。它支持多种Modbus模式,包括RTU(通过串行线路),ASCII和TCP/IP。本教程将重点介绍如何使用PyModbus库进行Modbus RTU通信。

安装PyModbus

在开始编写代码之前,需要确保已经安装了PyModbus库。可以使用pip命令轻松地安装:

pip install pymodbus

配置串行连接

导入必要的模块

首先,需要从pymodbus库中导入必要的模块:

from pymodbus.client.sync import ModbusSerialClient as ModbusClient

不知道是不是改版了,我用上面导入报错,用下面的可以:

from pymodbus.client import ModbusSerialClient as ModbusClient

创建Modbus客户端实例

接下来,创建一个ModbusClient实例,用于建立与Modbus设备的RTU通信:

client = ModbusClient(method='rtu', port='/dev/ttyUSB0', baudrate=9600)

在这里,method参数设置为'rtu'以指定通信协议,port参数根据实际连接的串行端口进行设置(例如Linux系统中可能是'/dev/ttyUSB0',Windows中可能是'COM3'),baudrate参数设置传输速率,这些参数应与设备文档或配置相匹配。

建立连接

连接到Modbus设备

在配置好客户端实例后,尝试连接到Modbus设备:

if client.connect():
    print("Modbus RTU Client Connected")
else:
    print("Failed to connect to Modbus RTU Client")

读取数据

读取寄存器

Modbus协议定义了几种类型的寄存器,最常见的是保持寄存器和输入寄存器。以下示例展示了如何读取保持寄存器:

response = client.read_holding_registers(address=1, count=10, unit=1)
if not response.isError():
    print("Register Values: ", response.registers)
else:
    print("Failed to read registers")

在这个例子中,read_holding_registers方法用于读取地址为1的起始位置、数量为10的连续寄存器。unit参数表示从哪个单元(即设备ID)读取数据。

注意:pymodbus某个版本已将unit字段改为slave。使用时即使写错也不会报错,注意查看你的pymodbus文档。

写入数据

写入单个寄存器

要向设备的单个寄存器写入数据,可以使用以下代码:

write_response = client.write_register(address=1, value=25, unit=1)
if not write_response.isError():
    print("Written successfully")
else:
    print("Failed to write register")

这里使用了write_register方法,它接受地址、要写入的值以及目标设备的单元ID。

写入多个寄存器

如果要写入多个寄存器,可以使用write_registers方法:

values = [20, 40, 60, 80, 100]
write_response = client.write_registers(address=1, values=values, unit=1)
if not write_response.isError():
    print("Multiple registers written successfully")
else:
    print("Failed to write multiple registers")

这里values列表包含了要写入寄存器的值序列。

处理异常

处理Modbus通信过程中可能出现的异常非常重要,可以使用try-except语句捕获这些异常:

from pymodbus.exceptions import ModbusException

try:
    # 尝试执行Modbus操作
    response = client.read_holding_registers(address=1, count=10, unit=1)
except ModbusException as ex:
    print("An error occurred:", str(ex))

断开连接

在完成所有Modbus通信后,应该关闭与设备的连接:

client.close()
print("Modbus RTU Client Connection Closed")

调用close()方法将关闭串行端口,并释放相关资源。

高级主题

异步客户端(使用Twisted或Asyncio框架)

除了同步客户端,PyModbus还提供了异步客户端选项,可以使用Twisted或Asyncio框架。异步客户端允许程序在等待响应时执行其他任务,对于需要同时处理多个Modbus请求的应用非常有用。

自定义消息

有时候,标准的Modbus函数不足以满足特定的需求。PyModbus允许创建自定义消息和事务处理器,使得可以扩展协议以适应特殊用例。

日志记录

调试和监控Modbus通信过程中,日志记录功能至关重要。PyModbus提供了详细的日志记录机制,可以帮助分析问题所在。

实例

1. 使用RS485 modbus协议读取温度湿度传感器数据

# 请先安装 pymodbus 和 pyserial
# pip install pymodbus
# pip install pyserial


# from pymodbus.client.sync import ModbusSerialClient as ModbusClient   # 报错,说找不到 sync
from pymodbus.client import ModbusSerialClient as ModbusClient
from pymodbus.exceptions import ModbusException, ConnectionException
import logging

# 配置日志记录
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

# 初始化Modbus串行客户端
# client = ModbusClient(method='rtu', port='/dev/ttyUSB0', baudrate=9600, timeout=3)    # [Errno 2] could not open port /dev/ttyUSB0: [Errno 2] No such file or directory: '/dev/ttyUSB0'
# client = ModbusClient(method='rtu', port='/dev/ttyTHS1', baudrate=9600, timeout=3)
# ttyTHS4 ttyS0 ttyS1 ttyS2 ttyS4
# client = ModbusClient(method='rtu', port='/dev/ttyTHS1', baudrate=9600, timeout=3)
# client = ModbusClient(method='rtu', port='/dev/ttyTHS0', baudrate=9600, timeout=3, stopbits=1, bytesize=8, parity='N')
client = ModbusClient(port='/dev/ttyTHS0', baudrate=9600, timeout=3,
                      stopbits=1, bytesize=8, parity='N')    # 看文档,method='rtu'貌似没用


def read_temperature_and_humidity(client):
    try:
        # 读取寄存器地址0和1上的4个字节(两个寄存器)
        # result = client.read_input_registers(address=0, count=3, unit=1)  # 这个错了,这是读取输入寄存器的)0x04
        # result = client.read_holding_registers(address=0, count=3, unit=1)  # 这个才是读取输入寄存器的0x03  # unit参数错了,当前pymodbus版本没有这个参数,搞乌龙了,要不是用filelocator搜索函数用法,还真不知道- -
        result = client.read_holding_registers(
            address=0, count=2, slave=1)  # 读取输入寄存器的0x03 # 读两个寄存器就ok,卖家说第三个寄存器是预留的,不用读

        if result.isError():
            # 处理错误
            print("读取错误:", result)
            return None, None

        # 将读取到的结果转换为温度和湿度
        registers = result.registers
        temperature_reg = registers[0]
        humidity_reg = registers[1]

        # 检查是否有探头错误
        if temperature_reg == 0x8000 or humidity_reg == 0x8000:
            print("探头错误")
            return None, None

        # 计算实际的温度和湿度值
        temperature = temperature_reg * 0.1
        humidity = humidity_reg * 0.1

        # 格式化温度和湿度值,保留一位小数
        temperature = round(temperature, 1)
        humidity = round(humidity, 1)

        return temperature, humidity

    except ModbusException as e:
        print("Modbus异常:", e)
        return None, None
    except Exception as e:
        # 捕获除ModbusException之外的所有异常
        print(f"An error occurred: {e}")
        return None, None


def main():
    try:
        if client.connect():  # 尝试连接到Modbus服务器/设备
            temperature, humidity = read_temperature_and_humidity(client)
            if temperature is not None and humidity is not None:
                print(f"温度: {temperature}°C, 湿度: {humidity}%RH")
            client.close()  # 关闭连接
        else:
            print("无法连接到Modbus设备")
    except ConnectionException as e:
        print("连接异常:", e)


if __name__ == "__main__":
    main()

运行结果:

在这里插入图片描述

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

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

相关文章

[autojs]利用console实现悬浮窗日志输出

"ui"; ui.layout(<vertical><button id"autoFloatWindow" text"开启悬浮窗" textSize"15sp" /><button id"autoService" text"开启无障碍服务" textSize"15sp" /><button id"…

手把手教你如何提交App备案

手把手教你如何提交App备案 随着工信部出台了《工业和信息化部关于开展移动互联网应用程序备案工作的通知》对于我司所使用的到的移动应用APP就需要做app备案&#xff0c;今天用游戏app手把手教你如何提交App备案。 基本操作流程 运营、市场 提供需要备案的APP名称、主体、A…

如何避免Steam搬砖项目中账号被盗

购买steam余额有风险吗&#xff1f;及N种被红锁的情况 相信最近很多人都已经听说过steam游戏搬砖这个项目&#xff0c;也叫CSGO游戏搬砖项目&#xff0c;还有人叫它&#xff1a;国外steam游戏汇率差项目&#xff0c;无论怎么称呼&#xff0c;都是同一个项目。 那么什么是stea…

封装一个基于ThreeJS渲染基础模型的类,非常简单,可拖动可缩放

工作需求要求threeJS渲染一个模型以供可视化大屏展示&#xff0c;抛出模型精度不谈&#xff0c;只说业务实现 1.Three.JS的引入 ThreeJS官网地址:Three.js – JavaScript 3D Library 查看文档 中文切换及安装创建步骤 如果是自己研究学习用的&#xff0c;在官网安装完后&…

Docker部署单机nginx

一、拉取镜像运行容器 docker run -d --name nginx-server -v /opt/nginx-server:/home/work/tools/nginx/dist/html:ro nginx-d 后台运行 –name 为这个容器命名 -v 挂载&#xff0c;目录映射 /opt/nginx-server:/home/work/tools/nginx/dist/html 容器内地址&#xff1a;本地…

SA实战 ·《SpringCloud Alibaba实战》第14章-服务网关加餐:SpringCloud Gateway核心技术

大家好,我是冰河~~ 一不小心《SpringCloud Alibaba实战》专栏都更新到第14章了,再不上车就跟不上了,小伙伴们快跟上啊! 在《SpringCloud Alibaba实战》专栏前面的文章中,我们实现了用户微服务、商品微服务和订单微服务之间的远程调用,并且实现了服务调用的负载均衡。也基…

抖音汽车租赁小程序技术指南:开发高效便捷的租赁系统

为了更好地满足用户需求&#xff0c;抖音汽车租赁小程序成为一个备受关注的技术解决方案。本文将深入探讨开发高效便捷的汽车租赁系统所需的技术要点&#xff0c;为开发者提供一份实用的技术指南。 小程序架构选择 在搭建抖音汽车租赁小程序时&#xff0c;选择合适的小程序架构…

使用 Pinia 的五个技巧

在这篇文章中&#xff0c;想与大家分享使用 Pinia 的五大技巧。 以下是简要总结&#xff1a; 不要创建无用的 getter在 Option Stores 中使用组合式函数&#xff08;composables&#xff09;对于复杂的组合式函数&#xff0c;使用 Setup Stores使用 Setup Stores 注入全局变量…

Python入门教程之条件语句与运算符优先级详解

文章目录 Python 条件语句Python运算符优先级关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Python兼职渠道 Python 条件语句 …

vscode-insiders Remote-SSH XHR failed无法访问远程服务器

问题概述&#xff1a; destFolder/home/apple/.vscode-server-insiders > destFolder2/vscode-cli-05cd2640ec8a106a4ee99cb38e6ee34fbec04f11.tar.gz > 194f252f7426:trigger_server_download_end > Waiting for client to transfer server archive... > W…

VM——畸变校正、标定板标定

1、需求&#xff1a;精密测量时&#xff0c;使用远心镜头时依然会有畸变&#xff0c;最好使用标定板进行畸变校正和像素当量计算 2、方法&#xff1a;使用VM的“畸变校正”、“标定板标定”模块 2.1 标定板制作 step1: 使用海康的标定板生成工具&#xff0c;可以制作海康I型…

设计模式——行为型模式(二)

6.8 迭代器模式 6.8.1 概述 定义:提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。 6.8.2 结构 迭代器模式主要包含以下角色: 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合元素以及创建迭代器对象的接口。具体聚合(ConcreteAggreg…

python+pytest接口自动化:token关联登录这样做,阿里p8都直呼牛逼!!!

在PC端登录公司的后台管理系统或在手机上登录某个APP时&#xff0c;经常会发现登录成功后&#xff0c;返回参数中会包含token&#xff0c;它的值为一段较长的字符串&#xff0c;而后续去请求的请求头中都需要带上这个token作为参数&#xff0c;否则就提示需要先登录。 这其实就…

python+pytest接口自动化:cookie绕过登录(保持登录状态)这样做,测试组长都直呼牛逼!!!

在编写接口自动化测试用例或其他脚本的过程中&#xff0c;经常会遇到需要绕过用户名/密码或验证码登录&#xff0c;去请求接口的情况&#xff0c;一是因为有时验证码会比较复杂&#xff0c;比如有些图形验证码&#xff0c;难以通过接口的方式去处理&#xff1b;再者&#xff0c…

【高级程序设计】django与网页设计

django安装与配置 使用pip进行Django的安装: pip install djangoconda install django验证django安装成功 import django django.__version__ ## django.get_version()新建一个名称为blog的django项目(project), D:\>cd web-project D:\web-project>django-admi…

Nginx结合cpolar实现内网穿透多个Windows Web站点端口

文章目录 1. 下载windows版Nginx2. 配置Nginx3. 测试局域网访问4. cpolar内网穿透5. 测试公网访问6. 配置固定二级子域名7. 测试访问公网固定二级子域名 1. 下载windows版Nginx 进入官方网站(http://nginx.org/en/download.html)下载windows版的nginx 下载好后解压进入nginx目…

Pycharm 教育版下载

1 访问主站-->Developer Tools-->PyCharm JetBrains: Essential tools for software developers and teams 2 页面往下划找到 PyCharm for Education-->CHECK IT OUT! PyCharm: the Python IDE for Professional Developers by JetBrains 3 点击 Download free Lea…

TIDB基础

TIDB整个逻辑架构跟MYSQL类似&#xff0c;如下&#xff1a; TIDB集群&#xff1a;相当于MYSQL的数据库服务器&#xff0c;区别是MYSQL数据库服务器为单进程的&#xff0c;TIDB集群为分布式多进程的。 数据库&#xff1a;同MYSQL数据库&#xff0c;数据库属于集群&#xff0c;…

类初始化,类加载,类加载器

类初始化&#xff0c;类加载&#xff0c;类加载器 1. 类加载1.1. 类的加载1.2. 类的链接1.2.1. 验证1.2.2. 准备1.2.3. 解析 2. 类加载器2.1. 类加载器分为四种&#xff1a;前三种为虚拟机自带的加载器。2.2. 类加载有三种方式&#xff1a;2.3. **JVM类加载机制**2.4. 双亲委派…

财报解读:电商GMV增长30%后,快手将坚守本地生活?

快手逐渐讲好了其高质量成长的故事。 根据财报&#xff0c;快手三季度业绩超出预期&#xff0c;其中&#xff0c;营收279.5亿元&#xff0c;同比增长20.8%&#xff1b;调整后净利润31.7亿元&#xff0c;同比扭亏为盈。 而联系市场环境来看&#xff0c;三季度广告、电商市场较…