昉·星光系列课程14:昉·星光开发板炫彩灯环控制

昉·星光系列课程14:昉·星光开发板炫彩灯环控制

本次课程为昉·星光开发板IoT开发系列课程的第十四讲,将带领同学们在昉·星光开发板上,控制WS2812B炫彩灯环。
本次课程,在昉·星光开发板V1和V2上,操作步骤相同。

一、学习目标

  • 学习昉·星光开发板通过SPI输出,实现对WS2812B炫彩灯环的控制。

二、准备工作

在开始本次课程的实际操作之前,同学们需要做好一些准备工作,课程中涉及到的硬件如下:

  • 开发板:昉·星光开发板
  • 炫彩灯环:24灯珠WS2812B灯环
  • 杜邦线:若干

三、炫彩灯环使用原理

本次课程中,使用的炫彩灯环模块具体如下:

在灯环的接口上,除了VCC(+)和GND(-),还有DIN用于输出控制信号,DOUT用于传递信号给后续的灯珠。

所有基于WS2812B的灯环、点阵等,其使用原理都一样,连接上也都是一颗一颗串起来的:

WS2812B控制一颗灯珠,需要24bits的数据,代表着GRB三种颜色值:
4.WS2812B2B-1

而要控制多颗灯珠,则连续发送多组上述24bits的数据:

当然,发送上述的数据,需要按照一定的规格进行打包发送。具体的打包规则,可以查看 WS2812B版星际之门 了解。

在这片课程中,我们使用SPI接口,来发送WS2812B所需要的控制数据,从而实现24颗灯珠的炫彩灯环控制。

四、实物连线

首先,参考下图,将炫彩灯板连接到昉·星光开发板:

实物连接如下:

注意:
应根据实际使用的传感器,确定供电电压。本次课程中使用的模块使用5V供电电压。

五、代码编写

然后,我们编写如下的程序:

# -*- coding: utf-8 -*-
# file: ~/projects/spi/ws2812b_test.py

import time
from lib import neopixel_spidev as np
from lib.pixelbuf import wheel

with np.NeoPixelSpiDev(1, 0, n=24, pixel_order=np.GRB) as pixels:
    try:
        while True:
            print("整圈颜色变化效果:")
            pixels.fill((0,0,0))
            time.sleep(1)
            for i in range(0,255,2):
                print(" %d" % i, end="",flush=True)
                pixels.fill(wheel(i))
                time.sleep(0.01)

            print("")
            time.sleep(1)
            pixels.fill((0,0,0))
            time.sleep(1)

            print("依次点亮效果:")
            for i in range(pixels.n):
                print(" %d" % i, end="", flush=True)
                if i>0:
                    pixels[i-1] = (0,0,0)
                pixels[i] = wheel(128)
                time.sleep(0.1)

            print("")
            time.sleep(1)
            pixels.fill((0,0,0))
            time.sleep(1)

            print("数量变化效果:")
            colors = (
                (0,0,0),
                (128,0,0),
                (0,128,0),
                (0,0,128),
                (128,128,0),
                (128,0,128),
                (0,128,128),
                (128,128,128)
            )
            for n in (1,2,3,1,1,2,3,1,3,4,5,3,4,5,5,6,5,4,3,1,5,6,5,4,3,1,1,5,1,1,5,1):
                print("n=%d" % n, end="", flush=True)
                pixels.fill((0,0,0))
                time.sleep(0.1)
                for i in range(n*2):
                    print(" %d" % i, end="", flush=True)
                    pixels[i] = colors[n]
                time.sleep(0.4)
                print("")

            time.sleep(1)
            pixels.fill((0,0,0))
            time.sleep(1)

            time.sleep(5);
    except KeyboardInterrupt:
        pass

发送WS2812B的控制信号,需要特定结构的数据,我们可以在了解其原理后自己进行组装。在上述代码中,使用了 py-neopixel-spidev 这个扩展库,其通过开发板的SPI接口来输出控制信号给WS2812B。

代码中,一共进行了三种效果的演示:

  • 整个炫彩灯环颜色的变化,从(0,0,0) → (255,255,255)
  • 单个灯珠一次点亮
  • 根据两只老虎的简谱,每次点亮一定数量的灯珠,并根据简谱序号,从colors中选取对应的颜色

六、运行效果

要运行以上的程序,还需要安装相应的支持库,具体如下:

# 安装扩展库
git clone https://github.com/fschrempf/py-neopixel-spidev.git
cd py-neopixel-spidev
python setup.py build
sudo python setup.py install

编写完成后,运行 ws2812b_test.py,即可看到炫彩灯环的效果展示。

sudo python3 ws2812b_test.py

运行后,输出如下:

实际效果如下:

七、总结

在本次课程中,我们学习了控制WS2812B炫彩灯环。
WS2812B的应用场合非常多,广泛应用于城市夜景、灯光秀、广告柜、珠宝展示柜、玩具等。
在214或者520的时候,你也可以制作一个效果绚丽的心,送给心爱之人!

八、课后作业

  • 了解WS2812B使用原理
  • 学会控制WS2812B的颜色和灯珠
  • 了解相关音乐的知识,实现WS2812B配合音乐的效果呈现

九、参考资料

3 Likes

老师好,我在 VisionFive 1 和 VisionFive 2 上分别运行本课程的内容得到了不同的结果,希望老师能够指点一下:

VisionFive 1 上运行能够点亮灯环,但是和实际效果不一样。灯环颜色变化部分可以变色,但除了 IN 处的能够正常显示颜色之外,其余灯珠均偏白,显示白色灯光。在单个灯珠可见到单个灯珠在微微闪烁,但各个灯珠均显示偏白,显示白色灯光。一次点亮指定数量的灯珠时和单个灯珠并无什么区别。

本人分析,是否为供电的问题?我的供电器输出为 5V 3A,和您示例图中不一样未接小风扇。

VisionFive 2 上运行则直接报错 Segmentation fault,请教老师一下该如何排查相关问题,谢谢!

1 Like
  1. 你使用的灯环具体是哪一种?数量是多少?
  2. 灯珠数量可以先设置为1颗,然后控制看情况如何?
  3. 可能的话,给灯环单独供电试试
1 Like

感谢老师回复!

我使用的灯环应该和您一样: DFRobot WS2812-16 RGB LED Ring,并且是 24 灯珠的。

灯珠数量这个我还没有尝试,尝试之后再在这里回复;灯环单独供电请问该如何操作?本人小白一枚,还希望老师多多指点一下。

1 Like

再请教一下老师,我看到您的实物连接图两边的线颜色不一样,不知道您在镜头外做了什么样的接线操作呢?

一般灯珠用单独的5V供电,和板子共地即可。

两边接线不一样,只是因为线不够长,所以中间转接了一下。

只要按照上面的将灯环的DIN的D引脚连接到19号引脚(GPIO52)即可。
如果控制的灯珠少,则可以直接用板子5V供电,5V->DIN+,GND->DIN-