一:基础知识
WS2812内部封装的不仅仅是一颗LED,而是一颗微型控制芯片(通常称为WS2812)与三色LED的组合。它的核心工作逻辑是:
单线通信:数据和时钟合并在同一根线上,通过不同占空比的波形来区分逻辑0和逻辑1。
级联机制:每个灯珠上电后,会覆盖前24位数据(每颜色8位),然后将剩余数据整形放大后从DO引脚输出给下一个灯珠。
PWM恒流驱动:内部将接收到的8位亮度值(0-255)转换为PWM信号,驱动内部MOS管。这意味着它的亮度是线性的,但人眼对亮度感知是非线性的,后面我们会提到如何处理。
二:代码如下:在初始化时候,需要安装下驱动库:
在Arduino IDE中,点击 工具 > 管理库,搜索 Adafruit NeoPixel 并安装。
下面的代码会让灯带上的LED亮起绿色,然后整体显示红色,再亮起蓝色,如此循环。
2.1 初始化:// 请根据你的实际情况修改这两个参数
#define LED_PIN 2 // WS2812数据信号连接的GPIO引脚
#define LED_COUNT 2 // 灯带上的灯珠数量
// 初始化灯带对象
// 参数: 灯珠数量, 引脚号, 灯珠类型 (通常为 NEO_GRB + NEO_KHZ800)
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin(); // 初始化
strip.show(); // 将所有灯珠置为关闭状态
strip.setBrightness(10); // 设置亮度 (0-255),建议先调低一点保护眼睛和灯珠
}2.2 三种颜色灯变化的功能void loop() {
// 效果1: 逐个点亮为绿色,间隔500ms
strip.clear(); // 将所有像素颜色设为'off',需要调用 show() 才生效
for (int pixel = 0; pixel < LED_COUNT; pixel++) {
strip.setPixelColor(pixel, strip.Color(0, 255, 0)); // 设置当前像素为绿色
strip.show(); // 更新显示
delay(500);
}
// 等待2秒
delay(2000);
// 效果2: 所有灯珠同时显示为红色,持续1秒
strip.clear();
for (int pixel = 0; pixel < LED_COUNT; pixel++) {
strip.setPixelColor(pixel, strip.Color(255, 0, 0)); // 设置所有像素为红色
delay(500);
strip.show();
}
delay(2000);
// 效果3: 所有灯珠同时显示为蓝色,持续1秒
strip.clear();
for (int pixel = 0; pixel < LED_COUNT; pixel++) {
strip.setPixelColor(pixel, strip.Color(0, 0, 255)); // 设置所有像素为蓝色
delay(500);
strip.show();
}
delay(2000);
// 关闭所有灯珠1秒
strip.clear();
strip.show();
delay(1000);
}Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);:创建一个灯带对象,指定了灯珠数量、控制引脚和色彩模式。对于大多数WS2812灯带,NEO_KHZ800 是正确的设置。
strip.Color :生成一个24位的颜色值,参数范围是0-255。
strip.setPixelColor :设置指定位置灯珠的颜色,但此时数据并未真正发送到灯带。
strip.show();这个函数至关重要,它会将内存中的所有颜色数据通过引脚发送出去,灯带才会实际更新颜色。
三:实物验证:
电源:WS2812灯带需要5V电源。如果灯珠数量较多(比如超过10个),请勿直接使用ESP32开发板的5V引脚供电,电流可能不足。建议使用外部5V电源,并将ESP32的GND与灯带的GND和外部电源的GND连接到一起(共地)。
引脚:数据引脚(本例中为GPIO2)连接到ESP32的一个GPIO即可。部分ESP32开发板(如ESP32-S3)有内置RGB LED,其引脚可能被预定义,但外接灯带时你可以自由选择任意空闲GPIO。
电平转换:对于较长的灯带(>1-2米)或有信号不稳定情况,ESP32的3.3V逻辑电平可能无法被WS2812稳定识别为高电平,此时需要在数据线上串联一个电平转换芯片(如74HCT245)将信号升到5V。
我要赚赏金
