读取MODBUS网关与串口读取

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()

 

### PyModbus 库使用教程 `pymodbus` 是一个功能强大的 Python 模块,用于实现 Modbus 协议的客户端和服务器端通信。它支持多种传输层协议,如 TCP、UDP 和串行接口 (RTU/ASCII)。 #### 安装 `pymodbus` 首先需要安装 pymodbus 可通过 pip 进行安装: ```bash pip install pymodbus ``` #### 创建简单的 Modbus 客户端示例 下面是如何创建一个基于 TCP 的简单 Modbus RTU 客户端来读取保持寄存器的数据。 ```python from pymodbus.client.sync import ModbusTcpClient as ModbusClient # 初始化客户端并连接到远程设备 client = ModbusClient('192.168.0.1', port=502) connection_status = client.connect() if not connection_status: print("无法建立连接") else: # 成功连接后尝试读取保持寄存器数据 result = client.read_holding_registers(address=400, count=1, unit=1) if not result.isError(): value = result.registers[0] print(f"从地址400处获取到值:{value}") else: print("读取失败") # 断开连接以释放资源 client.close() ``` 此段代码会尝试去连接指定IP及端口上运行着的服务,并从中取出编号为 400 开始的一个整数类型的寄存器内容;如果成功,则显示该数值。 #### 构建基本的 Modbus 服务端实例 接下来展示如何快速搭建起一台模拟性的TCP型ModBus主机以便其他节点可以其交互。 ```python from pymodbus.server.async_io import StartTcpServer from pymodbus.datastore import ModbusSequentialDataBlock, ModbusSlaveContext, ModbusServerContext def run_server(): store = ModbusSlaveContext( di=ModbusSequentialDataBlock(0x0,[False]*10), # 离散输入DI co=ModbusSequentialDataBlock(0x0,[True]*10), # 绕线圈CO hr=ModbusSequentialDataBlock(0x0,[i for i in range(10)]), # 保留HR ir=ModbusSequentialDataBlock(0x0,[i*10 for i in range(10)]) ) # 输入注册IR context = ModbusServerContext(slaves=store,single=True) StartTcpServer(context,address=("localhost", 502)) if __name__ == "__main__": run_server() ``` 这里定义了一个包含四组不同类型存储空间的数据上下文对象,然后将其传递给实际启动服务函数StartTcpServer()作为参数之一。 --- 以上就是关于PyModBus的基本介绍以及怎样运用这个模块构建简易版客户机和服务程序的例子了!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值