[STM32U5]【NUCLEO-U5A5ZJ-Q测评】驱动DFRobot 24灯珠炫彩灯环带你穿越时空之门

本文详细介绍了在NUCLEO-U5A5ZJ-Q开发板上使用WS2812B灯环的实验,包括硬件配置、驱动适配、基本测试以及如何根据简谱控制灯珠点亮,展示了编程控制LED灯珠和色彩的实践过程。
摘要由CSDN通过智能技术生成

本篇文章,分享了在 NUCLEO-U5A5ZJ-Q 开发板上,使用WS2812B 炫彩灯环的经验,展示的效果,包括按照顺序亮灭灯环上的灯珠,已经根据简谱点亮对应数量的灯珠。

一、硬件了解
炫彩灯带是一种非常常见的LED灯带,一般有5050灯带、WS28系列灯带(WS2801、WS2812、WS2813、WS2815和WS2818),在日常要使用灯光效果的场合,应用非常的多。
 



其中WS2812是最常见的一种,可以编程控制每一颗灯珠的亮灭,以及不同的颜色。

我手头有WS2812的灯板(1、2、4、8*8)、灯带(60、92)、灯环(24),其中24灯珠的灯环最常用:
 


我给这个灯环配了一个时空之门的底座,科幻感十足,当灯环上的灯珠亮起来的时候,仿佛开启了时空之门。


这是一款DFRobot出品的灯环,其参数如下:

工作电压:3.3~5V
最大工作电流:<100mA
接口类型:PH2.0-3P
灯珠型号:WS2812
灯珠数量:24
颜色:1600万色


要控制WS2812,除了供电以外,只需要1根数据信号线,即可控制所有的灯珠,非常的方便。
关于WS2812的具体控制原理,可以参考我的文章:【GD32F427开发板试用】点亮WS2812B炫彩灯环,里面详细讲述了灯环的电路原理和灯珠和颜色控制的原理。

在咱们 NUCLEO-U5A5ZJ-Q 开发板 开发板上,可与使用SPI的方式进行控制,将其信号线,连接到开发板的Arduino兼容接口的MOSI即可:
 



具体连接如下:
 



如果有多个这样的灯环,那灯环直接,还可以串联起来使用:
 




不过,需要注意的是,如果控制的灯珠较多,那么务必需要使用外部供电。
通常情况下,1颗灯珠,1种颜色,需要20mA电流,白色需要60mA电流,控制100颗,就需要最大6A电流。

二、驱动适配
在Zephyr中,提供了ws2812B的处理,但是没有提供咱们NUCLEO-U5A5ZJ-Q 开发板对应的处理定义,需要自己处理适配一下。
文件1:samples/drivers/led_ws2812/boards/nucleo_u5a5zj_q.conf

复制

CONFIG_WS2812_STRIP_SPI=y

CONFIG_SPI=y

这个文件定义了使用SPI,以及使用SPI控制WS2812。

文件2:samples/drivers/led_ws2812/boards/nucleo_u5a5zj_q.overlay:

复制

/*

 * Copyright (c) 2022, STMicroelectronics

 *

 * SPDX-License-Identifier: Apache-2.0

 */



#include <zephyr/dt-bindings/led/led.h>



&arduino_spi {

        led_strip: ws2812[url=home.php?mod=space&uid=2514928]@0[/url] {

                compatible = "worldsemi,ws2812-spi";



                /* SPI */

                reg = <0>; /* ignored, but necessary for SPI bindings */

                spi-max-frequency = <DT_FREQ_M(4)>;

                frame-format = <32768>; /* SPI_FRAME_FORMAT_TI */



                /* WS2812 */

                chain-length = <24>; /* arbitrary; change at will */

                spi-one-frame = <0x70>;

                spi-zero-frame = <0x40>;

                color-mapping = <LED_COLOR_ID_GREEN

                                 LED_COLOR_ID_RED

                                 LED_COLOR_ID_BLUE>;

        };

};



/ {

        aliases {

                led-strip = &led_strip;

        };

};


这个文件定义了基于arduio_spi的led-strip设备,使用4MHz通信速率,灯珠数量24颗,颜色对应关系为GRB。
对,就是GRB,WS2812就是这样定义颜色的:
 



三、基础测试
在Zephyr中,提供了ws2812的基础实例:samples/drivers/led_ws2812
其中main.c内容如下:

复制

/*

 * Copyright (c) 2017 Linaro Limited

 * Copyright (c) 2018 Intel Corporation

 *

 * SPDX-License-Identifier: Apache-2.0

 */



#include <errno.h>

#include <string.h>



#define LOG_LEVEL 4

#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(main);



#include <zephyr/kernel.h>

#include <zephyr/drivers/led_strip.h>

#include <zephyr/device.h>

#include <zephyr/drivers/spi.h>

#include <zephyr/sys/util.h>



#define STRIP_NODE                DT_ALIAS(led_strip)

