pymodbus库使用教程(以Modbus RTU为例)
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
from pymodbus.exceptions import ModbusException, ConnectionException
import logging
from pymodbus.client.sync import ModbusSerialClient
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)
port = 'COM8' # 替换为您的串行端口
baudrate = 4800 # 替换为您的波特率
parity = 'N' # 替换为您的校验位
# 创建ModbusSerialClient实例,用于与Modbus服务器通信
client = ModbusSerialClient(method='rtu', port=port, baudrate=baudrate,stopbits=1, parity=parity)
def read_temperature_and_humidity(client):
try:
result = client.read_holding_registers(
address=0, count=2, slave=1,unit=1) # 读取输入寄存器的0x03 # 读两个寄存器
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():
temperature, humidity = read_temperature_and_humidity(client)
if temperature is not None and humidity is not None:
print(f"温度: {humidity}°C, 湿度: {temperature}%RH")
client.close() # 关闭连接
else:
print("无法连接到Modbus设备")
except ConnectionException as e:
print("连接异常:", e)
if __name__ == "__main__":
main()
TCP版
from pymodbus.client.sync import ModbusTcpClient
from pymodbus.exceptions import ModbusException
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)
# 远程Modbus服务器的IP地址和端口号
HOST = '192.168.1.250'
PORT = 8888
# 创建ModbusTcpClient实例,用于与Modbus服务器通信
client = ModbusTcpClient(HOST, port=PORT,ethod='rtu')
def read_holding_registers(unit, address, count):
"""
从Modbus服务器读取保持寄存器的值。
参数:
unit (int): 从站ID(slave ID)
address (int): 寄存器的起始地址
count (int): 要读取的寄存器数量
返回:
list: 读取到的寄存器值列表
"""
try:
# 连接到Modbus服务器
if client.connect():
print(f"成功连接到Modbus服务器 {HOST}:{PORT}")
# 读取保持寄存器
response = client.read_holding_registers(address, count, unit=unit)
# 检查是否成功接收到响应
if not response.isError():
print("读取寄存器成功")
return response.registers
else:
print("读取寄存器失败")
return None
else:
print("连接到Modbus服务器失败")
return None
except ModbusException as e:
print(f"Modbus异常: {e}")
return None
finally:
# 断开与Modbus服务器的连接
client.close()
def calculate_temperature(raw_value):
"""
根据传感器的数据格式计算实际温度值。
参数:
raw_value (int): 从传感器读取的原始温度值
返回:
float: 实际温度值
"""
if raw_value > 32767:
# 处理负温度值的补码
return -((65536 - raw_value) / 10.0)
else:
return raw_value / 10.0
def calculate_humidity(raw_value):
"""
根据传感器的数据格式计算实际湿度值。
参数:
raw_value (int): 从传感器读取的原始湿度值
返回:
float: 实际湿度值
"""
return raw_value / 10.0
def main():
# 从站ID,通常为1,除非您的设备配置不同
slave_id = 1
# 寄存器的起始地址,根据您的设备文档设置
start_address = 0
# 要读取的寄存器数量,根据您的需求设置
number_of_registers = 2
# 调用函数读取寄存器
registers = read_holding_registers(slave_id, start_address, number_of_registers)
# 打印读取到的寄存器值
if registers is not None:
# 计算温度和湿度
temperature_raw = registers[0]
humidity_raw = registers[1]
temperature = calculate_temperature(temperature_raw)
humidity = calculate_humidity(humidity_raw)
print(f"读取到的温度值为: {humidity}℃")
print(f"读取到的湿度值为: {temperature}%RH")
if __name__ == "__main__":
main()