Hello everyone,
Currently I'm designing a reaction timer game for my students. 1 Button, 1 LED and the serial monitor is all I need (I think).
I'm not a complete noob at programming but I must admit that I'm more familiar with ladder diagrams (PLC). That's why I try to keep the programming to functions/statements I understand, so I can explain them in detail if my students would be interested.
My goal is to have some instructions in the serial monitor: the user presses and holds the button, that would trigger a "3" "2" "1" on serial monitor, timed with 1 second in between them. Then a random time would be added and when the time is reached the LED would come on: signaling the user to release the button. When released, the serial monitor should show the difference in the internal timer and when the user released the button.
ATM; The problem is that it does not wait a second for the next number, in fact, it does not wait at all. I have filtered it down to being a lower value being subtracted by an higher value, creating an overflow.
Both variables are being derived from the Millis() function, one is the starting value (static), the other one is the value that the user has been waiting until the LED would come on.
The weird thing is that I fill in the currentvalue before the waitvalue which should result in the waitvalue being higher than the currentvalue, but it doesn't seem to work.. Any suggestions?
This is (part of) the serial monitor output:
DEBUG currenttime value 0
3
DEBUG currenttime value 1001
DEBUG starttime value 1004
2
DEBUG currenttime value 1001
DEBUG starttime value 1004
1
DEBUG currenttime value 1001
DEBUG starttime value 1004
0 ... Watch the LED!
DEBUG bttnState value 1
DEBUG steps value 2
DEBUG LED value 0
DEBUG currenttime value 1001
DEBUG waittime value 1214
Here is a loop of the code that I used:
void loop()
{
bttnState = digitalRead(BTTN);
digitalWrite(LED, ledState);
switch (steps)
{
case 0: // State: button not pushed yet, game is ready
if (bttnState == true && (bttnState != bttnPrevState)) // Check if button is pressed since last cycle
{
bttnPrevState = bttnState; // Shift current state into last state
ledState = false; // set to false once before case 2
printFlag0 = true; // set to true once before case 1
printFlag1 = true;
printFlag2 = true;
printFlag3 = true;
randomizerFlag = true; // set to true once before case 2
steps = 1; // Go to next case
}
break;
case 1: // State: button is pressed, start counting
if (bttnState == true && (bttnState == bttnPrevState)) // Check if button is still pressed down
{
currentTimeMs = millis(); // FIll in current time
if (printFlag3 == true) // Check if printed only once to serial monitor or not
{
Serial.println("3");
startTimeMs = millis(); // Take time when the program starts
printFlag3= false; // After printing to serial monitor, we don't want to print again
}
if ((currentTimeMs - startTimeMs) >= 1000) // Checking if passed time is > 1s
{
if (printFlag2 == true) // Check if printed only once to serial monitor or not
{
Serial.println("2");
printFlag2 = false; // After printing to serial monitor, we don't want to print again
}
}
if ((currentTimeMs - startTimeMs) >= 2000) // Checking if passed time is > 2s
{
if (printFlag1 == true) // Check if printed only once to serial monitor or not
{
Serial.println("1");
printFlag1 = false; // After printing to serial monitor, we don't want to print again
}
}
if ((currentTimeMs - startTimeMs) >= 3000) // Checking if passed time is > 3s
{
if (printFlag0 == true) // Check if printed only once to serial monitor or not
{
Serial.println("0 ... Watch the LED!");
printFlag0 = false; // After printing to serial monitor, we don't want to print again
waitTimeMs = millis(); // Write time since program will ask to wait on LED
steps = 2; // Go to next case
}
}
}
else if (bttnState == false) // do this if button is not pressed anymore
{
bttnPrevState = bttnState;
Serial.println("Button Released far too soon!");
Serial.println("Start again!");
steps = 0;
}
break;
case 2: // State: LED will go on and time will be made visual, then reset.
currentTimeMs = millis();
if ((bttnState == true) && (bttnState == bttnPrevState)) // Check if button is still pressed down
{
if (randomizerFlag == true)
{
randomTimeMs = random(2000,7000);
randomizerFlag = false;
endTimeMs = (waitTimeMs + randomTimeMs);
}
else if ( randomizerFlag == false)
{
if (currentTimeMs >= endTimeMs )
{
ledState = true;
}
}
}
else if ( (bttnState == false) && (currentTimeMs < endTimeMs) ) // do this if button is not pressed anymore & endtime not reached
{
Serial.println("Button Released far too soon!");
Serial.println("Loser!");
Serial.println("Start again!");
digitalWrite(LED, LOW); // Make sure to initialize LED for next round
steps = 0;
}
else if ( (bttnState == false) && (currentTimeMs >= endTimeMs) ) // do this if button is not pressed anymore & endtime is reached
{
Serial.print("Nice! Your time is: "); // Give user information
Serial.println(currentTimeMs);
Serial.print("Press button to start again!");
digitalWrite(LED, LOW); // Make sure to initialize LED for next round
steps = 0;
}
break;
}