机器人串口通信

掌握乐白机器人机器人串口通信,助您快速进入开发状态,高效实现机器人控制与应用开发

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)