質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.33%

Arduino UNOで2組のスイッチを押すとLEDが点灯する回路があって、点灯を2秒間保持すると他のスイッチが反応しません。同時に点灯させたい

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 2,231

Q_1986-kt

score 13

基本は、スイッチを押している時にだけLEDが点灯するスケッチです。このスイッチとLEDが2組あります。
スイッチ1を押すとLED1が点灯、スイッチがOFFになってもLEDを2秒点灯させます。
スイッチ2も同じように押すとLED2が2秒間点灯。2つのスイッチを押すタイミングは決まっていません。
どちらが先になるかはわかりません。2つ同時の場合もあります。

コード

int sw_state1 = 0;
int sw_state2 = 0;

void setup() {
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
}

void loop() {
  sw_state1 = digitalRead(3);
  if (sw_state1 == HIGH) {
    digitalWrite(12, HIGH);
    delay(2000);
  } else {
    digitalWrite(12, LOW);
  }

  sw_state2 = digitalRead(4);
  if (sw_state2 == HIGH) {
    digitalWrite(13, HIGH);
    delay(2000);
  } else {
    digitalWrite(13, LOW);
  }
}


dalay(200)ぐらいにすれば、スイッチとLEDの点灯はイメージ通りに反応します。
dalay(2000)にして2秒点灯させようとすると、先に点灯したLEDが消灯してからでないと
もう一方のスイッチが反応しません。
(時間は特に決まってはいませんが数秒点灯を保持したいということです)

一方のスイッチを押してLEDが点灯していても、
もう一方のスイッチを押したらもう1つのLEDを点灯させたいです。
2つのスイッチは同時に押される可能性もあります。

Arduinoの接続するピンの場所を変えてみたり、
スイッチを内臓プルアップにしてみたり、
ハード的な変更もしてみました。

プログラム初心者ですが、
このコードだと、dalayで遅らせている時間が過ぎないと次の行のコードを実行できないということでしょうか
2つのスイッチのコードを並列(この表現でいいのかわかりませんが)に書かないとだめということでしょうか
試しに書いてみたコードです。

void loop(){
  sw_state1 = digitalRead(3);
  if (sw_state1 == HIGH) {
    sw1();
  } else {
    digitalWrite(12, LOW);
  }

  sw_state2 = digitalRead(4);
  if (sw_state2 == HIGH) {
    sw2();
  } else {
    digitalWrite(13, LOW);
  }
}

void sw1() 
{
    digitalWrite(12, HIGH);
    delay(2000);
}

void sw2() 
{
    digitalWrite(13, HIGH);
    delay(2000);
}


結果は、同じでした。

何かアドバイスをお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

最初に聞いときますけど、こういう回路になっていると思っていいですか。
回路
R3/R4に相当する、スイッチがオープンの時に電位をLに固定する処置はしてありますね?
端子が何もつながっていない、というのは決してLOWという意味ではないです。動いていても「たまたま」と考える必要があります。
スイッチをON時HIGHで取得する人ってよくやっちゃってるので念の為。
(スイッチON時LOWにするのなら内蔵PULLUPが使えば外部に抵抗をつけなくてもいいのですが)

で。
長時間のdelayはダメダメだけど、短時間毎に区切ればdelayでも十分に対応可能。何の前提もなく"delayはダメ"だと思っているのならそれは違うから。

ちょっと「2つのLED」は忘れて、LEDひとつスイッチひとつで、スイッチを押したら点灯。スイッチを離したら2秒たって消灯、してみましょう。あなたの最初のプログラムと同様に作ると、

int sw_state1 = 0;

void setup() {
  pinMode(3, INPUT);
  pinMode(12, OUTPUT);
}

void loop() {
  sw_state1 = digitalRead(3);
  if (sw_state1 == HIGH) {
    digitalWrite(12, HIGH);
    delay(2000);
  } else {
    digitalWrite(12, LOW);
  }
}


それを、こうしてみたらどうでしょう。

int sw_state1 = 0;
int count1 = 0;
const int DLY = 10;
const int HOLD_TIME = 2000;

void setup() {
  pinMode(3, INPUT);
  pinMode(12, OUTPUT);
}

void loop() {
  int ledStat1 = LOW;
  sw_state1 = digitalRead(3);
  if ( count1 > 0) { //スイッチが押されてから指定時間が経ってない
    count1--;//減算
    ledStat1 = HIGH;//LEDは点灯
  } else {//指定時間経過以降
    if (sw_state1 == HIGH ) { //スイッチが押されている
      ledStat1 = HIGH;//LED点灯
      count1 = HOLD_TIME / DLY; //指定時間をセット
    } else {
      ledStat1 = LOW;//LED消灯
    }
  }
  digitalWrite( 12, ledStat1 );
  delay(DLY);
}


delay()は10msだけ。人間には遅れをほぼ検知出来ない周期でスイッチを調べていますが、しかし2秒間はLEDが点灯している、そういうプログラムになっています。
delay()以外の部分は「一瞬」で終わりますから、複数のスイッチで複数のLEDを処理したければ、同様の処理で変数を変えたものを並べれば人間にとっては「同時」に2つのLEDが制御されている(としか思えない)状況が作れます。ついでに、LED1はスイッチ1から2秒、LED2はスイッチ2から3秒で消える、なんていうのも簡単に出来ますね。

時間を測ってもいいですけど、delayがダメ、というわけでは必ずしもないので。    

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/01/13 22:28

    thkanaさん、とても丁寧な説明ありがとうございます。
    とても参考になりました。

    今、作っているコードにはタイマーの機能もついているので時間を測るとかなり複雑で面倒だなと思っていたので
    時間を測らないこの方法は、シンプルでわかりやすく、実際に使っているコードに組み込んでちゃんと動くことも確認でき、希望通りの動きができました。本当にありがとうございました。

    キャンセル

checkベストアンサー

0

そりゃDelayの間はただ待ってるだけで、他のことは全くしないのでスイッチ効きません。
Delayを使わないで実装しましょう
2秒経過するまで何もしないでスルーするようにすればそのあとスイッチの処理ができます

繰り返しますが、Delayは使ってはいけません

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/01/10 22:59

    やっぱり、そうですか。
    時間を計測して、その時間が経過するまで点灯させるようにやってみます。
    ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Arduinoに関する質問
  • Arduino UNOで2組のスイッチを押すとLEDが点灯する回路があって、点灯を2秒間保持すると他のスイッチが反応しません。同時に点灯させたい