跳到主要内容

第 6 课 · NeoPixel 灯板

这一课学什么?

这一课只讲一个核心点:让灯光成为程序结果的一部分。

NeoPixel 灯板适合拿来做三类事情:

  • 显示状态
  • 做动态效果
  • 练习循环和编号控制

这块灯板一共有 48 颗灯珠,按从左到右、从上到下的顺序排列,可以看成 68 列。

NeoPixel 灯板

学习目标

  • 会给扩展模块上电并初始化 NeoPixel 灯板
  • 会一次点亮全部灯珠
  • 会按编号控制单颗灯珠
  • 会做出流水灯、轮转和彩色渐变这类基础效果
  • 理解“先布置图案,再让图案变化”的写法

用到的硬件和功能

这一课需要接入 NeoPixel 灯板。

会用到的接口主要有:

  • cm.power_on():给扩展模块上电。
  • cm.neopixel_attach(n=48):初始化 NeoPixel 灯板。n 是灯珠数量,CoCube 这块灯板通常用 48
  • cm.neopixel_set_all(r, g, b):把所有灯珠设置成同一种颜色。r / g / b 范围都是 0~255
  • cm.neopixel_set(i, r, g, b):设置第 i 颗灯珠的颜色。注意编号从 1 开始,不是从 0 开始。
  • cm.neopixel_set_color(i, color):设置第 i 颗灯珠的整数颜色值。color 通常可以由 cm.color_from_rgb(...) 生成。
  • cm.neopixel_clear():熄灭全部灯珠。
  • cm.neopixel_rotate(n=1):把当前灯光图案整体循环移位。n 为正表示向后移,n 为负表示向前移。
  • cm.neopixel_shift_all_colors(delta):整体改变当前图案的色相,适合做渐变和彩虹效果。
  • cm.color_from_rgb(r, g, b):把 RGB 颜色打包成一个整数颜色值。
  • cm.random_color():随机生成一个适合直接显示的颜色值。

先认识这个能力

NeoPixel 和屏幕有点像,都是“输出类”能力。
区别在于:

  • 屏幕更适合显示文字和图形
  • NeoPixel 更适合用颜色和动画表达状态

这一课里的代码会反复出现两个动作:

  1. 先把某些灯珠设成你想要的颜色
  2. 再通过循环让它们按时间变化

开始编程

1. 先把整块灯板点亮

import time
import cocube_module as cm

cm.power_on()
time.sleep_ms(300)
cm.neopixel_attach(48)

cm.neopixel_set_all(0, 120, 255)

先确认最基础的一步能跑通:

  • 模块能正常上电
  • 灯板能被正确初始化
  • 所有灯珠都能一起点亮

如果想熄灭,补一行就可以:

cm.neopixel_clear()

2. 逐颗点亮,做一个最简单的流水灯

import time
import cocube_module as cm

cm.power_on()
time.sleep_ms(300)
cm.neopixel_attach(48)

while True:
for i in range(1, 49):
cm.neopixel_clear()
cm.neopixel_set(i, 255, 80, 0)
time.sleep_ms(60)

这段程序很适合拿来理解两个关键点:

  • NeoPixel 的编号从 148
  • for 循环可以让同一段动作按顺序重复执行

逐颗流水灯效果

3. 先排出一整行,再做轮转效果

因为每一行有 8 颗灯珠,所以如果先点亮 1~8 号灯珠,再执行 rotate(8),就相当于整行一起移动。

import time
import cocube_module as cm

cm.power_on()
time.sleep_ms(300)
cm.neopixel_attach(48)
cm.neopixel_clear()

for i in range(1, 9):
cm.neopixel_set(i, 0, 255, 80)

while True:
cm.neopixel_rotate(8)
time.sleep_ms(120)

整行轮转效果

4. 让整块灯板做颜色渐变

如果你已经有一组颜色图案,可以继续让整块灯板的色相慢慢变化。

import time
import cocube_module as cm

cm.power_on()
time.sleep_ms(300)
cm.neopixel_attach(48)

base_colors = [
cm.color_from_rgb(255, 0, 0),
cm.color_from_rgb(255, 128, 0),
cm.color_from_rgb(255, 255, 0),
cm.color_from_rgb(0, 180, 255),
]

for i in range(1, 49):
cm.neopixel_set_color(i, base_colors[(i - 1) % len(base_colors)])

while True:
cm.neopixel_shift_all_colors(4)
time.sleep_ms(80)

颜色渐变效果

运行时观察什么

运行这节课的程序时,重点看这些现象:

  • 灯珠编号是不是按预期顺序变化
  • 整行轮转时,图案是不是每次移动 8
  • 不同颜色的亮度感受会不会差很多
  • 动画太快或太慢时,sleep_ms() 改多少会更合适

常见问题 / 使用提醒

  • NeoPixel 功耗不低,连续高亮运行会更快耗电
  • 灯珠编号从 1 开始;如果按 0 开始写,效果通常会不对
  • 建议先单独测试 NeoPixel,再和别的外设组合
  • AI 摄像头模式会占用 GPIO22,这时 NeoPixel 不能同时使用

挑战一下

试着做一个“状态灯板”:

  • 待机时显示一种颜色
  • 运行中显示另一种颜色
  • 完成时再切换成第三种颜色

如果想继续升级,可以把“整块同色”改成“每一行不同色”,再让整块图案轮转起来。

参考代码(默认折叠)
import time
import cocube_module as cm

cm.power_on()
time.sleep_ms(300)
cm.neopixel_attach(48)

row_colors = [
cm.random_color(),
cm.random_color(),
cm.random_color(),
cm.random_color(),
cm.random_color(),
cm.random_color(),
]

for row in range(6):
color = row_colors[row]
for col in range(8):
idx = row * 8 + col + 1
cm.neopixel_set_color(idx, color)

while True:
cm.neopixel_rotate(8)
time.sleep_ms(150)

快速参考

这一课最常用的写法是:

import cocube_module as cm

cm.power_on()
cm.neopixel_attach(48)
cm.neopixel_set_all(0, 0, 255)
  • cm.neopixel_attach(48):初始化 48 颗灯珠
  • cm.neopixel_set_all(...):全部点亮成同一种颜色
  • cm.neopixel_set(i, ...):设置单颗灯珠
  • cm.neopixel_set_color(i, color):设置单颗整数颜色值
  • cm.neopixel_rotate(...):整体轮转已有图案
  • cm.neopixel_shift_all_colors(...):让现有图案整体变色

如果想继续查外设接口,可以查看 cocube_module 快速参考