Ledの点滅を止める

私のコード:

// Pin 13 has a LED connected on most Arduino boards.
// give it a name:
int led = 13;
const int buttonPin = 2;

// the setup routine runs once when you press reset:
void setup() {
 //initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
}

// the loop routine runs over and over again forever:
void loop() 
{
  bool buttonState = digitalRead(buttonPin);
  while (buttonState == LOW)
  {
   digitalWrite(led, HIGH);  //turn the LED on (HIGH is the voltage level)
   delay(1000);              //wait for a second
   digitalWrite(led, LOW);   //turn the LED off by making the voltage LOW
   delay(1000);              //wait for a second
   }
 if (buttonState == HIGH){
   digitalWrite(led, LOW);}
  }

最後のコード行:

if (buttonState == HIGH){
   digitalWrite(led, LOW);}

私は、連続して点滅している状態からのLEDをオフにするために使ったものです。このプロジェクトのポイントは、LEDのボタンを点滅させてから、同じボタンを使ってLEDをオフにすることです。これは数時間私を悩ませています、私はすべての仕事をしたが、この最後の部分を完了するように見えることはできません。何がここで間違っていますか?

説明のため EDITED:

その意図は、ボタンを押すたびにLEDが点滅状態と点滅しない状態との間でトグルされることである。 LEDの状態は、ボタン自体のレベル(プッシュ/非プッシュ)によって駆動されるのではなく、プッシュ動作自体によって駆動される。

2
あなたは何をしたいですか?点滅を開始するには一回押し、点滅を止めるにはもう一度押しますか?ボタンを押している間点滅しますか?他に何か?
追加された 著者 af.,
はい、あなたが言った最初のこと。点滅を開始するには一回押し、点滅を止めるにはもう一度押す
追加された 著者 Jon7,

5 答え

点滅制御とは全く無関係にスイッチテストを行うことは理にかなっています。これは次のコードで実行され、ボタンが押されるたびに点滅がオンまたはオフになります。このコードでは、ボタンを押す間にLEDが消灯するか、約2 Hzの速度で点滅します。

enum { LED=13, ButtonPin=2, BounceMS=50, BlinkMS=256 };
unsigned long buttonAt;
bool blinky, bouncy, buttonState;

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(ButtonPin, INPUT_PULLUP);
  blinky = bouncy = buttonState = false;
  buttonAt = millis();
}

void loop() {
 //Detect button changes
  if (bouncy) {
    if (millis() - buttonAt > BounceMS)
      bouncy = false;      //End of debounce period
  } else {
    if (digitalRead(ButtonPin) != buttonState) {
      buttonState = digitalRead(ButtonPin);
      buttonAt = millis();
      bouncy = true;       //Start debounce period
      if (buttonState) {   //Was button just pressed?
        blinky = !blinky;  //Toggle blink-state
      }
    }
  }
 //Control light-blinking
  if (blinky) {
   //Turn LED on for BlinkMS ms, then off for same 
    digitalWrite(LED, (millis() - buttonAt)%(2*BlinkMS) < BlinkMS);
  } else {
    digitalWrite(LED, LOW);
  }
}
2
追加された

OPがコメントで説明したように、彼が達成しようとしているのは、ボタンを点滅させて消灯させ、ボタンを押してLEDをシャットダウンしないことです。

これは次のようにして行うことができます。

bool prevButtonState;
bool ledBlinking;

void loop() 
{
    bool buttonState = digitalRead(buttonPin);

    if (prevButtonState && !buttonState)
    {//Pressing edge: there is a transition between high and low
        ledBlinking = !ledBlinking;
    }
    prevButtonState = buttonState;

    if (ledBlinking)
    {
        digitalWrite(led, HIGH);  //turn the LED on (HIGH is the voltage level)
        delay(1000);              //wait for a second
        digitalWrite(led, LOW);   //turn the LED off by making the voltage LOW
        delay(1000);              //wait for a second
    }
    else
    {
        digitalWrite(led, LOW);
    }
}

