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

FastLED 库的 GitHub 源码`​fill_rainbow`

本帖最后由 keer_zu 于 2025-5-8 10:00 编辑

可以直接在 FastLED 库的 GitHub 源码中找到 fill_rainbow 的实现代码。以下是具体获取方法:
1. 访问 FastLED 官方 GitHub 仓库FastLED 库的源码托管在 GitHub 上:https://github.com/FastLED/FastLED
2. 定位 fill_rainbow 函数源码fill_rainbow 的实现位于以下文件中:文件路径: FastLED/hsv2rgb.cpp
在文件中搜索 fill_rainbow,会找到如下代码片段:
void fill_rainbow( struct CRGB* pFirstLED, int numToFill,                  uint8_t initialhue,                  uint8_t deltahue ){    CHSV hsv;    hsv.hue = initialhue;    hsv.val = 255;    hsv.sat = 240;    for( int i = 0; i < numToFill; i++) {      pFirstLED = hsv;      hsv.hue += deltahue;    }}3. 代码解析输入参数:
pFirstLED: LED 数组指针。
numToFill: 需要填充的 LED 数量。
initialhue: 起始色相值(0-255)。
deltahue: 相邻 LED 的色相差值。
实现逻辑:
初始化一个 CHSV 结构体(HSV 颜色模型)。
固定饱和度(sat = 240)和亮度(val = 255)。
遍历每个 LED,为其分配递增的色相值,并通过 hsv2rgb 自动转换为 RGB 颜色。
4. 本地查看源码(通过 Arduino IDE)如果你已通过 Arduino IDE 安装了 FastLED 库,可以直接在本地找到源码:路径:你的Arduino安装目录/libraries/FastLED/src/hsv2rgb.cpp
5. 进阶:修改自定义彩虹效果如果你想自定义彩虹行为(例如修改饱和度或亮度),可以:
在本地库中修改 hsv2rgb.cpp 的 fill_rainbow 函数。
或直接在自己的代码中复制此函数并重写。
6. 其他相关函数FastLED 还提供了其他彩虹生成函数,例如:
fill_gradient(): 更通用的渐变填充。
fill_rainbow_circular(): 环形灯带的彩虹效果。
这些函数的源码均在 hsv2rgb.cpp 或 colorutils.cpp 中。
通过阅读源码,你可以更灵活地控制 LED 的彩虹效果!

keer_zu 发表于 2025-5-13 21:47

#include <BluetoothSerial.h>
#include <FastLED.h>
#include <math.h>
struct Polar { float radius; float angle_radians; };

Polar cartesianToPolar(float x, float y) {
    return {
      sqrt(x*x + y*y),
      atan2(y, x)
    };
}

#define LED_PIN   15   // 数据线连接的GPIO引脚
#define NUM_LEDS    450// LED数量
#define BRIGHTNESS 100// 亮度(0-255)
CRGB leds;
CRGB red_c   = CRGB(255, 0, 0);    // 红色
CRGB green_c   = CRGB(0, 255, 0);    // 绿色
CRGB blue_c   = CRGB(0, 0, 255);    // 蓝色
CRGB black_c   = CRGB(0, 0, 0);      // 黑色(关闭LED)
CRGB white_c   = CRGB(255, 255, 255);// 白色(全亮度)

CRGB yellow_c   = CRGB(255, 255, 0);// 黄色
CRGB qing_c   = CRGB(0, 255, 255);// 青色
CRGB pin_c   = CRGB(255, 0, 255);// 品红
CRGB cheng_c   = CRGB(255, 165, 0);// 橙色
CRGB zi_c   = CRGB(128, 0, 128);// 紫色
CRGB fen_c   = CRGB(255, 192, 203);// 粉色
int flag=0;

#define FILL_LEDS(value) do { \
    for (size_t i = 0; i < NUM_LEDS; ++i) { \
      (leds) = (value); \
    } \
} while(0)

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

#if !defined(CONFIG_BT_SPP_ENABLED)
#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
#endif

BluetoothSerial SerialBT;
#define BUFFER_SIZE 1024
uint8_t buffer;
int write_idx = 0;
int read_idx = 0;
unsigned long total_bytes = 0;
unsigned long last_time = 0;

#define BT_DISCOVER_TIME 10000

static bool btScanAsync = true;
static bool btScanSync = true;

void btAdvertisedDeviceFound(BTAdvertisedDevice *pDevice) {
Serial.printf("Found a device asynchronously: %s\n", pDevice->toString().c_str());
}

