ModbusTcp获取数据

ModbusTcp获取数据


记录一个用 pymodbus 库来获取数据的代码。

  • 注意:
    • 1.读取寄存器地址是16进制的。
    • 2.大小端转换通过代码知道原理。
    • 读取数据时,切记频率别太高,否则会出现连接被关闭问题。
from pymodbus.client.sync import ModbusTcpClient
import struct
from datetime import datetime 
import time
def read_coordinate(host, port, register_address, unit_id,coordinate):
    """
    通过Modbus TCP读取机械臂的X坐标值。

    参数:
    host (str): Modbus TCP服务器的IP地址。
    port (int): Modbus TCP服务器的端口号。
    register_address (int): 存储X坐标值的第一个寄存器地址。
    unit_id (int): Modbus设备的单元ID,默认为1。

    返回:
    float: 机械臂的X坐标值,如果读取失败则返回 None。
    """
    start_time = datetime.now()
    client = ModbusTcpClient(host, port)
    try:
        if client.connect():
            # 读取两个连续的寄存器
            response = client.read_holding_registers(address=register_address, count=6, unit=unit_id)
            if response.isError():
                print(f"Modbus error: {response}")
                return None
            else:
                # 获取两个寄存器的值
                registers = response.registers
                coordinates = []
                for i in range(0,6,2):
                    #小端模式
                    combined_value = (registers[i + 1] << 16) | registers[i]
                    #大端模式
                    # combined_value = (registers[i] << 16) | registers[i + 1]
                    # 将两个寄存器的值组合成一个32位整数
                    coordinate_value = struct.unpack('!f', struct.pack('!I', combined_value))[0]
                    coordinates.append(coordinate_value)
                coordinate.extend(coordinates)
                return coordinates
        else:
            print("Failed to connect to Modbus server")
            return None
    finally:
        client.close()

if __name__ == "__main__":
# 示例使用
    host = '192.168.2.100'  # 替换为实际的Modbus服务器IP地址
    port = 502              # 替换为实际的Modbus服务器端口号
    register_address = 0x54 # 替换为实际的寄存器地址
    unit_id = 1
    coordinate = []

    while True:
        coordinate = read_coordinate(host, port, register_address,unit_id,coordinate)
        if coordinate is not None:
            x_coordinate = coordinate[0] * 1000
            y_coordinate = coordinate[1] * 1000
            z_coordinate = coordinate[2] * 1000
            print(f"机械臂的Xyz坐标值: {x_coordinate,y_coordinate,z_coordinate}")
            coordinate.clear()
        else:
            print("无法读取机械臂的X坐标值")
        time.sleep(0.2)
### Modbus TCP 数据读取与 DCBA 字节序转换 当使用Modbus TCP协议从设备读取数据时,通常会遇到需要将多个寄存器中的原始十六进制数值组合成更复杂的数据类型的情况。对于浮点数而言,在工业自动化领域中常见的做法是从四个连续的16位寄存器获取值,并按照特定顺序排列这些字节来形成IEEE754标准定义下的单精度(32-bit)或双精度(64-bit)浮点表示。 针对DCBA(最高有效位优先)这种特殊的字节排序方式: - **高地址高位(High Address High Byte, HAHB)** 放置在最左边 - 接着是低地址高位(Low Address High Byte, LAHB) - 然后再放低地址低位(Low Address Low Byte, LALB) - 最右边则是高地址低位(High Address Low Byte, HALB) 为了实现这一过程,可以采用如下Python代码片段作为示例[^1]: ```python import struct def modbus_registers_to_float(registers): """ 将来自Modbus响应消息体内的两个或者更多个16位整型组成的列表转换为一个32位浮点数, 假设输入遵循DCBA格式。 参数: registers (list): 包含至少两个元素的int类型的列表 返回: float: 转换后的浮点数值 """ # 对于DCBA模式下,我们需要先重组这四个字节到一个新的bytes对象里 bytes_data = ( ((registers[1] & 0xFF00) >> 8).to_bytes(1, 'big') + (registers[1] & 0x00FF).to_bytes(1, 'big') + ((registers[0] & 0xFF00) >> 8).to_bytes(1, 'big') + (registers[0] & 0x00FF).to_bytes(1, 'big') ) return struct.unpack('>f', bytes_data)[0] # 示例调用函数 example_registers = [0x4DCC, 0xCCCD] # 这是一个假设的例子,实际应用中应替换为此处获得的真实寄存器值 float_value = modbus_registers_to_float(example_registers) print(f"The converted floating point value is {float_value}") ``` 上述脚本展示了如何接收由`modbus-tcp`请求返回的一组寄存器值,并利用Python内置模块`struct`来进行最终的二进制串至浮点数之间的转变操作。注意这里的例子仅适用于处理32位浮点数;如果目标是64位,则需相应调整方法逻辑以及所使用的结构化字符串描述符[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值