
在昆仑通态触摸屏中,希望在对话框输入带符号小数,机器人对应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