我正在尝试在Arduino中创建一个倒数计时器,它将在按下按钮时启动,并且在按下相同按钮时也会中止。该值介于0-60之间,由电位计设定。到目前为止我遇到的问题是我无法在启动后退出循环。我知道可以使用'break'来完成它,但是我无法弄清楚将结果放在哪里,结果将是所希望的。这就是我到目前为止所做的:
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,关闭,但如果我再次按下按钮直到完成,我就无法突破它。如何通过按下按钮来摆脱这个循环?
答案 0 :(得分:1)
我注意到这个帖子已经在这里待了一年了,但万一有人还在寻找答案......
突破loop(){}?你试过打电话吗
返回;
您希望它何时退出该循环?像:
void loop(){
buttonState = digitalRead(buttonPin);
if (buttonState == quitLoopState) {
delay(loopDelay);
return;
}
continueOperationOtherwise();
delay(loopDelay);
}
您始终可以将延迟代码放在方法的顶部以避免代码重复,并避免因早期中断循环而意外跳过代码。
答案 1 :(得分:0)
到目前为止我遇到的问题是我无法在启动后退出循环。
在您的代码中,您创建以下循环:
for (int i = timer_value; i >= 0; i--){ //Begin the loop
Serial.println(i);
delay(1000);
}
它是在按下按钮时调用的函数内部。打破循环,
你只需要在该循环中添加一个break;
语句。但问题是如何
检查可以帮助你摆脱循环的条件?
您需要再次检查循环内的输入引脚(使用digitalRead
)。但
为什么在一个简单的算法中检查两次单个按钮的状态?
这就是为什么我建议您使用单个loop
来解决您的问题,
loop()
函数,使用一组三个状态变量:
last_button_state
用于检测按钮的过渡状态count_down
了解我们是否处于倒计时count_down_value
倒计时的实际价值最后两个值可以合并为一个(例如,将count_down
设置为-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
...
现在,只有两种可能的情况:
如果电位计为0,则按钮被禁用。
答案 2 :(得分: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 what time it was 1000ms (1 second a go) and see if it is the same time or later than the last count, if so, it needs to count down.
if(millis() - 1000 >= last_count) {
//Time to count down.
timer_value--;
Serial.println(timer_value);
}
}
}
这样每个循环都会检查按钮,并且循环连续运行,而不是暂停第二个等待它倒计时,并且它将每秒计数。