在昆仑通态触摸屏中,希望在对话框输入带符号小数,机器人对应D变量能接收到,例如上图。
可以采用两种方式:
方式一: 触摸屏设置读写寄存器为16位 有符号二进制,同时在“通道处理”中,将实际带小数点数据放大为整数,例如输入-1000.0~1000.0,放大为-10000~10000. 在lua中,将收到的寄存器数据(默认解析为无符号数)转为对应的有符号数,并乘以放大缩小系数。例如使用以下代码中的SetDvarfromReg(D变量名字,寄存器地址,比例系数)。 上图的行间距输入框对应D020变量采用这种方式。
方式二:触摸屏设置读写寄存器为32位 浮点数,地址为2个寄存器中的低地址,同时在设置界面,设置32位浮点字节序为2-3412(即2个寄存器顺序交换)。
在lua中,将收到的2个寄存器数据转为对应的浮点数。例如使用以下代码中的SetDvarfromReg2(D变量名字,寄存器地址)。 文首的列间距输入框对应D021变量采用这种方式。
-- Author: chenliao@elibot.cn -- Apr.26, 2023 function SetDvarfromReg(D, reg, ratio) -- D为D变量名字的字符串,例如'D020' -- 读取地址为reg的一个16位寄存器,读入数据为无符号数, -- 输出对应的有符号数据*ratio local data = get_robot_extra_register(reg) if ratio == nil then ratio = 1 end if (data ~= 0) then -- 如果触摸屏输入不等于0,则接受触摸屏输入数据 -- 触摸屏配置为有符号数据,如果有小数,先乘以倍率放大到整数,例如10.1,实际触摸屏发送101 local d = string.pack("I2", data) d = string.unpack("i2", d) set_global_variable(D, d * ratio) else -- 如果触摸屏输入等于0,则将机器人当前数据写入触摸屏 out = Int2StrHex(math.floor(get_global_variable(D) / ratio)) set_robot_extra_register(reg, 2, out) end end function SetDvarfromReg2(D, reg) -- D为D变量名字的字符串,例如'D021' -- 读取地址为reg开始的连续2个寄存器(共32位)寄存器,读入数据为无符号数,转换为浮点数 -- 触摸屏对应数据格式设置为浮点数 local data_low = get_robot_extra_register(reg) local data_high = get_robot_extra_register(reg + 1) local data = (data_high << 16) | data_low data = string.pack("I4", data) data = string.unpack("f", data) if (data ~= 0) then -- 如果触摸屏输入不等于0,则接受触摸屏输入数据 -- 触摸屏配置为32bit 浮点数 set_global_variable(D, data) else -- 如果触摸屏输入等于0,则将机器人当前数据写入触摸屏 out = Float2StrHex(get_global_variable(D)) set_robot_extra_register(reg, 4, out) end end function Int2StrHex(data, BigEndian) -- 输入16位的带符号整数,输出转为16进制数据的字符串形式 -- 默认小端编码,若要使用大端编码,使用BigEndian out = string.pack("i2", data) if (BigEndian == nil) then out = string.unpack(">I2", out) else out = string.unpack("<I2", out) end return string.upper(string.format("%04x", out)) end function Float2StrHex(data, BigEndian) -- 输入浮点数,输出转为16进制数据的字符串形式 -- 默认小端编码,若要使用大端编码,使用BigEndian out = string.pack("f", data) if (BigEndian == nil) then out = string.unpack(">I", out) else out = string.unpack("<I", out) end return string.upper(string.format("%08x", out)) end while true do -- 机器人地址309,对应昆仑通态的310地址 SetDvarfromReg("D020", 309, 0.1) -- 行间距,对应D20 SetDvarfromReg2("D021", 310) -- 列间距,对应D21 sleep(0.1) end