Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 我怎样才能在按下按钮时打破这个循环?_Loops_Arduino_Break - Fatal编程技术网

Loops 我怎样才能在按下按钮时打破这个循环?

Loops 我怎样才能在按下按钮时打破这个循环?,loops,arduino,break,Loops,Arduino,Break,我正在尝试在Arduino中创建一个倒计时计时器,它将在按下按钮时启动,也将在按下同一按钮时中止。该值介于0-60之间,由电位计设置。到目前为止,我遇到的问题是,我无法在循环启动后退出循环。我知道可以使用“中断”来完成,但我不知道应该将其放在何处,以确保结果符合预期。这就是我到目前为止所做的: const int buttonPin = 2; // The pin that the pushbutton is attached to int buttonState = 0;

我正在尝试在Arduino中创建一个倒计时计时器,它将在按下按钮时启动,也将在按下同一按钮时中止。该值介于0-60之间,由电位计设置。到目前为止,我遇到的问题是,我无法在循环启动后退出循环。我知道可以使用“中断”来完成,但我不知道应该将其放在何处,以确保结果符合预期。这就是我到目前为止所做的:

const int  buttonPin = 2;    // The pin that the pushbutton is attached to
int buttonState = 0;         // Current state of the button
int lastButtonState = 0;     // Previous state of the button

void setup() {
    // initialize serial communication:
    Serial.begin(9600);
}

void timer(){
    int pot_value = analogRead(A0); //read potentiometer value
    if (pot_value > 17) { //i set it so, that it doesn't start before the value
                          //isn't greater than the 60th part of 1023
        int timer_value = map(pot_value, 0, 1023, 0, 60); //Mapping pot values to timer
        for (int i = timer_value; i >= 0; i--){ //Begin the loop
            Serial.println(i);
            delay(1000);
        }
    }
}

void loop() {
  // Read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // Compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      // If the current state is HIGH then the button
      // went from off to on:
      timer(); //run timer
    }
    else {
      // If the current state is LOW then the button
      // went from on to off:
      Serial.println("off");
    }
  }
  // Save the current state as the last state,
  //for next time through the loop
  lastButtonState = buttonState;
}
例如,如果我将电位计设置为5并按下按钮,我会看到5、4、3、2、1、0处于关闭状态,但如果我再次按下按钮直到按钮完成,我将无法摆脱它。我怎样才能在按下一个按钮时逃脱这个循环

到目前为止,我遇到的问题是,我无法在循环启动后退出循环

在代码中,创建以下循环:

for (int i = timer_value; i >= 0; i--){ //Begin the loop
    Serial.println(i);
    delay(1000);
}
它位于按下按钮时调用的函数内部。为了打破这个循环, 您只需添加一个
中断语句。但问题是怎么做
检查是否有助于您打破循环

您需要再次检查回路内的输入引脚(使用
数字读取
)。但是 为什么要在一个简单的算法中检查两次单个按钮的状态

这就是为什么我建议您通过使用单个
循环来解决您的问题,
loop()
函数使用一组三个状态变量:

  • last_button_state
    用于检测按钮的过渡状态
  • 倒计时
    了解我们是否在倒计时
  • 倒计时值
    倒计时的实际值
最后两个值可以合并为一个(例如,将
倒计时
设置为
-1
以显示 我们没有处于倒计时状态),但为了清楚起见,我省略了这两个状态变量

#define BUTTON_PIN 42

void setup() {
    Serial.begin(9600);
    pinMode(BUTTON_PIN, INPUT);
}

// State variables
uint8_t last_button_state = LOW;
bool count_down;
uint8_t count_down_value;

void loop() {
    int pot_value;

    // Read the pushbutton input pin:
    uint8_t button_state = digitalRead(buttonPin);

    if (button_state != last_button_state) {
        Serial.println("BUTTON STATE CHANGED");
        // On button press
        if (button_state == HIGH) {
            Serial.println("BUTTON PRESS");
            // Starts the count down if the value of potentiometer is high enough
            pot_value = analogRead(A0);
            if (pot_value > 17) {
                Serial.println("POT IS HIGH ENOUGH");
                if (count_down == false) {
                    Serial.println("ENABLING THE COUNT DOWN");
                    count_down = true;
                    count_down_value = map(pot_value, 0, 1023, 0, 60);
                } else {
                    Serial.println("DISABLING THE COUNT DOWN");
                    count_down = false;
                }
            }
        } else {
            Serial.println("BUTTON RELEASE");
        }
    }
    Serial.println("STORING BUTTON STATE");
    // Save button state for next iteration
    last_button_state = button_state;

    // If the countdown is running
    if (count_down == true) {
        Serial.println("RUNNING COUNTDOWN");
        // If the last value has been shown, show last value and stop the countdown
        if (count_down_value == 0) {
            Serial.println("BOOM!");
            count_down = false;
        // Otherwise decrements the value
        } else {
            // Prints out the value
            Serial.println(count_down_value);
            // Wait
            delay(1000);
            --count_down_value;
        }
    }
    delay(500); // Not to flood output
}
在这里,我希望得到以下输出:

