LEDを個別の周期で点滅させる制御方法
こんばんわ、くろべこでございます。
オリンピック延期になりましたね、、、
私はくろべこは奇跡的にチケット(シンクロナイズドダイビング)をゲットした所に延期のお知らせですよ、、、せめて、せめて返金をくれないかなと願っております。
という事で、今回はオリンピックには関連しませんがLED個別制御をしていきたいと思います。
ここで制御のイメージが出来る方は回れ右でOKです。たぶんそこまで得られるものはありません。
ここでの個別制御は複数あるLEDに対して異なる周期で点滅させることとします。早速ですが以下の動画を見てみてください。
どうでしょうか、オリンピックの5輪のマークを意識しました。
説明しますと、右から100ms, 300ms, 500ms, 700ms, 1000ms間隔で点滅制御を行っています。
Arduinoのサンプルコード(Blink)にもある様にLEDを点滅させるにはdelay()関数を使用することが多いと思います。
しかし、このdelay()関数はちょっと曲者で関数を使用している間はセンサーから値を読み取ったり、計算をしたり、ピンの制御を行うことができなく、その結果、ほとんどの動作を止めてしまうんですね。
なので、LED1つだけの制御ならdelay関数で事足りますが、動画のように複数のLEDを個別に制御するときにdelayを使ってしまうと遅延時間が蓄積されてしまい、おかしなことになってしまうと思います。
delayを使わない点滅制御方法
個別制御の答えは【ループ時間をモニタして処理毎に時間で分岐させる】です。
※あくまでもやり方の一つです。例えば異なるTIMERレジスタを使用しても個別制御可能です(割り込み)。
具体的にどのように制御するかというと、以下に模式図を描いてみました。
メインループを監視する変数cnt0を作ってあげまして、時間毎に処理分岐したい数だけcnt変数を作ります。そして、ループ内でcnt0と比較をしてあげて分岐させるイメージです。
単純です。軽いタイマー割り込みみたいな感じです。
では、実際のコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
uint16_t cnt0;//メインループカウント uint16_t cnt1=0, cnt2=0, cnt3=0, cnt4=0, cnt5=0;//各LEDカウント bool led[6]={0,0,0,0,0,0};//各LED出力状態 void setup() { for(uint8_t i=8;i<13;i++){ pinMode(i,OUTPUT);//8~12pin出力 } } void loop() { cnt0=millis(); //100ms毎点灯 if((cnt0-cnt1)>100){ led[1]=!led[1];// digitalWrite(8,led[1]); cnt1=cnt0; } //300ms毎点灯 if((cnt0-cnt2)>300){ led[2]=!led[2];// digitalWrite(9,led[2]); cnt2=cnt0; } //500ms毎点灯 if((cnt0-cnt3)>500){ led[3]=!led[3];// digitalWrite(10,led[3]); cnt3=cnt0; } //700ms毎点灯 if((cnt0-cnt4)>700){ led[4]=!led[4];// digitalWrite(11,led[4]); cnt4=cnt0; } //1000ms毎点灯 if((cnt0-cnt5)>1000){ led[5]=!led[5];// digitalWrite(12,led[5]); cnt5=cnt0; } } |
多分、サーボモーターとかの複数処理とかも可能だと思います。
こんな感じでタスク分割してあげると様々な処理を並列で処理が可能になります。
今回は技術メモ程度の内容でしたが、いろんなことに応用可能な内容なので参考にして頂ければと思います。
では、今回はこれで失礼します。
コメント