LoginSignup
1
0

More than 5 years have passed since last update.

ちょっと上いくLフワの作り方

Posted at

少し上質なLフワ(LEDフワフワ)をやってみよう!、という記事です。
あるはずのmbed LPC1768が見当たらないのでmbed LPC1114FN28を使います。

ファームウェアをアップデート

無用なトラブルを避けるために、mbed LPC1114FN28を使う前にインターフェースのファームウェアをアップデートしておきましょう。
ファームウェアと手順はこちらです。

2016年8月に新しいファームウェアが出ています。
継続的に更新されていて、ありがたい。

Lフワ

LEDと(電流制限)抵抗を接続します。
PWMで明るさを変化させるので、"PwmOut"のピンに接続しなければいけません。今回は、dp18に接続します。

image.png

プログラムは、100ミリ秒毎に1%ずつON時間を増やして、(10秒経過して)100%になると0%になって、またON時間を増やすようにしました。

経過時間[秒] PWM出力値
0.0 0.00
0.1 0.01
0.2 0.02
0.3 0.03
... ...
10.0 1.00
10.1 0.00
10.2 0.01
... ...
main.cpp
#include "mbed.h"

PwmOut Led(dp18);

int main()
{
    for(;;) {
        for (int i = 0; i <= 100; i++) {
            Led = (float)i / 100;
            wait_ms(100);
        }
    }
}

実行!

image.png

