FastLED 库的 GitHub 源码`​fill_rainbow`

[复制链接]
 楼主| keer_zu 发表于 2025-5-8 09:57 | 显示全部楼层 |阅读模式
本帖最后由 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 | 显示全部楼层
  1. #include <BluetoothSerial.h>
  2. #include <FastLED.h>
  3. #include <math.h>
  4. struct Polar { float radius; float angle_radians; };

  5. Polar cartesianToPolar(float x, float y) {
  6.     return {
  7.         sqrt(x*x + y*y),
  8.         atan2(y, x)
  9.     };
  10. }

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

  20. CRGB yellow_c   = CRGB(255, 255, 0);  // 黄色
  21. CRGB qing_c   = CRGB(0, 255, 255);  // 青色
  22. CRGB pin_c   = CRGB(255, 0, 255);  // 品红
  23. CRGB cheng_c   = CRGB(255, 165, 0);  // 橙色
  24. CRGB zi_c   = CRGB(128, 0, 128);  // 紫色
  25. CRGB fen_c   = CRGB(255, 192, 203);// 粉色
  26. int flag=0;

  27. #define FILL_LEDS(value) do { \
  28.     for (size_t i = 0; i < NUM_LEDS; ++i) { \
  29.         (leds)[i] = (value); \
  30.     } \
  31. } while(0)

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

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

  38. BluetoothSerial SerialBT;
  39. #define BUFFER_SIZE 1024
  40. uint8_t buffer[BUFFER_SIZE];
  41. int write_idx = 0;
  42. int read_idx = 0;
  43. unsigned long total_bytes = 0;
  44. unsigned long last_time = 0;

  45. #define BT_DISCOVER_TIME 10000

  46. static bool btScanAsync = true;
  47. static bool btScanSync = true;

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

  51. void setup() {
  52.   FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  53.   FastLED.setBrightness(BRIGHTNESS);
  54.   
  55.   Serial.begin(115200);
  56.   SerialBT.begin("ESP32-liuyan");  //Bluetooth device name
  57.   Serial.println("The device started, now you can pair it with bluetooth!");
  58.   // SerialBT.setMTU(1024);

  59.   if (btScanAsync) {
  60.     Serial.print("Starting asynchronous discovery... ");
  61.     if (SerialBT.discoverAsync(btAdvertisedDeviceFound)) {
  62.       Serial.println("Findings will be reported in "btAdvertisedDeviceFound"");
  63.       delay(10000);
  64.       Serial.print("Stopping discoverAsync... ");
  65.       SerialBT.discoverAsyncStop();
  66.       Serial.println("stopped");
  67.     } else {
  68.       Serial.println("Error on discoverAsync f.e. not working after a "connect"");
  69.     }
  70.   }

  71.   if (btScanSync) {
  72.     Serial.println("Starting synchronous discovery... ");
  73.     BTScanResults *pResults = SerialBT.discover(BT_DISCOVER_TIME);
  74.     if (pResults) {
  75.       pResults->dump(&Serial);
  76.     } else {
  77.       Serial.println("Error on BT Scan, no result!");
  78.     }
  79.   }
  80. }

  81. void fill_shape( struct CRGB * targetArray, int numToFill,
  82.                   uint8_t initialhue,
  83.                   uint8_t deltahue )
  84. {
  85.     CHSV hsv;
  86.     hsv.hue = initialhue;
  87.     hsv.val = 255;
  88.     hsv.sat = 240;
  89.     for( int i = 0; i < numToFill; ++i) {
  90.         targetArray[i] = hsv;
  91.         hsv.hue += deltahue;
  92.     }
  93. }

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

  101.     // 写入缓冲区
  102.     if (bytes_to_read > 0) {
  103.       flag = 1;
  104.       SerialBT.readBytes(&buffer[write_idx], bytes_to_read);
  105.       if(buffer[write_idx] == 'r' || buffer[write_idx] == 'R'){
  106.         FILL_LEDS(red_c);
  107.       } else if(buffer[write_idx] == 'g' || buffer[write_idx] == 'G'){
  108.         FILL_LEDS(green_c);
  109.       } else if(buffer[write_idx] == 'b' || buffer[write_idx] == 'B'){
  110.         FILL_LEDS(blue_c);
  111.       } else if(buffer[write_idx] == 'w' || buffer[write_idx] == 'W'){
  112.         FILL_LEDS(white_c);
  113.       } else if(buffer[write_idx] == 'y' || buffer[write_idx] == 'Y'){
  114.         FILL_LEDS(yellow_c);
  115.       } else if(buffer[write_idx] == 's' || buffer[write_idx] == 'S'){
  116.         FILL_LEDS(black_c);
  117.         flag = 0;
  118.       } else if(buffer[write_idx] == 'q' || buffer[write_idx] == 'Q'){
  119.         FILL_LEDS(qing_c);
  120.       } else if(buffer[write_idx] == 'p' || buffer[write_idx] == 'P'){
  121.         FILL_LEDS(pin_c);
  122.       } else if(buffer[write_idx] == 'c' || buffer[write_idx] == 'C'){
  123.         FILL_LEDS(cheng_c);
  124.       } else if(buffer[write_idx] == 'z' || buffer[write_idx] == 'Z'){
  125.         FILL_LEDS(zi_c);
  126.       } else if(buffer[write_idx] == 'f' || buffer[write_idx] == 'F'){
  127.         FILL_LEDS(fen_c);
  128.       } else if(buffer[write_idx] == 'v' || buffer[write_idx] == 'V'){
  129.         FILL_LEDS(fen_c);
  130.       }
  131.       
  132.       FastLED.show();
  133.         
  134.       for(index = 0;index < bytes_to_read;index ++)
  135.       Serial.printf("%c",buffer[write_idx + index]);
  136.       write_idx = (write_idx + bytes_to_read) % BUFFER_SIZE;
  137.       total_bytes += bytes_to_read;
  138.     } else {
  139.       
  140.     }

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

  146.   // 计算实时带宽
  147.   unsigned long current_time = millis();
  148.   if (current_time - last_time >= 1000) {
  149.     float rate = (total_bytes * 8) / 1000.0;  // 转换为Kbps
  150.     //Serial.printf("当前接收速率: %.2f Kbps\n", rate);
  151.     total_bytes = 0;
  152.     last_time = current_time;
  153.   }
  154.   
  155.   //if(!flag) {
  156.     fill_shape(leds, NUM_LEDS, hue++, 10);
  157.     FastLED.show();
  158.     //Serial.printf("%d\n",hue);
  159.     //delay(1000);
  160.     //FILL_LEDS(black_c);
  161.     //FastLED.show();
  162.     //delay(1000);
  163.     //delay(10);
  164.     //flag = !flag;
  165.   //}
  166. }


您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:qq群:49734243 Email:zukeqiang@gmail.com

1478

主题

12915

帖子

55

粉丝
快速回复 在线客服 返回列表 返回顶部
个人签名:qq群:49734243 Email:zukeqiang@gmail.com

1478

主题

12915

帖子

55

粉丝
快速回复 在线客服 返回列表 返回顶部