合宙air780E解决适配ws2812b灯带发送错误问题

Posted on 2024-08-01 17:51  逍遥蓝枫叶  阅读(27)  评论(0编辑  收藏  举报

最近使用合宙air780E通过gpio口直驱ws2812b灯带,使用luatos开发,系统自带外设库

sensor.ws2812b(pin,data,T0H,T0L,T1H,T1L) 

详细接口文档见官方文档:luatos接口外设库文档

上测试代码:

--led灯条展示

local this = {}

local gpioId = 24 --输出gpio引脚
local timeDelay = 2000 --灯光刷新间隔 闪动间隔

local cfg = {} --led灯状态
local color = { --GRB
    red = 0x00b400, --红色 故障
    blue = 0x0000b4, --蓝色 空闲
    green = 0xb40000, --绿色 充电中/充满
    orange = 0x609600, --橙色 插枪时颜色
    close = 0x000000, --关灯
    pink = 0x00b4b4, --粉红色 急停按下 闪动
}

--1-电源指示灯状态 0/100-故障 红灯 1-正常
--2-灯珠状态 0-熄灭 1-点亮
local powerState = {
    state = 100, --电源指示灯状态 0-熄灭 1-正常 绿常亮 100-故障 红闪
    light = 0, --灯珠状态  0-熄灭 1-点亮
}

local light=0 --闪动灯珠统一的状态  0-熄灭 1-点亮


--led灯光存储zbuff x=4*y=3 二维数组
local buff = zbuff.create({ 4, 3, 24 }, color.red)  --x=4,y=3

for i = 1, rxConfig.get("portCount") do
    cfg[i] = {
        state = 100, --状态 0空闲(蓝闪)、1充电中(绿闪)、3已插枪(黄闪)、4急停按下(红闪)、5充电完成(绿色常亮) 100-故障/异常/超功率(红闪)
        light = 0, --灯珠状态  0-熄灭 1-点亮
    }
end

gpio.setup(gpioId, 1)
gpio.set(gpioId, 0)
--pwm.open(1, 800*1000, 50,1)
--ws2812.create(ws2812.PWM, 12, 1)



--向led总线发送数据
local function sendData()
    sensor.ws2812b(gpioId, buff, 10, 0, 10, 300)
    --sensor.ws2812b_pwm(1,buff)
    --for i=0,11 do
    --    pwm.open(0, 800*1000,buff[i],8)
    --end

end

--延迟100毫秒显示默认红灯状态
sys.timerStart(function()
    sendData()
end, 100)

--设置某行灯珠颜色
--i 1-A枪指示灯 2-系统指示灯 3-B枪指示灯
--c 颜色
local function setColor(i, c)
    buff:drawLine(0, i - 1, 4, i - 1, c)  --绿
end

--设置指定接口灯珠的led颜色
--port 1-10接口id  100-电源指示灯
local function setPortLed(port, c)
    if port == 100 then
        setColor(2, c)
    elseif port == 1 then
        setColor(1, c)
    elseif port == 2 then
        setColor(3, c)
    end
end

--获取指定接口状态的颜色和事件 1 2接口号  100电源指示灯
--return 颜色,事件 1-常亮 2-闪动
local function getStateData(port)
    if port < 10 and cfg[port] == nil then
        return nil
    end
    --电源指示灯处理
    if port == 100 then
        local state = powerState.state
        if state == 0 then
            return color.close, 1
        elseif state == 1 then
            return color.blue, 1
        else
            return color.red, 2
        end
        --return 0, 0
    end

    local state = cfg[port].state
    if state == 0 then
        --空闲 蓝色 闪动
        return color.blue, 2
    elseif state == 1 then
        --充电中 绿色 闪动
        return color.green, 2
    elseif state == 3 then
        --插枪 橙色 闪动
        return color.orange, 2
    elseif state == 4 then
        --急停按下 粉红色 闪动
        return color.pink, 2
    elseif state == 5 then
        return color.green, 1
    else
        return color.red, 2
    end
end


--设置指定接口灯的状态
local function setState(port, state)
    if cfg[port]==nil then
        return
    end

    log.info("rx_led.lua.setState:port,state=",port,state)
    cfg[port].state = state
end

--led灯带处理事件
local function ledEvent()
    --处理电源指示灯
    local powerColor, s = getStateData(100)
    if s == 1 then
        --常亮处理
        setPortLed(100, powerColor)
        powerState.light = 1
    else
        --闪动处理
        if powerState.light == 0 then
            --当前熄灭处理
            setPortLed(100, powerColor)
            powerState.light = 1
        else
            --当前亮灯处理
            setPortLed(100, color.close)
            powerState.light = 0
        end
    end

    --处理各接口指示灯
    for k, v in pairs(cfg) do
        local c, s = getStateData(k) --获取灯的状态和颜色
        if c ~= nil then
            --local light=0
            --if k==1 then
            --    light=cfg[k].light
            --end

            if s == 1 then
                --常亮处理
                setPortLed(k, c)
                cfg[k].light = 1
            else
                --2和其他 闪动处理
                if light == 0 then
                    setPortLed(k, c)
                    cfg[k].light = 1
                    --light=1
                else
                    setPortLed(k, color.close)
                    cfg[k].light = 0
                    --light=0
                end
            end
        end
    end

    if light==0 then
        light=1
    else
        light=0
    end

    sendData()
    --sys.timerStart(ledEvent, timeDelay)
end

local function ledEventLoop()
    sys.taskInit(function()
        while true do
            ledEvent()
            sys.wait(timeDelay)
        end
    end)

end

ledEventLoop()

--其他业务事件代码省略

return this

 

正常灯带应该全部闪红色,但是经过测试,每间隔几秒就会出现几个灯错误颜色或者灭后个别亮起,当插在电脑usb上的时候,基本不会出现问题,本来以为是电源不稳定的,后来经过合宙官方技术支持提醒,问题存在在:

1.4g通讯类芯片,网络通讯优先级最高,可能在给灯带发送数据时,被更高优先级的网络底层通讯占用时间片

2.如果插usb正常,拔掉usb不正常,可以关闭uart0的debug日志尝试解决

 

我们先关闭uart0的日志尝试,问题就解决了,分享以下关闭uart0日志的方式:

 

需要登录合宙luatos构建平台,https://www.luatos.com/

登录后点击右上角的构建功能

新建构建,模块类型选择 EC618-luatos.

在功能模块选择中,找到"释放UART0供用户使用.不能从UART0读取底层日志了,只能通过USB读取日志"选项,选中

在选择其他需要的功能模块,构建后选择该底层固件进行尝试,问题就解决了

Copyright © 2024 逍遥蓝枫叶
Powered by .NET 8.0 on Kubernetes