うん、フワフワと...していますが...
Lチカとは明らかに違うものの、「ふわっ」という感じではなく、「ドカンッ」という感じの点灯具合です。(汗

さらに、デジカメで撮影すると、
Lフワ動画①
LEDが点滅して見えてしまいます。orz
これでは、せっかくのLフワもtwitter/Facebookで自慢が出来ないではありませんか!

問題点は以下の2つ。

  • 「ドカンッ」と点灯してしまう
  • デジカメで上手く撮影できない

デジカメで撮影できるように

デジカメで上手く撮影できないのは、シャッタースピードと比べて、PWM周期が遅かったり、近いのが原因です。デフォルトのPWM周期は、PwmOutの説明に書かれていました。

The default period is 0.020s, and the default pulsewidth is 0.

どれくらい速くすれば良いのか分からないので、適当に10マイクロ秒にして、デジカメで撮影してみます。

main.cpp
#include "mbed.h"

PwmOut Led(dp18);

int main()
{
    Led.period_us(10);  // PWM周期を10マイクロ秒に設定

    for(;;) {
        for (int i = 0; i <= 100; i++) {
            Led = (float)i / 100;
            wait_ms(100);
        }
    }
}

Lフワ動画②

デジカメで撮影できるようになりました(^O^)/

点灯具合を調整できるように

つぎは「ドカンッ」です。
明るさとON時間の関係を数式で表現するのは難しそうなので、調整できるようにすることで対処します。

明るさに対応するON時間の表を用意します。
Excelでデータを作って、サクラエディタにコピペして、キーボードマクロでC言語の配列に加工しました。

image.png

main.cpp
#include "mbed.h"

const float LedMap[] = {
    0.0000, 0.0001, 0.0004, 0.0009, 0.0016, 0.0025, 0.0036, 0.0049, 0.0064, 0.0081,
    0.0100, 0.0121, 0.0144, 0.0169, 0.0196, 0.0225, 0.0256, 0.0289, 0.0324, 0.0361,
    0.0400, 0.0441, 0.0484, 0.0529, 0.0576, 0.0625, 0.0676, 0.0729, 0.0784, 0.0841,
    0.0900, 0.0961, 0.1024, 0.1089, 0.1156, 0.1225, 0.1296, 0.1369, 0.1444, 0.1521,
    0.1600, 0.1681, 0.1764, 0.1849, 0.1936, 0.2025, 0.2116, 0.2209, 0.2304, 0.2401,
    0.2500, 0.2601, 0.2704, 0.2809, 0.2916, 0.3025, 0.3136, 0.3249, 0.3364, 0.3481,
    0.3600, 0.3721, 0.3844, 0.3969, 0.4096, 0.4225, 0.4356, 0.4489, 0.4624, 0.4761,
    0.4900, 0.5041, 0.5184, 0.5329, 0.5476, 0.5625, 0.5776, 0.5929, 0.6084, 0.6241,
    0.6400, 0.6561, 0.6724, 0.6889, 0.7056, 0.7225, 0.7396, 0.7569, 0.7744, 0.7921,
    0.8100, 0.8281, 0.8464, 0.8649, 0.8836, 0.9025, 0.9216, 0.9409, 0.9604, 0.9801,
    1.0000,
};


PwmOut Led(dp18);

int main()
{
    Led.period_us(10);  // PWM周期を10マイクロ秒に設定

    for(;;) {
        for (int i = 0; i < sizeof (LedMap) / sizeof (LedMap[0]); i++) {
            Led = LedMap[i];
            wait_ms(100);
        }
    }
}

Lフワ動画③

まだ今一つな感じもしますが、これで点灯具合が調整できるようになりました。
ただ、光り初めのときがスムーズに明るくなっていません。ガタガタしている感じがします。

ガタガタをスムーズに

どうやら、PWM周期を短くし過ぎて、分解能が不足しているようです。
10マイクロ秒を1ミリ秒に変更してみます。

main.cppの一部
    Led.period_us(1000);  // PWM周期を1ミリ秒に設定

Lフワ動画④

消えるときもフワッと

これは説明不要ですね♪

main.cpp
#include "mbed.h"

const float LedMap[] = {
    0.0000, 0.0001, 0.0004, 0.0009, 0.0016, 0.0025, 0.0036, 0.0049, 0.0064, 0.0081,
    0.0100, 0.0121, 0.0144, 0.0169, 0.0196, 0.0225, 0.0256, 0.0289, 0.0324, 0.0361,
    0.0400, 0.0441, 0.0484, 0.0529, 0.0576, 0.0625, 0.0676, 0.0729, 0.0784, 0.0841,
    0.0900, 0.0961, 0.1024, 0.1089, 0.1156, 0.1225, 0.1296, 0.1369, 0.1444, 0.1521,
    0.1600, 0.1681, 0.1764, 0.1849, 0.1936, 0.2025, 0.2116, 0.2209, 0.2304, 0.2401,
    0.2500, 0.2601, 0.2704, 0.2809, 0.2916, 0.3025, 0.3136, 0.3249, 0.3364, 0.3481,
    0.3600, 0.3721, 0.3844, 0.3969, 0.4096, 0.4225, 0.4356, 0.4489, 0.4624, 0.4761,
    0.4900, 0.5041, 0.5184, 0.5329, 0.5476, 0.5625, 0.5776, 0.5929, 0.6084, 0.6241,
    0.6400, 0.6561, 0.6724, 0.6889, 0.7056, 0.7225, 0.7396, 0.7569, 0.7744, 0.7921,
    0.8100, 0.8281, 0.8464, 0.8649, 0.8836, 0.9025, 0.9216, 0.9409, 0.9604, 0.9801,
    1.0000,
};

#define LedMapNumber    (sizeof (LedMap) / sizeof (LedMap[0]))

PwmOut Led(dp18);

int main()
{
    Led.period_us(1000);

    for(;;) {
        for (int i = 0; i < LedMapNumber; i++) {
            Led = LedMap[i];
            wait_ms(10);
        }
        for (int i = LedMapNumber - 1; i >= 0; i--) {
            Led = LedMap[i];
            wait_ms(10);
        }
        wait_ms(1000);
    }
}

Lフワ動画⑤

まとめ

  • 綺麗に撮影できるよう、PWM周期(PwmOut.period_us())を設定しましょう。
  • 明るさとON時間の対応を調整しましょう。

おまけ

PWMの最小分解能はいくつなんだろう?
PWM周期10usec.のLフワを、ロジアナで測定して確認しました。

image.png

image.png

だいたい、0.7usec.でした。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0