You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Minimal Modbus向PLC写入浮点数时的字序交换问题

解决Minimal Modbus写入浮点数字序错误及负数寄存器写入问题

一、浮点数字序交换的正确实现

你预交换字序时报错,是因为直接传递了numpy数组给write_float,但这个方法只接受单个数值类型的输入。要满足PLC的字序要求,我们可以绕开write_float,手动拆分浮点数为寄存器值后交换写入:

  1. 先把浮点数转换成两个16位寄存器的原始值(模拟write_float的内部转换逻辑):
import struct
import minimalmodbus

# 目标浮点数
target_float = 123.456

# 将浮点数打包为大端格式的4字节流,再拆分为两个16位寄存器值
packed_bytes = struct.pack('>f', target_float)
reg_val1 = struct.unpack('>H', packed_bytes[0:2])[0]
reg_val2 = struct.unpack('>H', packed_bytes[2:4])[0]

# 交换两个寄存器的顺序(匹配PLC的字序要求)
swapped_registers = [reg_val2, reg_val1]
  1. 用write_registers一次性写入交换后的寄存器:
# 初始化设备(根据你的实际端口和站号调整)
plc1 = minimalmodbus.Instrument('/dev/ttyUSB0', 1)
# 写入到起始寄存器28672
plc1.write_registers(28672, swapped_registers, functioncode=6)

这样就能得到你预期的结果:寄存器28672为十进制-5767(十六进制42F6),寄存器28673为十进制17142(十六进制E979)。

二、解决写入负数寄存器的报错问题

你用write_register写负数时报错,是因为该方法默认使用无符号16位整数格式(>H),负数超出了无符号范围。要写入负数对应的寄存器值,需要先把负数转换为16位有符号整数对应的无符号补码:

比如要写入-5767,转换逻辑如下:

negative_val = -5767
# 转换为16位无符号补码(等效于负数 + 65536)
unsigned_val = negative_val & 0xFFFF
# 现在可以正常写入寄存器
plc1.write_register(28676, unsigned_val, functioncode=6)

原理是:16位有符号整数的范围是-32768到32767,负数的补码可以通过与0xFFFF按位与得到,这样得到的无符号值就能被write_register正确处理。

额外提示

如果不想每次手动处理,也可以修改Minimal Modbus的write_float方法字节序逻辑,但手动拆分交换的方式更稳妥,避免修改库源码带来的后续维护问题。

内容的提问来源于stack exchange,提问作者user3005949

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:09:31