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 的彩虹效果!
#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]