找回密码
 会员注册
查看: 19|回复: 0

pythonpymodbus库使用教程(以ModbusRTU为例)(read_holding_registers()、read_input_registers())

[复制链接]

2

主题

0

回帖

7

积分

新手上路

积分
7
发表于 2024-9-5 10:12:18 | 显示全部楼层 |阅读模式
文档:https://pymodbus.readthedocs.io/en/latest/源码:https://github.com/riptideio/pymodbus/文章目录PythonPyModbus库使用教程:以ModbusRTU为例介绍安装PyModbus配置串行连接导入必要的模块创建Modbus客户端实例建立连接连接到Modbus设备读取数据读取寄存器关于读取其他寄存器以及查找pymodbus函数源码写入数据写入单个寄存器写入多个寄存器处理异常断开连接高级主题异步客户端(使用Twisted或Asyncio框架)自定义消息日志记录实例1.使用RS485modbus协议读取温度湿度传感器数据PythonPyModbus库使用教程:以ModbusRTU为例介绍Modbus是一种工业领域广泛使用的通信协议,而PyModbus是一个在Python中实现Modbus通信的库。它支持多种Modbus模式,包括RTU(通过串行线路),ASCII和TCP/IP。本教程将重点介绍如何使用PyModbus库进行ModbusRTU通信。安装PyModbus在开始编写代码之前,需要确保已经安装了PyModbus库。可以使用pip命令轻松地安装:pipinstallpymodbus1配置串行连接导入必要的模块首先,需要从pymodbus库中导入必要的模块:frompymodbus.client.syncimportModbusSerialClientasModbusClient1不知道是不是改版了,我用上面导入报错,用下面的可以:frompymodbus.clientimportModbusSerialClientasModbusClient1创建Modbus客户端实例接下来,创建一个ModbusClient实例,用于建立与Modbus设备的RTU通信:client=ModbusClient(method='rtu',port='/dev/ttyUSB0',baudrate=9600)1在这里,method参数设置为'rtu'以指定通信协议,port参数根据实际连接的串行端口进行设置(例如Linux系统中可能是'/dev/ttyUSB0',Windows中可能是'COM3'),baudrate参数设置传输速率,这些参数应与设备文档或配置相匹配。建立连接连接到Modbus设备在配置好客户端实例后,尝试连接到Modbus设备:ifclient.connect():print("ModbusRTUClientConnected")else:print("FailedtoconnecttoModbusRTUClient")1234读取数据读取寄存器Modbus协议定义了几种类型的寄存器,最常见的是保持寄存器和输入寄存器。以下示例展示了如何读取保持寄存器:response=client.read_holding_registers(address=1,count=10,unit=1)ifnotresponse.isError():print("RegisterValues:",response.registers)else:print("Failedtoreadregisters")12345在这个例子中,read_holding_registers方法用于读取地址为1的起始位置、数量为10的连续寄存器。unit参数表示从哪个单元(即设备ID)读取数据。注意:pymodbus某个版本已将unit字段改为slave。使用时即使写错也不会报错,注意查看你的pymodbus文档。关于读取其他寄存器以及查找pymodbus函数源码首先应该先通过厂商文档,看传感器要求用什么功能码去读取寄存器数据,拿到功能码后,转换成响应的函数,比如0x03是“输入寄存器(InputRegister)”,0x04是“保持寄存器(HoldingRegister)”,这在这里可以查到。然后可以到pythonmodbus库中搜源码,我用的虚拟环境,直接在ide里还链接不过去,所以我用fileLocatorpro工具直接搜源码,搜到这两个玩意:接下来就能知道函数该怎么调用了。写入数据写入单个寄存器要向设备的单个寄存器写入数据,可以使用以下代码:write_response=client.write_register(address=1,value=25,unit=1)ifnotwrite_response.isError():print("Writtensuccessfully")else:print("Failedtowriteregister")12345这里使用了write_register方法,它接受地址、要写入的值以及目标设备的单元ID。写入多个寄存器如果要写入多个寄存器,可以使用write_registers方法:values=[20,40,60,80,100]write_response=client.write_registers(address=1,values=values,unit=1)ifnotwrite_response.isError():print("Multipleregisterswrittensuccessfully")else:print("Failedtowritemultipleregisters")123456这里values列表包含了要写入寄存器的值序列。处理异常处理Modbus通信过程中可能出现的异常非常重要,可以使用try-except语句捕获这些异常:frompymodbus.exceptionsimportModbusExceptiontry:#尝试执行Modbus操作response=client.read_holding_registers(address=1,count=10,unit=1)exceptModbusExceptionasex:print("Anerroroccurred:",str(ex))1234567断开连接在完成所有Modbus通信后,应该关闭与设备的连接:client.close()print("ModbusRTUClientConnectionClosed")12调用close()方法将关闭串行端口,并释放相关资源。高级主题异步客户端(使用Twisted或Asyncio框架)除了同步客户端,PyModbus还提供了异步客户端选项,可以使用Twisted或Asyncio框架。异步客户端允许程序在等待响应时执行其他任务,对于需要同时处理多个Modbus请求的应用非常有用。自定义消息有时候,标准的Modbus函数不足以满足特定的需求。PyModbus允许创建自定义消息和事务处理器,使得可以扩展协议以适应特殊用例。日志记录调试和监控Modbus通信过程中,日志记录功能至关重要。PyModbus提供了详细的日志记录机制,可以帮助分析问题所在。实例1.使用RS485modbus协议读取温度湿度传感器数据#请先安装pymodbus和pyserial#pipinstallpymodbus#pipinstallpyserial#frompymodbus.client.syncimportModbusSerialClientasModbusClient#报错,说找不到syncfrompymodbus.clientimportModbusSerialClientasModbusClientfrompymodbus.exceptionsimportModbusException,ConnectionExceptionimportlogging#配置日志记录logging.basicConfig()log=logging.getLogger()log.setLevel(logging.DEBUG)#初始化Modbus串行客户端#client=ModbusClient(method='rtu',port='/dev/ttyUSB0',baudrate=9600,timeout=3)#[Errno2]couldnotopenport/dev/ttyUSB0:[Errno2]Nosuchfileordirectory:'/dev/ttyUSB0'#client=ModbusClient(method='rtu',port='/dev/ttyTHS1',baudrate=9600,timeout=3)#ttyTHS4ttyS0ttyS1ttyS2ttyS4#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'貌似没用defread_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,卖家说第三个寄存器是预留的,不用读ifresult.isError():#处理错误print("读取错误:",result)returnNone,None#将读取到的结果转换为温度和湿度registers=result.registerstemperature_reg=registers[0]humidity_reg=registers[1]#检查是否有探头错误iftemperature_reg==0x8000orhumidity_reg==0x8000:print("探头错误")returnNone,None#计算实际的温度和湿度值temperature=temperature_reg*0.1humidity=humidity_reg*0.1#格式化温度和湿度值,保留一位小数temperature=round(temperature,1)humidity=round(humidity,1)returntemperature,humidityexceptModbusExceptionase:print("Modbus异常:",e)returnNone,NoneexceptExceptionase:#捕获除ModbusException之外的所有异常print(f"Anerroroccurred:{e}")returnNone,Nonedefmain():try:ifclient.connect():#尝试连接到Modbus服务器/设备temperature,humidity=read_temperature_and_humidity(client)iftemperatureisnotNoneandhumidityisnotNone:print(f"温度:{temperature}°C,湿度:{humidity}%RH")client.close()#关闭连接else:print("无法连接到Modbus设备")exceptConnectionExceptionase:print("连接异常:",e)if__name__=="__main__":main()1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283运行结果:
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-7 06:05 , Processed in 0.411080 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表