一个在ESP32上使用FastLED库实现烛光效果的代码。这个效果模拟了真实蜡烛的闪烁和颜色变化。
#include <FastLED.h>
// LED点阵配置
#define LED_PIN 2
#define NUM_LEDS 64 // 假设是8x8点阵
#define BRIGHTNESS 100
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
// 烛光参数
uint8_t flickerIntensity = 50; // 闪烁强度
uint8_t baseBrightness = 150; // 基础亮度
unsigned long lastFlicker = 0;
unsigned long flickerDelay = 50; // 闪烁间隔(毫秒)
// 烛光颜色调色板 - 从深黄到橙红
CRGBPalette16 flamePalette = CRGBPalette16(
CRGB::DarkOrange,
CRGB::Orange,
CRGB::OrangeRed,
CRGB::Yellow,
CRGB::Gold,
CRGB::Orange,
CRGB::Red,
CRGB::DarkOrange,
CRGB::OrangeRed,
CRGB::Yellow,
CRGB::Orange,
CRGB::Gold,
CRGB::Red,
CRGB::DarkOrange,
CRGB::Orange,
CRGB::Yellow
);
void setup() {
Serial.begin(115200);
delay(1000); // 给串口时间初始化
// 初始化FastLED
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
Serial.println("烛光效果启动");
}
void loop() {
candleEffect();
FastLED.show();
delay(30); // 控制刷新率
}
void candleEffect() {
unsigned long currentTime = millis();
// 定期更新闪烁参数
if (currentTime - lastFlicker > flickerDelay) {
flickerIntensity = random8(30, 80);
flickerDelay = random8(30, 100);
lastFlicker = currentTime;
}
// 为每个LED生成烛光效果
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = getCandleColor(i);
}
}
CRGB getCandleColor(int ledIndex) {
// 使用噪声函数创建自然的烛光效果
uint16_t noise = inoise8(ledIndex * 20, millis() / 50);
// 基础颜色 - 暖黄色
CRGB baseColor = CRGB(255, 150, 50);
// 添加随机闪烁
uint8_t flicker = random8(flickerIntensity);
uint8_t brightness = baseBrightness - flicker;
// 使用调色板获取颜色变化
uint8_t colorIndex = scale8(noise, 128) + random8(20);
CRGB flameColor = ColorFromPalette(flamePalette, colorIndex);
// 混合基础颜色和火焰颜色
CRGB finalColor = blend(baseColor, flameColor, noise);
// 应用亮度变化
finalColor.nscale8_video(brightness);
return finalColor;
}
// 高级版本:模拟火焰形状的烛光
void advancedCandleEffect() {
// 假设8x8点阵,索引按行排列
const uint8_t width = 8;
const uint8_t height = 8;
for (uint8_t y = 0; y < height; y++) {
for (uint8_t x = 0; x < width; x++) {
int index = y * width + x;
// 计算距离中心的距离来创建火焰形状
int centerX = width / 2;
float distance = sqrt(pow(x - centerX, 2) + pow(y, 2));
// 基础亮度随高度增加而减小
uint8_t baseBright = 200 - (y * 25);
// 使用Perlin噪声创建有机的火焰运动
uint16_t noise1 = inoise8(x * 30, y * 40 + millis() / 60);
uint16_t noise2 = inoise8(x * 25 + 1000, millis() / 45);
// 结合多个噪声源
uint8_t combinedNoise = (noise1 + noise2) / 2;
// 火焰形状遮罩 - 底部亮,顶部暗
uint8_t flameMask = 255 - (y * 32);
if (flameMask < 50) flameMask = 50;
// 随机闪烁
uint8_t flicker = random8(30, 70);
// 最终亮度计算
uint8_t brightness = (baseBright * combinedNoise / 255) - flicker;
brightness = (brightness * flameMask) / 255;
// 颜色选择 - 底部偏黄,顶部偏橙红
uint8_t hue;
if (y < 2) {
hue = 25; // 黄色
} else if (y < 4) {
hue = 20; // 橙黄色
} else {
hue = 10; // 橙红色
}
// 添加颜色变化
hue += random8(-3, 3);
leds[index] = CHSV(hue, 255, brightness);
}
}
}
// 切换效果的函数
void switchEffect() {
static bool simpleEffect = true;
if (simpleEffect) {
candleEffect();
} else {
advancedCandleEffect();
}
simpleEffect = !simpleEffect;
}
使用说明
-
基础配置:
- 修改
LED_PIN 为你的ESP32连接的数据引脚
- 修改
NUM_LEDS 为你的点阵LED数量
- 调整
BRIGHTNESS 控制整体亮度
-
两种效果:
candleEffect(): 简单的烛光闪烁效果
advancedCandleEffect(): 更复杂的火焰形状模拟
-
自定义参数:
flickerIntensity: 控制闪烁强度
baseBrightness: 基础亮度水平
flamePalette: 烛光颜色调色板
进阶功能
你还可以添加以下功能来增强效果:
// 添加环境光传感器控制亮度
void autoBrightness() {
// 读取光敏电阻值
int lightValue = analogRead(A0);
int newBrightness = map(lightValue, 0, 4095, 50, 255);
FastLED.setBrightness(newBrightness);
}
// 响应声音的烛光效果
void soundReactiveCandle() {
int soundLevel = analogRead(A1);
if (soundLevel > 500) {
// 声音较大时增强闪烁
flickerIntensity = 100;
}
}
这个代码提供了自然的烛光效果,包括颜色变化、亮度闪烁和火焰形状模拟。可以根据实际硬件调整参数来获得最佳效果。