void setup() {
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);

Serial.begin(115200);
SerialBT.begin("ESP32-liuyan");//Bluetooth device name
Serial.println("The device started, now you can pair it with bluetooth!");
// SerialBT.setMTU(1024);

if (btScanAsync) {
    Serial.print("Starting asynchronous discovery... ");
    if (SerialBT.discoverAsync(btAdvertisedDeviceFound)) {
      Serial.println("Findings will be reported in \"btAdvertisedDeviceFound\"");
      delay(10000);
      Serial.print("Stopping discoverAsync... ");
      SerialBT.discoverAsyncStop();
      Serial.println("stopped");
    } else {
      Serial.println("Error on discoverAsync f.e. not working after a \"connect\"");
    }
}

if (btScanSync) {
    Serial.println("Starting synchronous discovery... ");
    BTScanResults *pResults = SerialBT.discover(BT_DISCOVER_TIME);
    if (pResults) {
      pResults->dump(&Serial);
    } else {
      Serial.println("Error on BT Scan, no result!");
    }
}
}

void fill_shape( struct CRGB * targetArray, int numToFill,
                  uint8_t initialhue,
                  uint8_t deltahue )
{
    CHSV hsv;
    hsv.hue = initialhue;
    hsv.val = 255;
    hsv.sat = 240;
    for( int i = 0; i < numToFill; ++i) {
      targetArray = hsv;
      hsv.hue += deltahue;
    }
}

void loop() {
int index;
static uint8_t hue = 0;
    // 非阻塞读取蓝牙数据
while (SerialBT.available()) {
    int bytes_to_read = SerialBT.available();
    bytes_to_read = min(bytes_to_read, BUFFER_SIZE - write_idx);

    // 写入缓冲区
    if (bytes_to_read > 0) {
      flag = 1;
      SerialBT.readBytes(&buffer, bytes_to_read);
      if(buffer == 'r' || buffer == 'R'){
      FILL_LEDS(red_c);
      } else if(buffer == 'g' || buffer == 'G'){
      FILL_LEDS(green_c);
      } else if(buffer == 'b' || buffer == 'B'){
      FILL_LEDS(blue_c);
      } else if(buffer == 'w' || buffer == 'W'){
      FILL_LEDS(white_c);
      } else if(buffer == 'y' || buffer == 'Y'){
      FILL_LEDS(yellow_c);
      } else if(buffer == 's' || buffer == 'S'){
      FILL_LEDS(black_c);
      flag = 0;
      } else if(buffer == 'q' || buffer == 'Q'){
      FILL_LEDS(qing_c);
      } else if(buffer == 'p' || buffer == 'P'){
      FILL_LEDS(pin_c);
      } else if(buffer == 'c' || buffer == 'C'){
      FILL_LEDS(cheng_c);
      } else if(buffer == 'z' || buffer == 'Z'){
      FILL_LEDS(zi_c);
      } else if(buffer == 'f' || buffer == 'F'){
      FILL_LEDS(fen_c);
      } else if(buffer == 'v' || buffer == 'V'){
      FILL_LEDS(fen_c);
      }
      
      FastLED.show();
      
      for(index = 0;index < bytes_to_read;index ++)
      Serial.printf("%c",buffer);
      write_idx = (write_idx + bytes_to_read) % BUFFER_SIZE;
      total_bytes += bytes_to_read;
    } else {
      
    }

    // 缓冲区切换检查(防止覆盖未读数据)
    if (write_idx >= BUFFER_SIZE / 2 && read_idx < BUFFER_SIZE / 2) {
      read_idx = BUFFER_SIZE / 2;// 切换到后半缓冲区
    }
}

// 计算实时带宽
unsigned long current_time = millis();
if (current_time - last_time >= 1000) {
    float rate = (total_bytes * 8) / 1000.0;// 转换为Kbps
    //Serial.printf("当前接收速率: %.2f Kbps\n", rate);
    total_bytes = 0;
    last_time = current_time;
}

//if(!flag) {
    fill_shape(leds, NUM_LEDS, hue++, 10);
    FastLED.show();
    //Serial.printf("%d\n",hue);
    //delay(1000);
    //FILL_LEDS(black_c);
    //FastLED.show();
    //delay(1000);
    //delay(10);
    //flag = !flag;
//}
}

页: [1]
查看完整版本: FastLED 库的 GitHub 源码`​fill_rainbow`