少し上質なLフワ(LEDフワフワ)をやってみよう!、という記事です。
あるはずのmbed LPC1768が見当たらないのでmbed LPC1114FN28を使います。
#ファームウェアをアップデート
無用なトラブルを避けるために、mbed LPC1114FN28を使う前にインターフェースのファームウェアをアップデートしておきましょう。
ファームウェアと手順はこちらです。
2016年8月に新しいファームウェアが出ています。
継続的に更新されていて、ありがたい。
#Lフワ
LEDと(電流制限)抵抗を接続します。
PWMで明るさを変化させるので、"PwmOut"のピンに接続しなければいけません。今回は、dp18に接続します。
プログラムは、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 |
... | ... |
#include "mbed.h"
PwmOut Led(dp18);
int main()
{
for(;;) {
for (int i = 0; i <= 100; i++) {
Led = (float)i / 100;
wait_ms(100);
}
}
}
実行!
うん、フワフワと...していますが...
Lチカとは明らかに違うものの、「ふわっ」という感じではなく、**「ドカンッ」**という感じの点灯具合です。(汗
さらに、デジカメで撮影すると、
Lフワ動画①
LEDが点滅して見えてしまいます。orz
これでは、せっかくのLフワもtwitter/Facebookで自慢が出来ないではありませんか!
問題点は以下の2つ。
- 「ドカンッ」と点灯してしまう
- デジカメで上手く撮影できない
#デジカメで撮影できるように
デジカメで上手く撮影できないのは、シャッタースピードと比べて、PWM周期が遅かったり、近いのが原因です。デフォルトのPWM周期は、PwmOutの説明に書かれていました。
The default period is 0.020s, and the default pulsewidth is 0.
どれくらい速くすれば良いのか分からないので、適当に10マイクロ秒にして、デジカメで撮影してみます。
#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);
}
}
}
デジカメで撮影できるようになりました(^O^)/
#点灯具合を調整できるように
つぎは「ドカンッ」です。
明るさとON時間の関係を数式で表現するのは難しそうなので、調整できるようにすることで対処します。
明るさに対応するON時間の表を用意します。
Excelでデータを作って、サクラエディタにコピペして、キーボードマクロでC言語の配列に加工しました。
#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);
}
}
}
まだ今一つな感じもしますが、これで点灯具合が調整できるようになりました。
ただ、光り初めのときがスムーズに明るくなっていません。ガタガタしている感じがします。
#ガタガタをスムーズに
どうやら、PWM周期を短くし過ぎて、分解能が不足しているようです。
10マイクロ秒を1ミリ秒に変更してみます。
Led.period_us(1000); // PWM周期を1ミリ秒に設定
#消えるときもフワッと
これは説明不要ですね♪
#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);
}
}
#まとめ
- 綺麗に撮影できるよう、PWM周期(PwmOut.period_us())を設定しましょう。
- 明るさとON時間の対応を調整しましょう。
#おまけ
PWMの最小分解能はいくつなんだろう?
PWM周期10usec.のLフワを、ロジアナで測定して確認しました。
だいたい、0.7usec.でした。