找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 1394|回復(fù): 6
打印 上一主題 下一主題
收起左側(cè)

用C語(yǔ)言編寫的10個(gè)通用RGB燈效算法

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:46750 發(fā)表于 2025-2-16 10:51 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
以下是用C語(yǔ)言編寫的10個(gè)通用RGB燈效算法,適用于大多數(shù)RGB LED控制場(chǎng)景(非硬件特定版本)。每個(gè)算法都包含可調(diào)節(jié)參數(shù),代碼設(shè)計(jì)為獨(dú)立函數(shù)形式,便于集成到不同項(xiàng)目中:

```c
#include <stdint.h>
#include <math.h>

// 顏色結(jié)構(gòu)體(通用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. 跑馬燈效果(可調(diào)寬度)
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. 顏色漸變過(guò)渡
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. 隨機(jī)流星效果
void meteorShower(RGBColor* leds, int numLeds, uint8_t* pos, uint8_t speed,
                 uint8_t tailLength, RGBColor color) {
    static uint8_t trail[64] = {0}; // 最大支持64長(zhǎng)度拖尾

    // 移動(dòng)流星位置
    *pos = (*pos + speed) % (numLeds + tailLength);

    // 生成拖尾數(shù)據(jù)
    for(int i=0; i<tailLength; i++) {
        trail[i] = (255 * (tailLength - i)) / tailLength;
    }

    // 應(yīng)用效果
    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. 音頻頻譜風(fēng)格效果
void spectrumAnalyzer(RGBColor* leds, int numLeds, uint8_t* heights,
                     uint8_t decay, RGBColor color) {
    for(int i=0; i<numLeds; i++) {
        // 模擬隨機(jī)輸入數(shù)據(jù)(實(shí)際使用時(shí)替換為真實(shí)音頻數(shù)據(jù))
        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) {
    // 生成隨機(jī)火花
    for(int i=0; i<numLeds; i++) {
        if(rand()%255 < sparking) {
            heat[i] = 255;
        }
    }

    // 熱量擴(kuò)散
    for(int i=numLeds-1; i>=2; i--) {
        heat[i] = (heat[i-1] + heat[i-2] + heat[i-2])/3;
    }

    // 應(yīng)用顏色映射
    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; // 隨機(jī)點(diǎn)亮
        }

        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) {
    // 假設(shè)LED排列為8x8x8立方體(需要根據(jù)實(shí)際布局修改坐標(biāo)計(jì)算)
    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轉(zhuǎn)RGB輔助函數(shù)(優(yōu)化整數(shù)版本)
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;
    }
}

// 正弦查表函數(shù)(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];
}
```

### 使用說(shuō)明:
1. **數(shù)據(jù)結(jié)構(gòu)**:
   - 使用`RGBColor`結(jié)構(gòu)體存儲(chǔ)顏色值
   - LED數(shù)組按順序排列,長(zhǎng)度由`numLeds`參數(shù)指定

2. **狀態(tài)管理**:
   - 帶`*phase`參數(shù)的效果需要調(diào)用者維護(hù)狀態(tài)變量
   - 多LED效果(如流星、火焰)需要預(yù)先分配狀態(tài)數(shù)組

3. **性能優(yōu)化**:
   - 使用查表法實(shí)現(xiàn)三角函數(shù)(`sin8`)
   - 全部使用整數(shù)運(yùn)算,避免浮點(diǎn)計(jì)算
   - 可調(diào)節(jié)的speed參數(shù)控制動(dòng)畫(huà)速度

4. **典型調(diào)用方式**:
```c
int main() {
    const int NUM_LEDS = 64;
    RGBColor leds[NUM_LEDS];

    // 狀態(tài)變量
    uint8_t phase = 0;
    uint8_t meteorPos = 0;
    uint8_t fireHeat[NUM_LEDS] = {0};
    uint8_t starStates[NUM_LEDS] = {0};

    while(1) {
        // 選擇要運(yùn)行的效果(示例)
        fireEffect(leds, NUM_LEDS, fireHeat, 30, 100);
        // rainbowWave(leds, NUM_LEDS, &phase, 3);
        // meteorShower(leds, NUM_LEDS, &meteorPos, 2, 10, (RGBColor){255,0,0});

        // 此處插入實(shí)際硬件更新代碼
        // ws2812_update(leds, NUM_LEDS);

        delay_ms(30);
    }
}
```

### 擴(kuò)展建議:
1. **顏色混合**:添加顏色混合函數(shù)實(shí)現(xiàn)更復(fù)雜效果
2. **參數(shù)動(dòng)態(tài)調(diào)整**:通過(guò)外部輸入(旋鈕、傳感器等)實(shí)時(shí)控制參數(shù)
3. **效果組合**:使用多層混合實(shí)現(xiàn)組合效果
4. **內(nèi)存優(yōu)化**:對(duì)于資源受限系統(tǒng),可減少狀態(tài)變量數(shù)量
5. **時(shí)間同步**:使用定時(shí)器中斷確保穩(wěn)定的刷新率

這些算法經(jīng)過(guò)模塊化設(shè)計(jì),可根據(jù)具體硬件平臺(tái)輕松適配,適合從Arduino到嵌入式Linux系統(tǒng)的各種應(yīng)用場(chǎng)景。

評(píng)分

參與人數(shù) 1黑幣 +30 收起 理由
wpppmlah + 30 贊一個(gè)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏9 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:1110477 發(fā)表于 2025-2-17 03:34 | 只看該作者
請(qǐng)問(wèn)流星效果,跟落雪是一樣的嗎?
回復(fù)

使用道具 舉報(bào)

板凳
ID:433219 發(fā)表于 2025-2-17 11:48 | 只看該作者
  各種視覺(jué)效果,都是數(shù)學(xué)問(wèn)題,哈哈
回復(fù)

使用道具 舉報(bào)

地板
ID:1143878 發(fā)表于 2025-2-17 15:19 | 只看該作者
<H1>可以</H1>
回復(fù)

使用道具 舉報(bào)

5#
ID:63317 發(fā)表于 2025-2-18 07:13 | 只看該作者
謝謝分享資料
回復(fù)

使用道具 舉報(bào)

6#
ID:112138 發(fā)表于 2025-3-6 09:43 | 只看該作者
謝謝分享,學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

7#
ID:3802 發(fā)表于 2025-3-7 07:35 | 只看該作者
各種視覺(jué)效果,都是數(shù)學(xué)問(wèn)題,哈哈
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表