しかしこれは、ボタンの連続チェック(サイクル間に2秒の遅延があるため)の間に非常に長い時間をもたらします。この問題を解決するには、millis関数を使用します。

bool prevButtonState;
bool ledBlinking;
unsigned long prevMillis;

void loop() 
{
    bool buttonState = digitalRead(buttonPin);

    if (prevButtonState && !buttonState)
    {//Pressing edge: there is a transition between high and low
        ledBlinking = !ledBlinking;

        prevMillis = millis() - 1000;//Force a check
    }
    prevButtonState = buttonState;

    if (ledBlinking)
    {
        if ((millis() - prevMillis) >= 1000)
        {
            prevMillis += 1000;
            digitalWrite(led, !digitalRead(led));
        }
    }
    else
    {
        digitalWrite(led, LOW);
    }
}

次にデバウンスの問題がありますが、これはOTになります。提案:バウンスが発生した場合は、Bounce2ライブラリを使用してボタンを管理してください

2
追加された
このコメントでは、ワンプッシュしたいと言っています→瞬く間に導かれ、別のプッシュ→導かれた。これは私のコードがするものです。あなたのコードは押されたままになっています - > LEDが点滅し、離されていない - > LEDが消灯
追加された 著者 Tom Collins,
いいえ、私はスイッチを切るためにボタンを使いたいと思います。スイッチと電球のように、唯一の違いは、電球が点滅することです。
追加された 著者 Jon7,

EDITED

この場合、Arduinoの loop()関数は while ループを冗長にします。さらに悪いことに、 while ループを実装した方法によって、 buttonState が更新されないようになり、ループが邪魔になります。

実際に必要なのは、タイマーを使用してLEDを点滅させ、HIGHからLOWへのボタン遷移によって駆動される2状態マシンです。

代わりにこれを試してください:

#include "Timer.h"

// Pin 13 has a LED connected on most Arduino boards.
// give it a name:
const int led = 13;
const int buttonPin = 2;

// declare state variables as global
bool buttonState = LOW;
bool buttonState_prev = LOW;
bool toggleBlinking;
bool blinkState;

// declare a Timer object so blinking can be done without loosing button presses
Timer timer_b;
int blink_id;

// the setup routine runs once when you press reset:
void setup() {
 //initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

 //initial state: toggle led each 1000 ms
  blink_id = timer_b.oscillate(led, 1000, HIGH);
  blinkState = true;
  toggleBlinking = false;
}

// the loop routine runs over and over again forever:
void loop() {
 //Update the timer (required)
  timer_b.update();

 //check if button has been pressed (HIGH to LOW),
 //then debounce it and raise toggle flag
  buttonState = digitalRead(buttonPin);
  if ((buttonState != buttonState_prev) && (buttonState_prev == HIGH)) {
   //simple button debounce (confirm press after some ms)
    delay (50);
    buttonState = digitalRead(buttonPin);
    if (buttonState != buttonState_prev) toggleBlinking = true;
  }

 //keep current LED state unless the button has been pushed
  switch (blinkState) {
    case true:
     //if button has been pushed, stop blinking and change LED state
      if (toggleBlinking == true) {
        timer_b.stop (blink_id);
        blinkState = false;
      }
      break;
    case false:
      digitalWrite(led, LOW);
     //if button has been pushed, start blinking and change LED state
      if (toggleBlinking == true) {
        blink_id = timer_b.oscillate(led, 1000, HIGH);
        blinkState = true;
      }
      break;
  }

  buttonState_prev = buttonState;
  toggleBlinking = false;
}

NOTE: You'll need to install the Timer.h library. I'VE TESTED MY CODE AND IT WORKS.

