以下是用C語言編寫的10個通用RGB燈效算法,適用于大多數RGB LED控制場景(非硬件特定版本)。每個算法都包含可調節參數,代碼設計為獨立函數形式,便于集成到不同項目中:
```c
#include <stdint.h>
#include <math.h>
// 顏色結構體(通用RGB格式)
typedef struct {
uint8_t r;
uint8_t g;
uint8_t b;
} RGBColor;
// 1. 呼吸燈效果(單色)
void breathEffect(RGBColor* leds, int numLeds, uint8_t* phase, uint8_t speed, RGBColor color) {
static uint8_t brightness = 0;
static int8_t direction = 1;
brightness += direction * speed;
if(brightness >= 255 - speed) direction = -1;
if(brightness <= speed) direction = 1;
for(int i=0; i<numLeds; i++) {
leds[i].r = (color.r * brightness) >> 8;
leds[i].g = (color.g * brightness) >> 8;
leds[i].b = (color.b * brightness) >> 8;
}
}
// 2. 彩虹波浪效果
void rainbowWave(RGBColor* leds, int numLeds, uint8_t* phase, uint8_t speed) {
*phase += speed;
for(int i=0; i<numLeds; i++) {
uint8_t hue = *phase + (i * 255 / numLeds);
hsv2rgb(hue, 255, 255, &leds[i].r, &leds[i].g, &leds[i].b);
}
}
// 3. 跑馬燈效果(可調寬度)
void runningDot(RGBColor* leds, int numLeds, uint8_t* position, uint8_t speed, uint8_t width, RGBColor color) {
*position = (*position + speed) % numLeds;
for(int i=0; i<numLeds; i++) {
uint8_t distance = abs((int)(*position) - i);
if(distance > width) {
leds[i] = (RGBColor){0,0,0};
} else {
uint8_t intensity = 255 - (distance * 255 / width);
leds[i].r = (color.r * intensity) >> 8;
leds[i].g = (color.g * intensity) >> 8;
leds[i].b = (color.b * intensity) >> 8;
}
}
}
// 4. 顏色漸變過渡
void colorTransition(RGBColor* leds, int numLeds, uint8_t* phase,
RGBColor start, RGBColor end, uint8_t step) {
*phase = (*phase + step) % 255;
for(int i=0; i<numLeds; i++) {
leds[i].r = start.r + ((end.r - start.r) * *phase) / 255;
leds[i].g = start.g + ((end.g - start.g) * *phase) / 255;
leds[i].b = start.b + ((end.b - start.b) * *phase) / 255;
}
}
// 5. 隨機流星效果
void meteorShower(RGBColor* leds, int numLeds, uint8_t* pos, uint8_t speed,
uint8_t tailLength, RGBColor color) {
static uint8_t trail[64] = {0}; // 最大支持64長度拖尾
// 移動流星位置
*pos = (*pos + speed) % (numLeds + tailLength);
// 生成拖尾數據
for(int i=0; i<tailLength; i++) {
trail[i] = (255 * (tailLength - i)) / tailLength;
}
// 應用效果
for(int i=0; i<numLeds; i++) {
int trailIndex = i - (*pos - tailLength);
if(trailIndex >=0 && trailIndex < tailLength) {
uint8_t intensity = trail[trailIndex];
leds[i].r = (color.r * intensity) >> 8;
leds[i].g = (color.g * intensity) >> 8;
leds[i].b = (color.b * intensity) >> 8;
} else {
leds[i] = (RGBColor){0,0,0};
}
}
}
// 6. 音頻頻譜風格效果
void spectrumAnalyzer(RGBColor* leds, int numLeds, uint8_t* heights,
uint8_t decay, RGBColor color) {
for(int i=0; i<numLeds; i++) {
// 模擬隨機輸入數據(實際使用時替換為真實音頻數據)
if(rand()%20 == 0 && heights[i] < 240) heights[i] += 15;
// 高度衰減
if(heights[i] > decay) heights[i] -= decay;
else heights[i] = 0;
// 繪制柱狀圖
leds[i].r = (i < heights[i]/10) ? color.r : 0;
leds[i].g = (i < heights[i]/10) ? color.g : 0;
leds[i].b = (i < heights[i]/10) ? color.b : 0;
}
}
// 7. 火焰模擬效果
void fireEffect(RGBColor* leds, int numLeds, uint8_t* heat, uint8_t cooling, uint8_t sparking) {
// 生成隨機火花
for(int i=0; i<numLeds; i++) {
if(rand()%255 < sparking) {
heat[i] = 255;
}
}
// 熱量擴散
for(int i=numLeds-1; i>=2; i--) {
heat[i] = (heat[i-1] + heat[i-2] + heat[i-2])/3;
}
// 應用顏色映射
for(int i=0; i<numLeds; i++) {
uint8_t temp = heat[i];
leds[i].r = temp;
leds[i].g = temp/3;
leds[i].b = temp/10;
// 冷卻
if(heat[i] >= cooling) heat[i] -= cooling;
else heat[i] = 0;
}
}
// 8. 雙色交替掃描
void dualScan(RGBColor* leds, int numLeds, uint8_t* phase, uint8_t speed,
RGBColor color1, RGBColor color2) {
static uint8_t direction = 0;
*phase += speed;
if(*phase >= numLeds) {
*phase = 0;
direction = !direction;
}
for(int i=0; i<numLeds; i++) {
if((direction && (i < *phase)) || (!direction && (i >= numLeds - *phase))) {
leds[i] = color1;
} else {
leds[i] = color2;
}
}
}
// 9. 星光閃爍效果
void starTwinkle(RGBColor* leds, int numLeds, uint8_t* states, uint8_t fadeSpeed) {
for(int i=0; i<numLeds; i++) {
if(states[i] == 0 && rand()%1000 == 0) {
states[i] = 255; // 隨機點亮
}
if(states[i] > 0) {
leds[i].r = states[i];
leds[i].g = states[i];
leds[i].b = states[i];
if(states[i] > fadeSpeed) states[i] -= fadeSpeed;
else states[i] = 0;
} else {
leds[i] = (RGBColor){0,0,0};
}
}
}
// 10. 三維立方體效果
void cubeEffect(RGBColor* leds, int numLeds, uint8_t* angle, uint8_t speed,
RGBColor color) {
// 假設LED排列為8x8x8立方體(需要根據實際布局修改坐標計算)
static const uint8_t cubeSize = 8;
*angle += speed;
for(int x=0; x<cubeSize; x++) {
for(int y=0; y<cubeSize; y++) {
for(int z=0; z<cubeSize; z++) {
int index = x + y*cubeSize + z*cubeSize*cubeSize;
uint8_t intensity =
(sin8(x*32 + *angle) +
sin8(y*32 + *angle/2) +
sin8(z*32 + *angle/3)) / 3;
leds[index].r = (color.r * intensity) >> 8;
leds[index].g = (color.g * intensity) >> 8;
leds[index].b = (color.b * intensity) >> 8;
}
}
}
}
// HSV轉RGB輔助函數(優化整數版本)
void hsv2rgb(uint8_t hue, uint8_t sat, uint8_t val,
uint8_t* r, uint8_t* g, uint8_t* b) {
uint8_t region, remainder;
uint8_t p, q, t;
if(sat == 0) {
*r = *g = *b = val;
return;
}
region = hue / 43;
remainder = (hue - (region * 43)) * 6;
p = (val * (255 - sat)) >> 8;
q = (val * (255 - ((sat * remainder) >> 8))) >> 8;
t = (val * (255 - ((sat * (255 - remainder)) >> 8))) >> 8;
switch(region) {
case 0: *r = val; *g = t; *b = p; break;
case 1: *r = q; *g = val; *b = p; break;
case 2: *r = p; *g = val; *b = t; break;
case 3: *r = p; *g = q; *b = val; break;
case 4: *r = t; *g = p; *b = val; break;
default: *r = val; *g = p; *b = q; break;
}
}
// 正弦查表函數(0-255輸入,0-255輸出)
uint8_t sin8(uint8_t theta) {
static const uint8_t sineTable[] = {
128, 140, 152, 165, 176, 188, 199, 209, 219, 228, 236, 243, 249, 254,
255, 254, 249, 243, 236, 228, 219, 209, 199, 188, 176, 165, 152, 140,
128, 115, 103, 90, 79, 67, 56, 46, 36, 27, 19, 12, 6, 1, 0, 1, 6, 12,
19, 27, 36, 46, 56, 67, 79, 90, 103, 115
};
return sineTable[theta % 64];
}
```
### 使用說明:
1. **數據結構**:
- 使用`RGBColor`結構體存儲顏色值
- LED數組按順序排列,長度由`numLeds`參數指定
2. **狀態管理**:
- 帶`*phase`參數的效果需要調用者維護狀態變量
- 多LED效果(如流星、火焰)需要預先分配狀態數組
3. **性能優化**:
- 使用查表法實現三角函數(`sin8`)
- 全部使用整數運算,避免浮點計算
- 可調節的speed參數控制動畫速度
4. **典型調用方式**:
```c
int main() {
const int NUM_LEDS = 64;
RGBColor leds[NUM_LEDS];
// 狀態變量
uint8_t phase = 0;
uint8_t meteorPos = 0;
uint8_t fireHeat[NUM_LEDS] = {0};
uint8_t starStates[NUM_LEDS] = {0};
while(1) {
// 選擇要運行的效果(示例)
fireEffect(leds, NUM_LEDS, fireHeat, 30, 100);
// rainbowWave(leds, NUM_LEDS, &phase, 3);
// meteorShower(leds, NUM_LEDS, &meteorPos, 2, 10, (RGBColor){255,0,0});
// 此處插入實際硬件更新代碼
// ws2812_update(leds, NUM_LEDS);
delay_ms(30);
}
}
```
### 擴展建議:
1. **顏色混合**:添加顏色混合函數實現更復雜效果
2. **參數動態調整**:通過外部輸入(旋鈕、傳感器等)實時控制參數
3. **效果組合**:使用多層混合實現組合效果
4. **內存優化**:對于資源受限系統,可減少狀態變量數量
5. **時間同步**:使用定時器中斷確保穩定的刷新率
這些算法經過模塊化設計,可根據具體硬件平臺輕松適配,適合從Arduino到嵌入式Linux系統的各種應用場景。
|