机器人串口通信
掌握乐白机器人机器人串口通信,助您快速进入开发状态,高效实现机器人控制与应用开发
Lebai Api 串口通信
打开串口设备
com = serial.open(path)
默认使用 波特率115200、 8 位数据位、1 位停止位、无检验位,如需更改请联系我们。
- 参数
path
。串口设备地址。
返回串口实例 或 抛出错误。
设置超时时间
com:set_timeout(timeout)
- 参数
timeout
超时时间,单位毫秒(ms)。默认800ms
设置波特率
com:set_baud_rate(baud_rate)
设置串口波特率
- 参数
baud_rate
。串口波特率。默认115200
返回空 或 抛出连接错误
设置奇偶校验位
com:set_parity(parity)
设置奇偶校验位
- 参数
parity
。奇偶校验位(None: 无奇偶校验; Odd: 奇校验; Even: 偶校验)。默认无奇偶校验位
返回空 或 抛出连接错误
发送数据
com:write(data)
通过串口发送u8数组
- 参数
data
。待发送的u8数组。
返回空 或 抛出连接错误
接收数据
data = com:read(len)
通过串口接收u8数组
- 参数
len
。单次接收的最大缓冲长度,可空,默认64字节。
返回u8数组 或 抛出连接错误
示例
local com1 = serial.open("/dev/ttyS1")
com1:set_timeout(200)
com1:set_baud_rate(9600)
local str = "123"
com1:write({string.byte(str, 1, #str)}) -- 发送字符串
com1:write({0x01, 0x02, 0x03}) -- 发送HEX
-- 读取串口,使用pcall捕获错误
success, result = pcall(function() return com1:read() end)
if success then
print(result) -- 打印HEX
print(string.char(table.unpack(result))) -- 打印字符串
else
print("Error: ", result)
end
-- 读取串口,由于未捕获错误,当发生错误时,任务异常退出
local data = com1:read()
print(data) -- 打印HEX
print(string.char(table.unpack(data))) -- 打印字符串
com1 = serial.open("/dev/ttyS1")
com1:set_timeout(0)
com1:set_baud_rate(9600)
-- 将字节流转换为16进制表示
function table2Hex(s)
rst = ''
for i = 1, #s do
rst = rst .. string.format('0x%02X ', s[i])
-- print(s[i])
end
return rst
end
function recv_data()
-- 读取串口,使用pcall捕获错误
success, result = pcall(function() return com1:read() end)
if success then
print(table2Hex(result)) -- 打印HEX
local data = string.char(table.unpack(result))
return data
else
print("Error: ", result)
end
end
while true
do
data = recv_data()
if(data == "1")
then
movej({j1 = 0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0}, 0.1, 0.1, 0, 0)
sync() -- 等待运动结束
set_claw(100,100)
local str = "finish 1"
com1:write({string.byte(str, 1, #str)}) -- 发送字符串
elseif(data == "2")
then
scene(10001) -- 执行场景
set_claw(100,0)
local str = "finish 2"
com1:write({string.byte(str, 1, #str)}) -- 发送字符串
else
print("unknown data:", data)
end
end
串口通讯制冰机协议案例
--crc校验函数 参数为数据字符串
function Crc16(buf)
local init = 0xFFFF
local poly = 0xA001
local ret = init
local byte=0
for j=1,#buf,1 do
byte = string.byte(buf,j)
ret=((ret ~ byte) & 0xFFFF)
for i=1,8,1 do
if((ret & 0x0001)>0) then
ret = (ret >> 1)
ret = ((ret ~ poly) & 0xFFFF)
else
ret= (ret >> 1)
end
end
end
local hi = ((ret >> 8) & 0xFF)
local lo = (ret & 0xFF)
ret = ((lo << 8) | hi)
return ret
end
local com1 = serial.open("/dev/ttyS0") ---串口选择232的port
com1:set_timeout(300) --读取超时时间
com1:set_baud_rate(9600) --设置波特率
com1:set_parity("None") --None: 无奇偶校验
--发送命令到串口的函数
function Send_Cmd_to_com(cmd)
-- print('cmd :',cmd)
com1:write(cmd) -- 发送相应命令
--循环读取直到读到数据校验完成返回数据,或者读取十次也未读到则终止返回false
for i = 1,3 do
wait(100)
-- 读取串口,使用pcall捕获错误
success, result = pcall(function() return com1:read() end)
-- print(success)
if success==true and result~=nil then
-- print('receive:',result) -- 打印HEX
crc_response = Crc16(string.char(table.unpack(result,1,#result-2)))
-- print('crc_response:',crc_response)
-- print( crc_response>>8 ,crc_response&0xFF)
if result[#result-1]crc_response>>8 and result[#result]crc_response&0xFF then
return result
end
end
end
return false
end
--出冰函数,参数为出冰时间,单位为0.1秒,例如输入40,则出冰4秒 返回true则出冰成功,返回false则出冰失败,返回其他则是发送命令或者通讯硬件问题
function Make_ice(out_ice_time)
if out_ice_time==nil then
out_ice_time=10
end
makeice_cmd = {0xA5,0x5A,0x01,0x02}
out_time= math.ceil(out_ice_time) --时间取整
table.insert(makeice_cmd, out_time&0xff00)
table.insert(makeice_cmd, out_time&0xff)
crc_result = Crc16(string.char(table.unpack(makeice_cmd))) --获得校验码
table.insert(makeice_cmd, crc_result>>8)
table.insert(makeice_cmd, crc_result&0xFF)
--发送出冰命令
make_ice_result= Send_Cmd_to_com(makeice_cmd)
if make_ice_result ~=false then
--正常命令的出冰返回结果
if #make_ice_result==8 then
status_code=table.unpack(make_ice_result,5,5)
if status_code==0 then --出冰成功
return true
else --出冰失败
return false
end
--错误命令导致的返回结果
elseif #make_ice_result==7 then
abnormal_code= table.unpack(make_ice_result,5,5)
if abnormal_code==0 then --位置错误导致出冰失败
return '未定义错误'
elseif abnormal_code==2 then --发送命令问题导致出冰失败
return '无法识别命令'
elseif abnormal_code==3 then --发送命令校验错误导致出冰失败
return 'CRC校验出错'
elseif abnormal_code==4 then --系统忙题导致出冰失败
return '系统忙'
end
end
else
--通讯故障
print('发送出冰命令时,与制冰机间的通讯异常')
return '通讯异常' --返回false 发送命令无返回值
end
end
--读取制冰机状态
function Read_machine_status()
read_status_cmd = {0xA5,0x5A,0x01,0x01,0x00,0x00,0x10,0xDF}
--发送读取状态命令
read_status_result= Send_Cmd_to_com(read_status_cmd)
--正常命令返回状态
if read_status_result ~=false then
if #read_status_result==8 then
machine_status_code= table.unpack(read_status_result,5,5)
error_code = table.unpack(read_status_result,6,6)
print('制冰机器状态码:', machine_status_code , ' 错误码:',error_code )
if machine_status_code==2 then
return '空闲待机'
elseif machine_status_code==3 then
return '出冰或出水中'
elseif machine_status_code==4 then
return '排冰'
elseif machine_status_code==5 then
if error_code==1 then
return '供水不足'
elseif error_code==2 then
return '制冰机内部温度过低'
elseif error_code==3 then
return '制冰机内部温度过高'
elseif error_code==4 then
return '压缩机温度过高'
elseif error_code==5 then
return '排气孔温度过低'
elseif error_code==6 then
return '电机电流过大'
elseif error_code==7 then
return '通讯异常'
elseif error_code==8 then
return '数据存储出错'
elseif error_code==9 then
return '电机堵转'
elseif error_code==10 then
return '电机警告'
end
elseif machine_status_code==6 then
return '清洗'
elseif machine_status_code1 or machine_status_code0 then
return '上电初始化中'
elseif machine_status_code==7 then
return '等待取冰'
end
--非正常命令返回状态
elseif #read_status_result==7 then
abnormal_code= table.unpack(read_status_result,5,5)
if abnormal_code==0 then
return '未定义错误'
elseif abnormal_code==2 then
return '无法识别命令'
elseif abnormal_code==3 then
return 'CRC校验出错'
elseif abnormal_code==4 then
return '系统忙'
end
end
--通讯故障无返回值
else
print('读取制冰机状态时,与制冰机的通讯异常' )
return '通讯异常'
end
return false
end
--检查冰桶状态
function Read_icebucket_status()
read_icebucket_cmd = {0xA5,0x5A,0x01,0x03,0x00,0x00,0xB1,0x1F}
--发送读取状态命令
read_icebucket_result= Send_Cmd_to_com(read_icebucket_cmd)
--正常命令返回状态
if read_icebucket_result~=false then
if #read_icebucket_result==8 then
icebucket_status_code= table.unpack(read_icebucket_result,5,5)
if icebucket_status_code==1 then
return '冰桶满'
else
return '冰未满'
end
--非正常命令返回状态
elseif #read_icebucket_result==7 then
icebucket_abnormal_code= table.unpack(read_icebucket_result,5,5)
if icebucket_abnormal_code==0 then
return '未定义错误'
elseif icebucket_abnormal_code==2 then
return '无法识别命令'
elseif icebucket_abnormal_code==3 then
return 'CRC校验出错'
elseif icebucket_abnormal_code==4 then
return '系统忙'
end
end
--通讯故障无返回值
else
print('读取冰桶状态时,与制冰机的通讯异常' )
return '通讯异常'
end
return false
end
print(Make_ice(10))
print(Read_machine_status())
print(Read_icebucket_status())
Lebai SDK 串口通信
设置超时时间
lebai:set_serial_timeout(device, timeout)
- 参数
device
设备名称timeout
超时时间,单位毫秒(ms)。默认800ms
设置波特率
lebai:set_serial_baud_rate(device, baud_rate)
设置串口波特率
- 参数
device
设备名称baud_rate
。串口波特率。默认115200
返回空 或 抛出连接错误
设置奇偶校验位
lebai:set_serial_parity(device, parity)
设置奇偶校验位
- 参数
device
设备名称parity
。奇偶校验位(None: 无奇偶校验; Odd: 奇校验; Even: 偶校验)。默认无奇偶校验位
返回空 或 抛出连接错误
发送数据
lebai:write_serial(device, data)
通过串口发送u8数组
- 参数
device
设备名称data
。待发送的u8数组。
返回空 或 抛出连接错误
接收数据
data = lebai:read_serial(device, len)
通过串口接收u8数组
- 参数
device
设备名称len
。单次接收的最大缓冲长度,可空,默认64字节。
返回u8数组 或 抛出连接错误
示例
local device = "/dev/ttyS1"
lebai:set_serial_baud_rate(device, 9600)
local str = "123"
lebai:write_serial(device, {string.byte(str, 1, #str)}) -- 发送字符串
lebai:write_serial(device, {0x01, 0x02, 0x03}) -- 发送HEX
local data = lebai:read_serial(device)
print(data) -- 打印HEX
print(string.char(table.unpack(data))) -- 打印字符串
机箱Modbus案例
-- 使用Modbus/RTU
local com1 = serial.open("/dev/ttyS1")
com1:set_timeout(200)
com1:set_baud_rate(9600)
local mb = modbus.new_rtu(com1)
-- 配置Modbus
mb:set_timeout(500)
mb:set_slave(0x01)
-- 设置1路DO,使用pcall捕获错误
success, result = pcall(function() mb:write_single_coil(0x0000, true) end)
if not success then
print("Error: "..tostring(result))
else
print("Write successful")
end
-- 设置5路DO
success, result = pcall(function()
mb:write_multiple_coils(0x0000, {true,true,true,true,true})
end)
if not success then
print("Error: ", result)
else
print("Write successful")
end
-- 读取5路DO
success, result = pcall(function() return mb:read_coils(0x0000, 5) end)
if not success then
print("Error: ", result)
else
print(result)
end
法兰Modbus案例
-- 使用末端法兰Modbus 可以用于控制夹爪类的末端执行工具
local mb = modbus.new_flange() --因为法兰的串口地址是固定的,这里不需要像机箱modbus需要配置串口实例化
-- 配置Modbus
mb:set_timeout(500)
mb:set_slave(0x01)
mb:write_single_register(0x0600, 0x0032)
mb:read_input_registers(0x0601, 0x0064)
force = mb:read_input_registers(0x0600, 1)
print(force)
amplitude = mb:read_input_registers(0x0601, 1)
print(amplitude)