2
追加された
それは rel="nofollow noreferrer">デッドロックではありませんが、それ以外の点では良いです:-)
追加された 著者 af.,
あなたは正しい、ありがとう。私は答えを編集します。
追加された 著者 Arperum,
OK、プルアップを使用しています。私はそれを確認します。
追加された 著者 Arperum,
私は答えを編集した、見てみましょう。
追加された 著者 Arperum,
あなたのコードはLedが一度点滅するようにしています...あなたがここで何をしようとしているのか理解していますが、ボタンを押すとLEDが点滅し続けるようにしました。しかし、ボタンをもう一度押すと、点滅が止まります。私が言ったように、これは一度点滅するだけで、ボタンを押さなくても点滅を止めることができます...
追加された 著者 Jon7,
はい、申し訳ありません、私はより詳細を与えておくべきです:/
追加された 著者 Jon7,
@EnricBlancoの更新情報申し訳ありません私はちょうど静かにこの上にあったし、問題についてのいくつかの説明が必要です..
追加された 著者 Jon7,

これを試して:

if (key_pressed()) digitalWrite(LED_PIN, (digitalRead(LED_PIN)==ON)?OFF:ON);
else digitalWrite(LED_PIN, OFF);

あなたのつながりに基づいてON/OFFを定義してください。

編集する。

あなたはボタンがあまりにも点滅のLEDのモードを変更したい場合は、これを試してください。

    if (btn_pressed())                  //if btn falling edge detected
        btn_status ^= 1;                //flip the last bit. btn_status += 1; works as well
    if (btn_status & 0x01) led1_flp();  //flip led1
    else led1_off();                    //otherwise, turn off led1

    //flip led2
    IO_FLP(LED_PORT, LED2);

ロジックはかなり簡単です:ボタンが押されている(アクティブロー)場合、btn_statusをトグルします。 btn_statusが1の場合、led1を点滅させます。

基本的に、ボタンを押すと、ledが点滅し始めます。ボタンを2回押すと、LEDストップが点滅します。

led2は常にコードの並行性を示すために点滅します。

ここでそれは行動する。

enter image description here

コードは写真用に書かれていますが、基本的にはどのMCUでも実行されます。

1
追加された
while (buttonState == LOW)

一度 buttonState == LOW すると無限ループに閉じ込められます。
buttonState 内部をポーリングする必要があります。 しかし、これはあなたの目的には十分ではありません。本当に必要なのは(ブール値)変数です。たとえば、 blinking という名前を付けましょう.-これは、buttonStateの下降エッジを見るたびに値を変更します。
次にif/else節でこの変数の値をチェックします:

if (blinking == true)
{
   digitalWrite(led, HIGH);  //turn the LED on (HIGH is the voltage level)
   delay(1000);              //wait for a second
   digitalWrite(led, LOW);   //turn the LED off by making the voltage LOW
   delay(1000);              //wait for a second
}
else
{
   digitalWrite(led, LOW);}
}

しかし、これですぐに次の問題に直面するでしょう:非常に長い遅延のため、ボタンのポーリング速度は非常に遅く、 if 節の中に約2秒間あります。
ここで説明しているように、PWMを使用して点滅サイクルを設定してください 上記の if 節を使用してPWMデューティを50%に設定し、 else 節を使用して0%に設定します。

1
追加された
この回答はやや誤解を招くものです。 while(buttonState == LOW)のループ内で buttonState をポーリングすると何も得られません。
追加された 著者 af.,
@Utsavいいえ、あなたは新しいものを作成し、スコープの外から他の1つをシャドウすることではなく、buttonStateを更新したいと思います。
追加された 著者 Hailwood,
@Utsavそれは役に立たない。 buttonState にはピンの現在の状態は反映されません。 digitalRead はそうです。
追加された 著者 Hailwood,
@ KIIVのでwhileループの中に別の buttonState = digitalRead(buttonPin); を入れ、whileループの中に If文をカットアンドペーストします。彼らはまだ結果を生み出しません:/あなたが望むものを実際に実装することができなかったのはごめんなさい...
追加された 著者 Jon7,
'blinking'という新しいbool変数を作成すると、その変数を数値で設定しますか? bool blinking = 0; のようにするか、他に何かしますか?私はかなり混乱しています..
追加された 著者 Jon7,
whileループの中に If(buttonState == HIGH)を挿入したいのですか?
追加された 著者 Jon7,