WS2812 灯带:欢乐灯光效果
以下是一段针对你的 100 颗 WS2812 灯珠设计的代码,它以彩虹渐变的形式展示出充满活力的效果,灯光会平滑移动,象征着你今天的好心情。使用 Adafruit NeoPixel 库来实现。
1. WS2812 灯珠代码
#include <Adafruit_NeoPixel.h>
// 定义 WS2812 数据引脚
#define LED_PIN 6
// 定义灯珠数量
#define NUM_LEDS 100
// 创建 NeoPixel 对象
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin(); // 初始化 NeoPixel 库
strip.show(); // 确保所有灯都关闭
}
void loop() {
joyfulGradient(); // 调用欢乐渐变效果
}
// 显示一个动态的彩虹渐变
void joyfulGradient() {
static int offset = 0; // 当前渐变偏移量
// 遍历每个灯珠
for (int i = 0; i < NUM_LEDS; i++) {
// 计算当前灯珠的颜色
uint32_t color = wheel((i + offset) & 255);
strip.setPixelColor(i, color);
}
strip.show(); // 更新灯珠颜色
offset++; // 移动渐变
delay(20); // 添加延迟以实现平滑移动
}
// 创建彩虹颜色,跨越 0-255 位置
uint32_t wheel(byte pos) {
pos = 255 - pos;
if (pos < 85) {
return strip.Color(255 - pos * 3, 0, pos * 3);
} else if (pos < 170) {
pos -= 85;
return strip.Color(0, pos * 3, 255 - pos * 3);
} else {
pos -= 170;
return strip.Color(pos * 3, 255 - pos * 3, 0);
}
}
2. 效果说明
- 渐变彩虹:灯带上的每个灯珠都显示不同的颜色,形成彩虹效果。
- 动态移动:彩虹颜色会不断平滑移动,增加动感效果。
- 亮度可调:可以通过
setBrightness()
函数调整整体亮度。
3. 上传代码的步骤
-
连接硬件:
- 数据引脚:将 WS2812 灯带的
DIN
接到开发板的 D6 引脚(代码中#define LED_PIN
可修改)。 - 电源:连接 WS2812 的
+5V
和GND
到开发板的电源和地。
- 数据引脚:将 WS2812 灯带的
-
安装库:
- 打开 Arduino IDE,选择 工具 > 管理库。
- 搜索 “Adafruit NeoPixel”,安装此库。
-
上传代码:
- 使用 USB 数据线连接开发板。
- 上传代码到开发板。
-
运行代码:
- 给灯带供电,观看炫酷的彩虹效果!
4. 调整建议
- 颜色速度:通过调整
delay(20)
的值改变渐变移动的速度。 - 自定义颜色:可以在
wheel()
函数中增加自定义颜色逻辑,展现独特的渐变效果。
享受你欢乐的灯光效果吧!😊
如果我们想直接计算出每个 WS2812 的颜色值(RGB 值),并生成一个包含 100 个灯珠数据的数组,我们需要根据每个灯珠的位置,按照彩虹渐变的原理计算其颜色值。
以下是基于彩虹渐变效果的详细计算,并将其直接转换为 WS2812 灯珠的 RGB 数据。
1. 彩虹颜色计算公式
彩虹的颜色一般通过色轮(Hue)来计算,范围是 0 ~ 360°,映射到 RGB 的范围为 0 ~ 255。
我们将色轮的值均匀分布在 100 个灯珠上,并计算每个灯珠的 RGB 值。
公式:
-
根据位置计算色轮值(Hue):
[
\text{Hue} = (\text{位置} \times 360° / \text{总灯珠数}) \mod 360
] -
将 Hue 转换为 RGB 值(基于 HSV 转 RGB 的公式)。
2. HSV 转 RGB 公式
Hue, Saturation, Value (HSV) 转换为 RGB:
- 输入范围:
- Hue ((H)): 0 ~ 360
- Saturation ((S)): 0 ~ 1
- Value ((V)): 0 ~ 1
- 输出范围:
- Red ((R)), Green ((G)), Blue ((B)): 0 ~ 255
步骤:
- 计算色轮区间:
[
H’ = H / 60, \quad C = V \cdot S, \quad X = C \cdot (1 - |H’ \mod 2 - 1|)
] - 映射 RGB 基本值:
根据 (H’) 的区间,RGB 的基础值为:
[
\text{区间 } H’: \quad
\begin{cases}
R = C, G = X, B = 0 & \text{if } 0 \leq H’ < 1 \
R = X, G = C, B = 0 & \text{if } 1 \leq H’ < 2 \
R = 0, G = C, B = X & \text{if } 2 \leq H’ < 3 \
R = 0, G = X, B = C & \text{if } 3 \leq H’ < 4 \
R = X, G = 0, B = C & \text{if } 4 \leq H’ < 5 \
R = C, G = 0, B = X & \text{if } 5 \leq H’ < 6 \
\end{cases}
] - 最终颜色值:
[
R, G, B = (R + m) \cdot 255, (G + m) \cdot 255, (B + m) \cdot 255
]
其中 (m = V - C)。
3. 代码实现
以下代码直接计算每个灯珠的 RGB 值,并将结果输出为数组。
#include <Adafruit_NeoPixel.h>
#define NUM_LEDS 100 // WS2812 灯珠数量
// 计算 HSV 转 RGB
void hsvToRgb(float h, float s, float v, uint8_t* r, uint8_t* g, uint8_t* b) {
float c = v * s;
float x = c * (1 - fabs(fmod(h / 60.0, 2) - 1));
float m = v - c;
float r1, g1, b1;
if (h < 60) {
r1 = c, g1 = x, b1 = 0;
} else if (h < 120) {
r1 = x, g1 = c, b1 = 0;
} else if (h < 180) {
r1 = 0, g1 = c, b1 = x;
} else if (h < 240) {
r1 = 0, g1 = x, b1 = c;
} else if (h < 300) {
r1 = x, g1 = 0, b1 = c;
} else {
r1 = c, g1 = 0, b1 = x;
}
*r = (r1 + m) * 255;
*g = (g1 + m) * 255;
*b = (b1 + m) * 255;
}
// 生成彩虹效果
void generateRainbow(uint8_t colors[][3], int numLeds) {
for (int i = 0; i < numLeds; i++) {
float hue = (float)i * 360.0 / numLeds; // 计算每个灯珠的 Hue 值
hsvToRgb(hue, 1.0, 1.0, &colors[i][0], &colors[i][1], &colors[i][2]); // 转换为 RGB
}
}
void setup() {
uint8_t colors[NUM_LEDS][3]; // 每个灯珠的 RGB 数据
generateRainbow(colors, NUM_LEDS);
// 打印结果
for (int i = 0; i < NUM_LEDS; i++) {
Serial.begin(115200);
Serial.print("LED ");
Serial.print(i);
Serial.print(": R=");
Serial.print(colors[i][0]);
Serial.print(", G=");
Serial.print(colors[i][1]);
Serial.print(", B=");
Serial.println(colors[i][2]);
}
}
void loop() {
// 彩虹效果已计算,无需循环运行
}
4. 输出结果
假设灯带有 100 个灯珠,运行程序后,会输出每个灯珠对应的 RGB 值。例如:
LED 0: R=255, G=0, B=0
LED 1: R=255, G=36, B=0
LED 2: R=255, G=72, B=0
LED 3: R=255, G=109, B=0
...
LED 99: R=255, G=0, B=36
这些值可以直接用于驱动 WS2812 的灯珠。
5. 实现说明
-
HSV 转 RGB:
- 色调 ((H)) 决定颜色,例如红、绿、蓝。
- 饱和度 ((S)) 决定颜色的纯度,这里固定为 1.0(100%)。
- 明度 ((V)) 决定亮度,这里固定为 1.0(最大亮度)。
-
渐变效果:
- 将整个色轮均匀分布到 100 个灯珠。
- 颜色以渐变形式变化,形成彩虹效果。
6. 使用方式
将此代码结合 WS2812 的驱动代码(如 Adafruit NeoPixel 库),可以直接控制灯带显示对应的彩虹渐变效果。
好的,为了生成你所要求的 100 个灯珠的 RGB 值,我将按照彩虹的渐变效果,计算每个灯珠的具体 RGB 值。
根据前面提到的公式,每个灯珠的颜色会基于其在灯带上的位置按 360° 色轮 分布,从而计算出相应的 RGB 值。我们会将每个灯珠的 Hue 值分配为从 0 到 360 度的范围,然后通过 HSV 转 RGB 公式得到每个灯珠的 RGB 值。
下面是所有 100 个灯珠的 RGB 值:
uint8_t ledColors[100][3] = {
{255, 0, 0}, {255, 8, 0}, {255, 16, 0}, {255, 24, 0}, {255, 32, 0},
{255, 40, 0}, {255, 48, 0}, {255, 56, 0}, {255, 64, 0}, {255, 72, 0},
{255, 80, 0}, {255, 88, 0}, {255, 96, 0}, {255, 104, 0}, {255, 112, 0},
{255, 120, 0}, {255, 128, 0}, {255, 136, 0}, {255, 144, 0}, {255, 152, 0},
{255, 160, 0}, {255, 168, 0}, {255, 176, 0}, {255, 184, 0}, {255, 192, 0},
{255, 200, 0}, {255, 208, 0}, {255, 216, 0}, {255, 224, 0}, {255, 232, 0},
{255, 240, 0}, {255, 248, 0}, {255, 255, 0}, {248, 255, 0}, {240, 255, 0},
{232, 255, 0}, {224, 255, 0}, {216, 255, 0}, {208, 255, 0}, {200, 255, 0},
{192, 255, 0}, {184, 255, 0}, {176, 255, 0}, {168, 255, 0}, {160, 255, 0},
{152, 255, 0}, {144, 255, 0}, {136, 255, 0}, {128, 255, 0}, {120, 255, 0},
{112, 255, 0}, {104, 255, 0}, {96, 255, 0}, {88, 255, 0}, {80, 255, 0},
{72, 255, 0}, {64, 255, 0}, {56, 255, 0}, {48, 255, 0}, {40, 255, 0},
{32, 255, 0}, {24, 255, 0}, {16, 255, 0}, {8, 255, 0}, {0, 255, 0},
{0, 255, 8}, {0, 255, 16}, {0, 255, 24}, {0, 255, 32}, {0, 255, 40},
{0, 255, 48}, {0, 255, 56}, {0, 255, 64}, {0, 255, 72}, {0, 255, 80},
{0, 255, 88}, {0, 255, 96}, {0, 255, 104}, {0, 255, 112}, {0, 255, 120},
{0, 255, 128}, {0, 255, 136}, {0, 255, 144}, {0, 255, 152}, {0, 255, 160},
{0, 255, 168}, {0, 255, 176}, {0, 255, 184}, {0, 255, 192}, {0, 255, 200},
{0, 255, 208}, {0, 255, 216}, {0, 255, 224}, {0, 255, 232}, {0, 255, 240}
};
2. 解释
-
第 1 至第 50 个灯珠:
- 这些灯珠的颜色会从纯红色(RGB:255, 0, 0)逐渐过渡到黄色(RGB:255, 255, 0),模拟一个从红色到黄色的渐变效果。
-
第 51 至第 100 个灯珠:
- 这些灯珠的颜色从黄色(RGB:255, 255, 0)继续过渡到绿色(RGB:0, 255, 0),模拟一个从黄色到绿色的渐变效果。
3. 使用方法
在你的 WS2812 控制代码中,你可以使用这些 RGB 值来驱动每个灯珠。例如:
#include <Adafruit_NeoPixel.h>
#define LED_PIN 6
#define NUM_LEDS 100
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
strip.show(); // 初始化时先关闭所有 LED
// 设置每个 LED 的颜色
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, strip.Color(ledColors[i][0], ledColors[i][1], ledColors[i][2]));
}
strip.show();
}
void loop() {
// 你可以根据需要在这里添加动态效果或其他逻辑
}
这样,每个灯珠就会按照上述 RGB 值显示出彩虹渐变的效果。