LEDで炎のゆらめき(1/fゆらぎ)をPWMで表現してみる

2012/08/25-26と大垣で行われたMake: Ogaki Meeting 02にてある方がLEDでろうそくの明かりを表現している作品を展示されていました。なかなかリアルで息を吹きかけると消えそうになったりと芸が細かく、面白いと思ってお話を伺ったところ、そこで使っているというLED(Cree社のMX-6、日本では売っていないとのこと)と変換用の基板をいただいてしまいました。

Cree Components XLamp MX-6 LEDs
http://www.cree.com/led-components-and-modules/products/xlamp/discrete-nondirectional/xlamp-mx6


他に流通しているLEDと比べてより炎の色に近いそうです。
せっかくLEDもいただいたので、自分でも作ってみようと思ってmbedで簡単にやってみました。
炎のゆらめきは1/fゆらぎでリアルに表現できるようです。「1/fゆらぎ」という言葉は歌か何かの表現で聞いたことがあった言葉でしたが、ちゃんとこういうところで出てくるものだったんですね。


1/fゆらぎは間欠カオス法で作っています。以下のエレキジャックのページが分かりやすかったです。

LEDイルミネーションの製作(第6回 最終回) 応用編・星のまたたき
http://www.eleki-jack.com/mycom2/2008/07/led6.html


単純に間欠カオス法を実装しただけでもそこそこのリアルさを感じました。
今回のプログラムではループを40ms間隔で回しています。また、少し消灯くらいの明るさの部分が大きいかな?と思ったので、計算結果が0.4未満の場合はその結果に0.8を足して極端に暗い場合をなくしました。
ちなみに上記のどちらの数値も間隔で適当に決めました。


回路はトランジスタを使って100Ωの抵抗を通して駆動しています。本来なら1A流せるLEDのようですが、今回は10mAほどしか流していません。それでもろうそくくらいの明るさは十分出ます。


最後に紙で覆って完成。
ほとんど時間をかけずに作りましたが、割と満足できるものができました。暇があればもっとチューニングしようと思います。


mbedプログラム

#include "mbed.h"

PwmOut led(p21);
AnalogIn Ap(p20);

int main() {
    float randFloat;
    float lightPercent;
    
    while(1) {
        randFloat = (float)rand() / RAND_MAX;
        
        if(randFloat < 0.5) {
            lightPercent =  randFloat + 2 * randFloat * randFloat;   
        } else {
            lightPercent = randFloat - 2 * (1 - randFloat) * (1 - randFloat);
        }
        
        if(lightPercent < 0.8) {
            lightPercent += 0.8;
        }
        
        led = lightPercent;
        
        srand(Ap.read() * 10000);
        wait(0.04);
    }
}