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