CS modbus/TCP读写数据时,默认每个寄存器16位,机器人读取到的数据为16位的无符号数(0-65535)
若外部设备(例如PLC)通过modbus/TCP向机器人写入浮点数(使用2个寄存器,共32位),机器人如何读取?
以下举例,PLC向机器人的寄存器地址256和257一共两个寄存器,写入浮点数。
1. 在机器人中创建m256(对应地址256,类型位寄存器输出)和m257(对应地址256,类型位寄存器输出)

2. 在modbus poll软件中,连接机器人,并使用功能吗16对多寄存器进行读写。Display类型选择为float CD AB。此时往256寄存器写入数值1.0

机器人运行脚本(其中modbus_float.script代码如文末),机器人可以正确读取到modbus 发来的浮点数1.0
若使用西门子PLC基于modbus 发送浮点数,以下程序中写为: var_1:=getModbusFloat('m257','m256')(即西门子的高word和低word为大端,机器人使用时反一下)

modbus_float.script代码如下:
import struct
def Bytes2Float(d,BigEndian=False):
# 输入4个字节数据,转化为对应的32位的实数,默认使用小端编码,使用大端编码添加参数BigEndian为True
if BigEndian ==True:
return struct.unpack('<f', struct.pack('4B', *d))[0]
else:
return struct.unpack('>f', struct.pack('4B', *d))[0]
def Bytes2Int32(d,BigEndian=False):
# 输入4个字节数据,转化为对应的32位的带符号整数,默认使用小端编码,使用大端编码添加参数BigEndian为True
if BigEndian ==True:
return struct.unpack('<i', struct.pack('4B', *d))[0]
else:
return struct.unpack('>i', struct.pack('4B', *d))[0]
def Bytes2Int16(d,BigEndian=False):
# 输入2个字节数据,转化为对应的16位的带符号整数,默认使用小端编码,使用大端编码添加参数BigEndian为True
if BigEndian ==True:
return struct.unpack('<h', struct.pack('2B', *d))[0]
else:
return struct.unpack('>h', struct.pack('2B', *d))[0]
def Float2Bytes(d,BigEndian=False):
# 输入32位的实数,转化位对应4个字节数据,默认使用小端编码,使用大端编码添加参数BigEndian为True
if BigEndian ==True:
return list(struct.unpack('4B',struct.pack('f',d)))
else:
return list(struct.unpack('4B',struct.pack('>f',d)))
def Int322Bytes(d,BigEndian=False):
# 输入32位带符号整数,转化位对应4个字节数据,默认使用小端编码,使用大端编码添加参数BigEndian为True
if BigEndian ==True:
return list(struct.unpack('4B',struct.pack('<i',d)))
else:
return list(struct.unpack('4B',struct.pack('>i',d)))
def Int162Bytes(d,BigEndian=False):
# 输入16位带符号整数,转化位对应2个字节数据,默认使用小端编码,使用大端编码添加参数BigEndian为True
if BigEndian ==True:
return list(struct.unpack('2B',struct.pack('<h',d)))
else:
return list(struct.unpack('2B',struct.pack('>h',d)))
def getModbusFloat(m_low,m_high):
# 将m_low和m_high 两个寄存器地址的数据读入,m_low和m_high为modbus变量名
# m_low存储的是低word的数据,m_high存储的是高word的数据,
# 即格式为CD,AB
low = modbus_get_signal_status(m_low)
high = modbus_get_signal_status(m_high)
d= [high>>8,high&255,low>>8,low&255]
return Bytes2Float(d)
def setModbusFloat(data,m_low,m_high):
# 将浮点数,拆分成2个无符号16bit数据 word,低word存入m_low, 高word存入m_high
# 数据格式CD,AB
# 即:m_low:AB
# m_high: CD
d = Float2Bytes(data)
low = d[2]*256+d[3]
high = d[0]*256+d[1]
modbus_set_output_register(m_low, low)
modbus_set_output_register(m_high, high)机器人也可以对modbus的2个连续寄存器写入浮点数,plc从这2个连续寄存器读取浮点数,具体如下:
假设机器人写入258和259两个寄存器(在配置中新建2个寄存器变量)
modbus poll软件中,功能码修改为03 read holding register,display类型依旧为float CD AB

机器人使用setModbusFloat(2.8,'m258','m259')写入寄存器,可以看到modbus poll可以读取到浮点数结果2.8.
如果上位机为西门子plc,机器人使用setModbusFloat(2.8,'m259','m258')来解决西门子高word和低word颠倒问题