CS机器人基于modbus/TCP 读写浮点数

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颠倒问题

点击显示全文
赞同0
发表评论
分享

手机扫码分享
0
1.111K
收藏
举报
收起
登录
  • 密码登录
  • 验证码登录
还没有账号,立即注册
还没有账号,立即注册
注册
已有账号,立即登录
选择发帖板块
上传文件
举报
请选择举报理由
举报
举报说明