<Press button>
BUTTON STATE CHANGED
BUTTON PRESS
POT IS HIGH ENOUGH
ENABLING THE COUNT DOWN
STORING BUTTON STATE
RUNNING COUNTDOWN
142
STORING BUTTON STATE
RUNNING COUNTDOWN
141
<Release button>
BUTTON STATE CHANGED
BUTTON RELEASE
STORING BUTTON STATE
RUNNING COUNTDOWN
140
<Press button>
BUTTON STATE CHANGED
BUTTON PRESS
POT IS HIGH ENOUGH
DISABLING THE COUNT DOWN
STORING BUTTON STATE
STORING BUTTON STATE
<Release button>
BUTTON STATE CHANGED
BUTTON RELEASE
STORING BUTTON STATE
...

按钮状态已更改
按键
罐子够高了
启用倒计时
存储按钮状态
运行倒计时
142
存储按钮状态
运行倒计时
141
按钮状态已更改
按钮释放
存储按钮状态
运行倒计时
140
按钮状态已更改
按键
罐子够高了
禁用倒计时
存储按钮状态
存储按钮状态
按钮状态已更改
按钮释放
存储按钮状态
...
因此,现在只有两种可能的情况:

  • 按下按钮,开始倒计时,重复倒计时,倒计时结束并停止
  • 按下按钮,倒计时开始,倒计时迭代,按下按钮,倒计时停止
如果电位计处于0,则按钮被禁用

到目前为止,我遇到的问题是,我无法在循环启动后退出循环

在代码中,创建以下循环:

for (int i = timer_value; i >= 0; i--){ //Begin the loop
    Serial.println(i);
    delay(1000);
}
它位于按下按钮时调用的函数内部。为了打破这个循环, 您只需添加一个
中断语句。但问题是怎么做
检查是否有助于您打破循环

您需要再次检查回路内的输入引脚(使用
数字读取
)。但是 为什么要在一个简单的算法中检查两次单个按钮的状态

这就是为什么我建议您通过使用单个
循环来解决您的问题,
loop()
函数使用一组三个状态变量:

  • last_button_state
    用于检测按钮的过渡状态
  • 倒计时
    了解我们是否在倒计时
  • 倒计时值
    倒计时的实际值
最后两个值可以合并为一个(例如,将
倒计时
设置为
-1
以显示 我们没有处于倒计时状态),但为了清楚起见,我省略了这两个状态变量

#define BUTTON_PIN 42

void setup() {
    Serial.begin(9600);
    pinMode(BUTTON_PIN, INPUT);
}

// State variables
uint8_t last_button_state = LOW;
bool count_down;
uint8_t count_down_value;

void loop() {
    int pot_value;

    // Read the pushbutton input pin:
    uint8_t button_state = digitalRead(buttonPin);

    if (button_state != last_button_state) {
        Serial.println("BUTTON STATE CHANGED");
        // On button press
        if (button_state == HIGH) {
            Serial.println("BUTTON PRESS");
            // Starts the count down if the value of potentiometer is high enough
            pot_value = analogRead(A0);
            if (pot_value > 17) {
                Serial.println("POT IS HIGH ENOUGH");
                if (count_down == false) {
                    Serial.println("ENABLING THE COUNT DOWN");
                    count_down = true;
                    count_down_value = map(pot_value, 0, 1023, 0, 60);
                } else {
                    Serial.println("DISABLING THE COUNT DOWN");
                    count_down = false;
                }
            }
        } else {
            Serial.println("BUTTON RELEASE");
        }
    }
    Serial.println("STORING BUTTON STATE");
    // Save button state for next iteration
    last_button_state = button_state;

    // If the countdown is running
    if (count_down == true) {
        Serial.println("RUNNING COUNTDOWN");
        // If the last value has been shown, show last value and stop the countdown
        if (count_down_value == 0) {
            Serial.println("BOOM!");
            count_down = false;
        // Otherwise decrements the value
        } else {
            // Prints out the value
            Serial.println(count_down_value);
            // Wait
            delay(1000);
            --count_down_value;
        }
    }
    delay(500); // Not to flood output
}
在这里,我希望得到以下输出:

