[英]Arduino Uno: While-loop fails to "restart" using Button to reset Timer when second-pressing?
What the code does:代码的作用:
My problem: when I get to STEP 5 in the code, it won't restart.我的问题:当我到达代码中的第 5 步时,它不会重新启动。 The problem is linked to the while-loop in the main function caused by, as far as I can see, the second while-loop in the function "stopTimer".问题与主函数中的 while 循环有关,据我所知,是由函数“stopTimer”中的第二个 while 循环引起的。 Can't make it to exit the loop.无法退出循环。 At least that's what I've understood from all the numerous unsuccessful tries!至少这是我从无数次失败的尝试中了解到的! Tried adding code with if-statements inside the "stopDisplay" function as well, including break;也尝试在“stopDisplay”函数中添加带有 if 语句的代码,包括 break; or return;或返回; etc.等等。
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <avr/io.h>
#include <util/delay.h>
#define BUTTONPRESSED PINC & 1 << PC0
/*
- PORT = D
Segment-A Pin 1 PD1 0B00000010
Segment-B Pin 2 PD2 0B00000100
Segment-C Pin 3 PD3 0B00001000
Segment-D Pin 4 PD4 0B00010000
Segment-E Pin 5 PD5 0B00100000
Segment-F Pin 6 PD6 0B01000000
Segment-G Pin 7 PD7 0B10000000
- PORT = B
Digit 1 Pin 10 PB2 0B00000100
Digit 2 Pin 11 PB3 0B00001000
Digit 3 Pin 12 PB4 0B00010000
Digit 4 Pin 13 PB5 0B00100000
- PORT = C
Button Pin A0 PC0 0B00000001
*/
//Number: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 in a array.
int segmentNumberArray[10] = {0B01111110, 0B00001100, 0B010110110, 0B10011110, 0B011001100, 0B11011010, 0B11111010, 0B00001110, 0B11111110, 0B11011110};
//Digit: 1, 2, 3, 4 in a array
int digitArrayOff[4] = {0B00000100, 0B00001000, 0B00010000, 0B00100000};
int digitArrayOn[4] = {0B11111011, 0B11110111, 0B11101111, 0B11011111};
//Blinking animation: segment-E, segment-D, segment-C, segment-G, segment-F, segment-A, segment-B, segment-G
int blinkingArray[8] = {0B00100000, 0B00010000, 0B00001000, 0B10000000, 0B01000000, 0B00000010, 0B00000100, 0B10000000};
long number = 0;
int recentTime;
int digit1, digit2, digit3, digit4;
int stopButton;
void startTimer();
void stopTimer();
void choseDigit(int x);
void showNumberOnDisplay(int x);
void blinkingAnimation();
int main()
{
DDRC = 0;
DDRD = 255;
DDRB = 0B00111100; //DDRB = 28;
srand(time(NULL));
while (1)
{
if (number == 0)
{
int randomWaitTime = rand() % 10 + 3; //Calls random number between 3-10
for (int i = 0; i < randomWaitTime; i++)
{
blinkingAnimation();
}
}
startTimer();
if (BUTTONPRESSED)
{
stopButton = 0;
stopTimer();
}
if (BUTTONPRESSED)
{
break;
}
}
return 0;
}
void startTimer()
{
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(1); //Turn Display 1 on
showNumberOnDisplay((number / 1000)); //Get value of thousand
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(2); //Turn Display 2 on
showNumberOnDisplay((number % 1000) / 100); //Get value of hundred
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(3); //Turn Display 3 on
showNumberOnDisplay(number % 100 / 10); //Get value of ten
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(4); //Turn Display 3 on
showNumberOnDisplay(number % 10); //Get value of single digit
_delay_ms(1); //Delay 1 ms
number++;
if (number == 9999) // Reset number count to 1;
{
number = 1;
}
}
void stopTimer()
{
recentTime = number;
digit1 = recentTime / 1000;
digit2 = (recentTime % 1000) / 100;
digit3 = recentTime % 100 / 10;
digit4 = recentTime % 10;
while (stopButton == 0)
{
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(1); //Turn Display 1 on
showNumberOnDisplay(digit1); //Get value of thousand
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(2); //Turn Display 2 on
showNumberOnDisplay(digit2); //Get value of hundred
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(3); //Turn Display 3 on
showNumberOnDisplay(digit3); //Get value of ten
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(4); //Turn Display 3 on
showNumberOnDisplay(digit4); //Get value of single digit
_delay_ms(1); //Delay 1 ms
}
}
void choseDigit(int x)
{
PORTB = 0B11111111;
switch (x)
{
case 1:
PORTB = digitArrayOn[0]; //Display 1 on
break;
case 2:
PORTB = digitArrayOn[1]; //Display 2 on
break;
case 3:
PORTB = digitArrayOn[2]; //Display 3 on
break;
case 4:
PORTB = digitArrayOn[3]; //Display 4 on
break;
}
}
void showNumberOnDisplay(int x)
{
switch (x)
{
case 1:
PORTD = segmentNumberArray[1];
break;
case 2:
PORTD = segmentNumberArray[2];
break;
case 3:
PORTD = segmentNumberArray[3];
break;
case 4:
PORTD = segmentNumberArray[4];
break;
case 5:
PORTD = segmentNumberArray[5];
break;
case 6:
PORTD = segmentNumberArray[6];
break;
case 7:
PORTD = segmentNumberArray[7];
break;
case 8:
PORTD = segmentNumberArray[8];
break;
case 9:
PORTD = segmentNumberArray[9];
break;
default:
PORTD = segmentNumberArray[0];
break;
}
}
void blinkingAnimation()
{
for (int i = 0; i < 8; i++)
{
PORTD = blinkingArray[i];
_delay_ms(125);
}
}
the value of variable stopButton still 0, resulting stopButton == 0 return true.变量stopButton的值仍然为 0,导致 stopButton == 0 返回 true。 But i think it better to use variable to represent the state.但我认为最好使用变量来表示状态。
#define STATE_COUNT 1
#define STATE_STOP 2
int currentState = 1;
while(1){
if(currentState == STATE_COUNT && BUTTONPRESSED){
//do something
currentState = STATE_STOP;
}
if(currentState == STATE_STOP && BUTTONPRESSED){
//do something
currentState = STATE_COUNT;
}
}
edited已编辑
so, my idea is to use STATE to define what code to run.所以,我的想法是使用 STATE 来定义要运行的代码。 so you can eliminate second while loop.所以你可以消除第二个while循环。
while (1) {
if(currentState == STATE_BLINK){
blink(); //run code 1 time and change state
currentState = STATE_COUNT;
}
if(currentState == STATE_COUNT){
startTimer();
}
if(currentState == STATE_STOP){
stopTimer(); // while loop inside is removed
}
if (BUTTONPRESSED) {
//change state here
}
}
void stopTimer() {
recentTime = number;
digit1 = recentTime / 1000;
digit2 = (recentTime % 1000) / 100;
digit3 = recentTime % 100 / 10;
digit4 = recentTime % 10;
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(1); //Turn Display 1 on
showNumberOnDisplay(digit1); //Get value of thousand
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(2); //Turn Display 2 on
showNumberOnDisplay(digit2); //Get value of hundred
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(3); //Turn Display 3 on
showNumberOnDisplay(digit3); //Get value of ten
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(4); //Turn Display 3 on
showNumberOnDisplay(digit4); //Get value of single digit
_delay_ms(1); //Delay 1 ms
}
void blink(){
if (number == 0) {
int randomWaitTime = rand() % 10 + 3; //Calls random number between 3-10
for (int i = 0; i < randomWaitTime; i++) {
blinkingAnimation();
}
}
}
Here is finally a solution to my problem above.这是我上面问题的最终解决方案。 Thought I post it in case anyone else runs into a similar problem:我想我发布它以防其他人遇到类似的问题:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <avr/io.h>
#include <util/delay.h>
#define BUTTONPRESSED PINC &(1 << PC0)
/*
- PORT = D
Segment-A Pin 1 PD1 0B00000010
Segment-B Pin 2 PD2 0B00000100
Segment-C Pin 3 PD3 0B00001000
Segment-D Pin 4 PD4 0B00010000
Segment-E Pin 5 PD5 0B00100000
Segment-F Pin 6 PD6 0B01000000
Segment-G Pin 7 PD7 0B10000000
- PORT = B
Digit 1 Pin 10 PB2 0B00000100
Digit 2 Pin 11 PB3 0B00001000
Digit 3 Pin 12 PB4 0B00010000
Digit 4 Pin 13 PB5 0B00100000
- PORT = C
Button Pin A0 PC0 0B00000001
*/
//Number: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 in a array
int segmentNumberArray[10] = {0B01111110, 0B00001100, 0B010110110, 0B10011110, 0B011001100, 0B11011010, 0B11111010, 0B00001110, 0B11111110, 0B11011110};
//Digit: 1, 2, 3, 4 in a array
int digitArrayOff[4] = {0B00000100, 0B00001000, 0B00010000, 0B00100000};
int digitArrayOn[4] = {0B11111011, 0B11110111, 0B11101111, 0B11011111};
//Blinking animation: segment-E, segment-D, segment-C, segment-G, segment-F, segment-A, segment-B, segment-G
int blinkingArray[8] = {0B00100000, 0B00010000, 0B00001000, 0B10000000, 0B01000000, 0B00000010, 0B00000100, 0B10000000};
long number = 0;
int recentTime;
int digit1, digit2, digit3, digit4;
int isCounting = 0;
int isButtonDown = 0;
void startTimer();
void stopTimer();
void choseDigit(int x);
void showNumberOnDisplay(int x);
void blinkingAnimation();
int main()
{
DDRC = 0; // För knappen -->> alt. DDRC&= ~(1 << PC0);
DDRD = 255;
DDRB = 0B00111100; //DDRB = 28; -->> detta är för Displayerna
srand(time(NULL));
blinkingAnimation();
while (1)
{
if (isCounting == 1)
{
startTimer();
}
if (BUTTONPRESSED)
{
if (isButtonDown == 0) //Button has not been pressed before
{
isButtonDown = 1;
if (isCounting == 0)
{
blinkingAnimation();
}
else
{
isCounting = 0;
}
}
}
else
{
isButtonDown = 0; //Button has been released
}
stopTimer();
}
return 0;
}
void startTimer()
{
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(1); //Turn Display 1 on
showNumberOnDisplay((number / 1000)); //Get value of thousand
_delay_ms(2.3); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(2); //Turn Display 2 on
showNumberOnDisplay((number % 1000) / 100); //Get value of hundred
_delay_ms(2.3); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(3); //Turn Display 3 on
showNumberOnDisplay(number % 100 / 10); //Get value of ten
_delay_ms(2.3); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(4); //Turn Display 4 on
showNumberOnDisplay(number % 10); //Get value of single digit
_delay_ms(2.3); //Delay 1 ms
number++;
if (number > 5999) // Reset number count to 1;
{
number = 1;
}
}
void stopTimer()
{
recentTime = number;
digit1 = recentTime / 1000;
digit2 = (recentTime % 1000) / 100;
digit3 = recentTime % 100 / 10;
digit4 = recentTime % 10;
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(1); //Turn Display 1 on
showNumberOnDisplay(digit1); //Get value of thousand
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(2); //Turn Display 2 on
showNumberOnDisplay(digit2); //Get value of hundred
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(3); //Turn Display 3 on
showNumberOnDisplay(digit3); //Get value of ten
_delay_ms(1); //Delay 1 ms
PORTD = 0B00000000; //Turn ALL segments off
choseDigit(4); //Turn Display 3 on
showNumberOnDisplay(digit4); //Get value of single digit
_delay_ms(1); //Delay 1 ms
}
void choseDigit(int x)
{
PORTB = 0B11111111;
switch (x)
{
case 1:
PORTB = digitArrayOn[0]; //Display 1 on
break;
case 2:
PORTB = digitArrayOn[1]; //Display 2 on
break;
case 3:
PORTB = digitArrayOn[2]; //Display 3 on
break;
case 4:
PORTB = digitArrayOn[3]; //Display 4 on
break;
}
}
void showNumberOnDisplay(int x)
{
switch (x)
{
case 1:
PORTD = segmentNumberArray[1];
break;
case 2:
PORTD = segmentNumberArray[2];
break;
case 3:
PORTD = segmentNumberArray[3];
break;
case 4:
PORTD = segmentNumberArray[4];
break;
case 5:
PORTD = segmentNumberArray[5];
break;
case 6:
PORTD = segmentNumberArray[6];
break;
case 7:
PORTD = segmentNumberArray[7];
break;
case 8:
PORTD = segmentNumberArray[8];
break;
case 9:
PORTD = segmentNumberArray[9];
break;
default:
PORTD = segmentNumberArray[0];
break;
}
}
void blinkingAnimation()
{
PORTB = digitArrayOn[4];
//Random wait time:
int randomWaitTime = rand() % 10 + 3; //Calls random number between 3-10 seconds
for (int i = 0; i < randomWaitTime; i++)
{
//Blink animation:
for (int i = 0; i < 8; i++)
{
PORTD = blinkingArray[i];
_delay_ms(125);
}
}
number = 0;
isCounting = 1;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.