はじめに
このページは「マイコンLチカ道場 Arduino編」の「1-7:ロウソクのようにランダムにゆらゆらとLチカ」に対応するページです。PWM幅をランダムに変化させて、LEDをゆらゆらとロウソクの様に点灯させるような動作をさせてみます。
今回は、random関数を使用して疑似乱数を生成させる方法を試してみます。また、randomSeed関数を使用して未使用ピンから読み込んだランダムな値を用いて、疑似乱数が同じパターンにならない様にして、LEDの光り方が毎回変わる様にしてみます。
回路図とブレッドボード接続図
今回の回路図は下記になります。
今回はスイッチを使用しませんのでLEDだけです。LEDはロウソクっぽくするため、電球色のLEDにしてみました。無い場合は、何色でも問題ありません。
ピン9に並列で追加しているコンデンサと抵抗は、PWM波形を鈍らせてオシロで見るためのCRフィルタです。(C=1μF、R=10kΩ)オシロで見ない場合は無くても問題ありません。
電球色LEDのVFについて
電球色LEDは初出なので、一応VF特性を測った結果を載せておきます。このLEDは、ヤフオクで大昔に買ったよくわからない代物です。
電球色LEDは白色LEDと同じ系統で、蛍光剤の種類により暖かみのある発色で光ります。VFは白色や青色と同じ3.2Vあたりのようです。よって、電流制限抵抗は青色と同じ220Ωとしておきます。
I(mA) | VF(V) No.1 | VF(V) No.2 | VF(V) No.3 | VF(V) AVE |
0.1 | 2.750 | 2.745 | 2.717 | 2.737 |
1 | 2.911 | 2.903 | 2.900 | 2.905 |
2 | 2.981 | 2.971 | 2.973 | 2.975 |
3 | 3.028 | 3.017 | 3.022 | 3.022 |
5 | 3.095 | 3.083 | 3.093 | 3.090 |
10 | 3.208 | 3.198 | 3.210 | 3.205 |
15 | 3.289 | 3.280 | 3.297 | 3.289 |
20 | 3.361 | 3.350 | 3.368 | 3.360 |
プログラム(スケッチ)を書いてみる
今回のプログラムが下記になります。
#include <MsTimer2.h>
const int LED1 = 9; //LEDを接続するピン(PWM出力490Hz:3,9,10,11、980Hz:5,6)
int led_width = 0; //ledのPWM幅用の変数
int RandomNoisePin = A0; //ノイズによるランダム値を読み込むため、A0ピンを未接続としておく
void setup() {
pinMode(LED1, OUTPUT); //LED1ピンを出力にする
randomSeed(analogRead(RandomNoisePin)); //ノイズによるランダム値を読み込んで疑似乱数列のスタート地点を設定
MsTimer2::set(100, random_time); //100ms毎に関数random_timeを実行
MsTimer2::start(); //割り込み有効
}
void loop() {
}
void random_time(){
led_width = random(32, 255); //32から255までの乱数を生成してled_widthに代入
analogWrite(LED1, led_width); //LED1をPWMで点灯させる
}
主な動作説明はコメント文に記載しています。
今回もミリ秒単位で指定した時間で関数を呼び出すことが出来る、MsTimer2ライブラリを使用しています。(詳細は前々回の記事を参照ください)
「randomSeed(analogRead(RandomNoisePin))」で、RandomNoisePin = A0ピンからAD変換して読み込んだ値を、疑似乱数列のスタート地点として設定します。これが無くても動作しますが、ランダムに見えて実際は毎回同じ変化となるようです。
※今回はLED1個なので実用上問題ありませんが、一応試しに入れてみました。
「led_width = random(32, 255)」で、32~255の値をランダムに生成してLEDのPWM幅としています。0~255にすると、PWM幅0でLEDが完全に消える状態まで変化するので、ロウソクの様に自然に見える値に調整してみました。
「MsTimer2::set(100, random_time)」では、100ms毎に割り込みを発生させ、random関数で明るさを変える周期を変えています。この値を10ms以下などにすると、変化のスピードが速すぎてロウソクの様に見えなかったため調整しました。
動作確認
実際に動作させたときの波形が下記になります。PWM幅が32~255の間で変動しているので、それに合わせてロウソクの様にランダムでLEDがゆらゆらと光ります。
リセットスイッチを押して、出だしの光り初めの波形を何回か測ってみましたが、ちゃんと毎回異なる波形(ランダムな光り方)になっていることを確認しました。
下記にリセット後の出だしの波形を2回分載せておきます。
おまけで、randomSeed関数無しの場合も試してみました。
波形で見てみるとリセット後の出だしが3回とも完全に一致していることがわかります。目視では言われてみれば同じような…って感じですが。
まとめ
PWM幅をランダムに変化させて、LEDをゆらゆらとロウソクの様に点灯させるような動作をさせてみました。
また、random関数、randomSeed関数、analogRead関数を使用して、未使用ピンから読み込んだランダムな値を用いることで、疑似乱数が同じパターンにならない様にして、LEDの光り方が毎回変わる様な動きをさせてみました。
引き続き難しいLチカに挑戦していきましょう。