<Press button>
BUTTON STATE CHANGED
BUTTON PRESS
POT IS HIGH ENOUGH
ENABLING THE COUNT DOWN
STORING BUTTON STATE
RUNNING COUNTDOWN
142
STORING BUTTON STATE
RUNNING COUNTDOWN
141
<Release button>
BUTTON STATE CHANGED
BUTTON RELEASE
STORING BUTTON STATE
RUNNING COUNTDOWN
140
<Press button>
BUTTON STATE CHANGED
BUTTON PRESS
POT IS HIGH ENOUGH
DISABLING THE COUNT DOWN
STORING BUTTON STATE
STORING BUTTON STATE
<Release button>
BUTTON STATE CHANGED
BUTTON RELEASE
STORING BUTTON STATE
...

按钮状态已更改
按键
罐子够高了
启用倒计时
存储按钮状态
运行倒计时
142
存储按钮状态
运行倒计时
141
按钮状态已更改
按钮释放
存储按钮状态
运行倒计时
140
按钮状态已更改
按键
罐子够高了
禁用倒计时
存储按钮状态
存储按钮状态
按钮状态已更改
按钮释放
存储按钮状态
...
因此,现在只有两种可能的情况:

  • 按下按钮,开始倒计时,重复倒计时,倒计时结束并停止
  • 按下按钮,倒计时开始,倒计时迭代,按下按钮,倒计时停止

如果电位计为0,则该按钮被禁用。

我知道该按钮激活已有一段时间,但我从前面的答案中看到的一个大问题是使用延迟,如果我正确读取,它会给出1.5秒计数,而不是1秒计数

更好的答案是计算自上次倒计时起的时间,如果是1秒或以上,则倒计时。它可能有点差,但更接近1秒

它还解决了另一个问题,即按钮只能存在于这些延迟之间,每1.5秒左右提供一个短时间,因此您可能需要按住按钮1.5秒来停止它,而不是仅仅按下按钮来停止它

我会做更像这样的事情:

const int  buttonPin = 2;   // The pin that the pushbutton is attached to
int buttonState = 0;        // Current state of the button
int lastButtonState = 0;    // Previous state of the button
int timer_value = 0;        // The timer that you want.
int last_count = 0;         // The time the counter last counted down.

void setup() {
    // initialize serial communication:
    Serial.begin(9600);
}

void loop() {
  // Read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // Compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      // If the current state is HIGH then the button
      // went from off to on:
      if(timer_value) {
        //checks to see if countdown is in progress, if 0, there is no count down.
        timer_value=0;
      }
      else {
        //The timer is not running, therefore start it.
        int pot_value = analogRead(A0); //read potentiometer value
        if (pot_value > 17) { //i set it so, that it doesn't start before the value
                              //isn't greater than the 60th part of 1023
            int timer_value = map(pot_value, 0, 1023, 0, 60); //Mapping pot values to timer.
            last_count = millis();  //sets up the timer to start counting.
            Serial.println(timer_value);  //Outputs the start of the timer.
        }
      }
    }
    else {
      // If the current state is LOW then the button
      // went from on to off:
      Serial.println("off");
    }
  }
  // Save the current state as the last state,
  //for next time through the loop
  lastButtonState = buttonState;
  
  //Check to see if counting down
  if(timer_value){
    //The timer is runing.
    //Check to see if it is time to count
    //Calculate how long since last count to see if it is greater than 1 s (1000 ms), if so, it needs to count down.
    if(millis() - last_count >= 1000) {
      //Time to count down.
      timer_value--;
      last_count = last_count + 1000;
      Serial.println(timer_value);
    }
  }
}

这样,每次循环都会检查按钮,循环会持续运行,而不是暂停一秒钟等待倒计时,并且它会每秒计数。

我知道这已经有一段时间没有被激活了,但我从前面的答案中看到一个大问题是延迟的使用,如果我读对了,它会给出1.5秒的计数,而不是1秒

更好的答案是计算自上次倒计时起的时间,如果是1秒或以上,则倒计时。可能有点不对劲,但离t更近了