struct.error: 'H' format requires 0 <= number <= 65535
全部代码如下:
from pymodbus.client import ModbusTcpClient
# 避坑:write_registers和write_register函数差一个s。多一个s的参数用整型列表,没有的只能用整型
def split_float_to_integer_and_fraction_parts(number):
"""
将浮点数拆分为整数部分和小数部分的函数
"""
integer_part = int(number)
fraction_part = int((number - integer_part) * 10000) # 将小数部分转换为整数
print(integer_part, "和", fraction_part)
# 将负值转换为无符号整数
# 将负值转换为无符号整数
if number < 0:
integer_part = 65536 + integer_part
fraction_part = 65536 + fraction_part
return integer_part, fraction_part
def send_coordinates_to_robot(coordinates, encoder_value, host_ip='192.168.0.11', host_port=502):
"""
将坐标发送给机器人的函数
"""
# 分解编码器值
result = None
# print(encoder_value,"encoder_value")
h4_encoder_integer_part = abs(int(encoder_value / 10000))
l4_encoder_integer_part = abs(int(encoder_value - h4_encoder_integer_part * 10000))
encoder_fraction_part = abs(int((encoder_value - int(encoder_value)) * 1000))
# 创建并连接到Modbus服务器
client = ModbusTcpClient(host_ip, port=host_port)
connection = client.connect()
if connection:
result = "成功连接到Modbus服务器。"
else:
return "无法连接到Modbus服务器。"
# 准备用于保存 坐标 -> 寄存器值 的列表
register_coord = []
# 准备用于保存 传送带编码值 -> 寄存器值 的列表
register_encoder = []
# 固定结束位
end = 1
# 依次写入坐标寄存器和工件属性寄存器
# x->(102.103) y->(104.105) z->(106.107) c->(108.109)
for i, (key, coordinate) in enumerate(coordinates.items()):
# 跳过"AREA"和"ID"字段
if key not in ["x", "y", "z", "c", "ATTR"]:
continue
# 坐标
if key in ["x", "y", "z", "c"]:
coord_integer_part, coord_fraction_part = split_float_to_integer_and_fraction_parts(coordinate)
register_coord.extend([coord_integer_part, coord_fraction_part])
# 传送带不在寄存器连续区间
# 物料属性
if key == "ATTR":
register_coord.append(coordinate)
# 写入编码器值寄存器:整数高4位,整数低4位,小数4位
register_encoder.extend([h4_encoder_integer_part, l4_encoder_integer_part, encoder_fraction_part])
print(register_coord)
print(register_encoder)
# 从102开始写到109,坐标+工件属性
response1 = client.write_registers(102, register_coord, slave=1)
# 从124开始写到126,编码器值
response2 = client.write_registers(124, register_encoder, slave=1)
# 在111写入结束位1
response3 = client.write_register(111, end, slave=1)
if response1.isError() or response2.isError():
result += "写入寄存器失败"
elif response3.isError():
result += "写入结束位失败"
else:
result += "成功写入寄存器,并发送物料信息至机器人"
# 关闭连接
client.close()
# 返回一条消息,表示操作已完成
return result
send_coordinates_to_robot({
'x': -2215,
'y': -5,
'z': -812.66,
'c': 23.4038,
'ATTR': 2,
}, 0)
调试:
输出:
为什么我小数大于零还进入了if分支???
我以为是Python有-0的问题,给我惊呆了,居然有负0。
x = -0
print(x)
if x == 0:
print("x==0,加1后:", x + 1)
elif x < 0:
print("x<0,加1后:", x + 1)
elif x > 0:
print("x>0,加1后:", x + 1)
说明不是负0的问题。
然后我最后才发现,用来判断的数不是我分解后的数。
这是原来的:
if number < 0:
integer_part = 65536 + integer_part
fraction_part = 65536 + fraction_part
修改后,应该分别判断他们是不是小于0
# 将负值转换为无符号整数
if integer_part < 0:
print("加之前:", fraction_part)
integer_part = 65536 + integer_part
if fraction_part < 0:
fraction_part = 65536 + fraction_part
这是上一个人给我遗留的代码,真的难找。