#define STRIP_NUM_PIXELS        DT_PROP(DT_ALIAS(led_strip), chain_length)



#define DELAY_TIME K_MSEC(CONFIG_SAMPLE_LED_UPDATE_DELAY)



#define RGB(_r, _g, _b) { .r = (_r), .g = (_g), .b = (_b) }



static const struct led_rgb colors[] = {

        RGB(0x0f, 0x00, 0x00), /* red */

        RGB(0x00, 0x0f, 0x00), /* green */

        RGB(0x00, 0x00, 0x0f), /* blue */

};



struct led_rgb pixels[STRIP_NUM_PIXELS];



static const struct device *const strip = DEVICE_DT_GET(STRIP_NODE);



int main(void)

{

        size_t cursor = 0, color = 0;

        int rc;



        if (device_is_ready(strip)) {

                LOG_INF("Found LED strip device %s", strip->name);

        } else {

                LOG_ERR("LED strip device %s is not ready", strip->name);

                return 0;

        }



        LOG_INF("Displaying pattern on strip");

        while (1) {

                memset(&pixels, 0x00, sizeof(pixels));

                memcpy(&pixels[cursor], &colors[color], sizeof(struct led_rgb));

                rc = led_strip_update_rgb(strip, pixels, STRIP_NUM_PIXELS);



                if (rc) {

                        LOG_ERR("couldn't update strip: %d", rc);

                }



                cursor++;

                if (cursor >= STRIP_NUM_PIXELS) {

                        cursor = 0;

                        color++;

                        if (color == ARRAY_SIZE(colors)) {

                                color = 0;

                        }

                }



                k_sleep(DELAY_TIME);

        }



        return 0;

}



这个代码的逻辑如下:
1. 定义了一个 colors ,用于灯珠显示的颜色定义
2. 定义了一个 pixels ,用于存放每颗灯珠的颜色数据
3. while循环过程中,cursor用于指向下一颗要点亮的灯珠,如果打倒了最大值,则从第一颗重新点亮
4. while循环过程中,没循环一遍灯珠,就指向下一个定义的颜色,如果颜色循环完了,则从头开始。
5. 使用 led_strip_update_rgb(strip, pixels, STRIP_NUM_PIXELS) 来更新灯珠的颜色,也就是通过SPI发送数据到WS2812。

编译下载后,具体的运行效果如下:



四、根据简谱控制灯珠点亮
在上面的基础测试中,是依次点亮灯珠。
下面,就根据《小星星》的简谱,来实现根据简谱点亮对应的灯珠。
首先,在代码中,添加一个颜色定义:

复制

static const struct led_rgb num_colors[] = {

        RGB(0x00, 0x00, 0x00), /* black */

        RGB(0x0f, 0x00, 0x00), /* red */

        RGB(0x00, 0x0f, 0x00), /* green */

        RGB(0x00, 0x00, 0x0f), /* blue */



        RGB(0x0f, 0x0f, 0x00), /* ?? */

        RGB(0x00, 0x0f, 0x0f), /* ?? */

        RGB(0x0f, 0x00, 0x0f), /* ?? */

        RGB(0x0f, 0x0f, 0x0f), /* white */

};

实际的颜色,大家可以对照RGB颜色表来取值。

再添加一个曲谱的定义:
 

复制

uint8_t nums[] = {1,1,5,5,6,6,5,0,4,4,3,3,2,2,1,0,5,5,4,4,3,3,2,0,5,5,4,4,3,3,2,0,1,1,5,5,6,6,5,0,4,4,3,3,2,2,1};



然后,把while循环替换为:

复制

        while(1) {

                memset(&pixels, 0x00, sizeof(pixels));

                for(int i=0;i<nums[cursor];i++) {

                        memcpy(&pixels[i], &num_colors[nums[cursor]], sizeof(struct led_rgb));

                }

                rc = led_strip_update_rgb(strip, pixels, STRIP_NUM_PIXELS);



                if (rc) {

                        LOG_ERR("couldn't update strip: %d", rc);

                }



                cursor++;

                if (cursor >= sizeof(nums)/sizeof(nums[0])) {

                        cursor = 0;

                }



                k_sleep(K_MSEC(500));

        }



上述代码,就是通过循环简谱的每一位,来确定要点亮的灯珠数量,控制pixels 中灯珠的颜色。具体的颜色,再根据要控制的数量,从 num_colors 中取值。

编译下载后,运行效果如下:
 



五、总结
WS2812的控制,是一件非常有意思的事情,了解其原理也是一件非常值得学习的事情。
在 NUCLEO-U5A5ZJ-Q 开发板 上使用WS2812,也是一件非常简单方便的事情。
如果感兴趣的话,还可以和音乐播放等结合起来,达到更好的效果。。
---------------------
作者:HonestQiao
链接:https://bbs.21ic.com/icview-3347060-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值