はじめまして。
2日前にArduino MEGAのスターターキットを購入し、一通り各種動作やプログラムを動かしてみました。
次のステップとして、複数の動作を実行したいと思い、プログラムを組んでみましたが思うような動きがされず、本サイトを知り、質問させて頂きます。
・やりたい動作
1) タクトスイッチAを押すとLEDが点滅する。
2) タクトスイッチBが押されるまで1)を継続する。もしくは3分経過した場合はLEDを消灯する。
3) タクトスイッチBを押している間はLEDを点灯させる
4) タクトスイッチBを離すとLED消灯する。
・困っていること
LEDを点滅させる、スイッチ押している間LED点灯させる、の個々の動作は問題なくプログラム作成、動作しますが、上記連続動作ができない。
初心者のため、非常に簡単な内容かもしれませんが、具体的なプログラムの書き方をアドバイス頂けますと幸いです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
その動作をさせるためには、スイッチAとBをずっと監視していなければいけません。
もし、点滅を
Arduino
1digitalWrite(LED,HIGH); 2delay(500); 3digitalWrite(LED,LOW); 4delay(500);
のように実装していたら、(少なくともAVRのArduinoの一般的なスキームのなかでは)希望の動作はできません。
ではどうするか...方法は一つではありません。
例えば、
マイコンは基本的に一時にはひとつの仕事しかできませんがしかし、人間から見ればそれなりの速さでたくさんの仕事ができます。ならば、いくつかの仕事を細切れにして実行してやる、ということでいくつかの、今回で言えばLEDの点滅とスイッチの監視という2つの仕事を同時に(見えるように)行うこともできます。
Arduino
1int count=0; 2void loop(){ 3 if(count<500){ 4 digitalWrite(LED,HIGH); 5 }else{ 6 digitalWrite(LED,LOW); 7 } 8 count++; 9 if(count>1000){ 10 count=0; 11 } 12 delay(1); 13}
というプログラムでも先のプログラムとほぼ同様にLEDが点滅する、というのは理解できますか? しかし、このプログラムは、delay()のところで0.5秒間とどまる先のものとは違い、常にloop()関数の先頭から最後までを実行します。1msだけ足踏みしますが...たった1000分の1秒だけ。人間にはこれを止まっていると認識することはできません。
では、タクトスイッチを監視してみましょう。スイッチを押したらLEDが点滅をやめるプログラムは
Arduino
1int count=0; 2bool blinking=true; 3 4void loop(){ 5 bool sw=digitalRead(SWPIN)==LOW;//スイッチは押すとマイコンピンがLになるように接続しているものとする 6 if(blinking){ 7 //LED点滅処理 8 if(count<500){ 9 digitalWrite(LED,HIGH); 10 }else{ 11 digitalWrite(LED,LOW); 12 } 13 count++; 14 if(count>1000){ 15 count=0; 16 } 17 } 18 if(sw){ 19 blinking=false; 20 } 21 delay(1); 22}
これくらいヒントがあると、だいぶ進むんじゃないかと思いますがどうでしょう。
投稿2021/06/23 13:34
総合スコア7703
0
ベストアンサー
2日でそこまで行くとはすごいね。
私なんて、一か月ぐらい?、開梱もしなかったなぁ。
上手いアドバイスは難しいね。作ったスケッチがあれば指摘しやすいけど。
まずは、動作(条件と結果)を理解、分類する事かな。
まぁ、今回は本人が考えたものだから、最初から頭の中にあるのでしょうけど。
※基本的にすべての操作を考慮するから、今回ので言うと、Aを押して、3分以内にまたAを押した場合の処理はどうするのか?という部分が分類出来ない。(時間を延長か、SW無効か)
動きが判ったら、次はスケッチ上でどう表すか?どういった条件で書くか。
今回のだと
・点滅とSW処理を両立しなければならないから、loopをぐるぐる回す。
まぁ、基本、常にloopをぐるぐる回すスケッチを書いていればどんなのも対応出来ます。
・SW処理は、押した瞬間をとらえる必要は無さそう。(その時のSWを見るだけで良さそう)
・LEDの状態を表す変数と、点滅用の変数を用意する必要がある
ぐらいかな。おおまかに。
あとは、条件(注意事項)を頭の中に入れながらスケッチを書いていくだけです。
細かい点は、アドバイスは難しいですね。実際には、打ち込むときは常に気を使いますから。
具体的には↓のを参考にして下さい。
※あくまで1例です。特に「参考になる良いもの」を意識して書いた訳では無いです。
Arduino
1 2byte sw_A=2; 3byte sw_B=3; 4byte led=4; 5 6byte led_state;//0:消灯、1:点灯、2:点滅 7word cnt;//点滅用 8 9void setup(){ 10 pinMode(sw_A,INPUT_PULLUP);//負論理。ピン-SW-GND 11 pinMode(sw_B,INPUT_PULLUP);//負論理。ピン-SW-GND 12 pinMode(led,OUTPUT); 13} 14 15void loop() { 16 if(digitalRead(sw_A)==LOW) {//スイッチAを押したら点滅に 17 if(led_state!=2)cnt=0;//カウンタをリセット。(※延長なしの場合) 18 led_state=2; 19 } 20 if(digitalRead(sw_B)==LOW)led_state=1;//スイッチBを押したら点灯 21 else if(led_state==1)led_state=0;//点灯状態からSWを離したのなら消灯 22 23 if(led_state==2) {//点滅なら 24 digitalWrite(led,cnt%100<50);//点滅させる 25 if(++cnt==18000)led_state=0;//(約)3分経ったら、消灯 26 } else digitalWrite(led,led_state);//点灯、消灯処理 27 28 delay(10);//基準時間10ms 29}
投稿2021/06/23 16:31
総合スコア494
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/24 03:03
2021/06/24 03:27
2021/06/30 05:51
2021/06/30 08:39
2021/07/01 00:27
2021/07/01 00:45
2021/07/01 19:33
0
LEDの状態を表す変数(enumだと分かりやすい)を用意し、
現在の状態が何かで条件分岐して、
その状態に応じたLED出力をし、
さらにその状態のときどういう操作をしたらどんな状態に遷移するかを書く
点滅にdelayを使っている場合は使わない方法に切り替える
例えばmillsなど、詳しくは調べれば出てくる
投稿2021/06/23 12:28
総合スコア13553
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/24 02:53