keer_zu 发表于 2025-5-8 09:54

FastLED库fill_rainbow实现原理

FastLED 库中的 `fill_rainbow` 函数是通过 **HSV 色彩空间** 的色相(Hue)渐变实现的彩虹效果。其核心原理是为每个 LED 灯珠分配一个渐变的色相值,然后通过 HSV-to-RGB 转换生成最终颜色。以下是具体实现细节:

---

### 函数原型


```
void fill_rainbow(
struct CRGB* leds,   // LED 数组指针
int num_leds,      // LED 数量
uint8_t initial_hue, // 起始色相 (0-255)
uint8_t delta_hue    // 色相增量 (0-255)
);
```

---

### 实现原理

1. **HSV 色彩模型**:
   * 彩虹效果基于 **色相(Hue)** 的变化,HSV 模型中的色相值 `H` 范围是 `0-255`,对应色轮上的不同颜色。
   * 饱和度(S)和明度(V)通常设为固定值(如 `255`,即最大饱和度和亮度)。
2. **色相渐变计算**:
   * 每个 LED 的色相值按以下公式递增:


   ```
   hue = initial_hue + (i * delta_hue)
   ```

   * `i` 是 LED 的索引(从 `0` 到 `num_leds-1`)。
   * `delta_hue` 控制相邻 LED 的色相差(值越大,颜色变化越快)。
3. **自动色相环绕**:
   * 由于色相是 `uint8_t` 类型(0-255),当计算结果超过 `255` 时会自动取模,形成无缝循环。
4. **HSV 转 RGB**:
   * 使用 `hsv2rgb_spectrum` 或 `hsv2rgb_rainbow` 函数将 HSV 颜色转换为 RGB,并写入 LED 数组。

---

### 源码简化版


```
void fill_rainbow(CRGB* leds, int num_leds, uint8_t initial_hue, uint8_t delta_hue) {
CHSV hsv;
hsv.saturation = 255; // 固定饱和度
hsv.value = 255;      // 固定亮度

for (int i = 0; i < num_leds; i++) {
    hsv.hue = initial_hue + (i * delta_hue);
    leds = hsv; // 自动调用 hsv2rgb 转换
}
}
```

---

### 关键参数说明

* `initial_hue`:起始色相,例如:
* `0` = 红色
* `85` = 绿色
* `170` = 蓝色
* `delta_hue`:色相步长,常见值:
* `255 / num_leds`:在全部 LED 中均匀分布整个彩虹。
* `5`:颜色缓慢变化,适合长灯带。

---

### 示例用法


```
#include <FastLED.h>
#define NUM_LEDS 60
CRGB leds;

void setup() {
FastLED.addLeds<WS2812, 6>(leds, NUM_LEDS);
// 生成彩虹:起始色相=0,色相增量=5
fill_rainbow(leds, NUM_LEDS, 0, 5);
FastLED.show();
}

void loop() {}
```

---

### 进阶技巧

1. **动态彩虹**:在 `loop` 中递增 `initial_hue`,可实现彩虹滚动效果:
   

   ```
   static uint8_t hue = 0;
   fill_rainbow(leds, NUM_LEDS, hue++, 5);
   FastLED.show();
   delay(20);
   ```
2. **色相方向控制**:通过 `delta_hue` 的正负值调整渐变方向。
3. **自定义饱和度/亮度**:修改 `hsv.saturation` 和 `hsv.value` 实现不同效果。

---

通过调整 HSV 参数,`fill_rainbow` 提供了一种高效且直观的彩虹生成方式,无需手动计算 RGB 值。
页: [1]
查看完整版本: FastLED库fill_rainbow实现原理