We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I'm programming my arduino to make a reaction time game as a sketch for a more serious scientific study. It works like this
I've managed to work ok all steps from 1 through 5, but I cannot see how to get to work step 6. The way the code is written, after 5 it loops back to 1, infinitely. Any ideas on how to solve this?
/* REACTION TIME (with 2 leds) v2.1 beta Luis Andrés Gonzalez Reaction time original version from http://www.instructables.com/id/Arduino-Reaction-Time-Tester/?ALLSTEPS Send data to processing via the Serial Port original from By Elaine Laguerta http://url/of/online/tutorial.cc */ const int switchPin = 6; // pin where the button will be connected const int ledPin1 = 2 ; // Left LED const int ledPin2 = 8 ; // Middle LED const int ledPin3 = 12; // Right LED // declare some variables: boolean lastButton = LOW; boolean currentButton = LOW; boolean gameStarted = false; // true if game has started boolean timerFlag = false; // true if timer is running long startTime; long endTime; int randomSeconds; long beginTime; float elapsedTime; int maxTimer = 5 * 1000; float totalTime; void setup() { // Setup button and LEDs: pinMode(switchPin, INPUT); pinMode(ledPin1, OUTPUT); pinMode(ledPin2, OUTPUT); pinMode(ledPin3, OUTPUT); // Begin serial communication Serial.begin(9600); } void loop() { // Check https://www.arduino.cc/en/Tutorial/StateChangeDetection to understand the following code. if ((millis() - beginTime) > (randomSeconds + maxTimer)) { Stop(); //resets game: gameStarted = false; timerFlag = false; currentButton = LOW; lastButton = LOW; Blink(2); Serial.println("message"); } // read the pushbutton input pin in the current loop: currentButton = buttonPressed(lastButton); // if there's a change from low to high (comparing last and current loop) then the following is true if (currentButton == HIGH && lastButton == LOW) { // outer IF if (gameStarted == false) { // middle IF. starts the game gameStarted = true; randomSeconds = random(2, 5) * 1000; // generates a random number of seconds between 3 and 8 Blink(1); Serial.println("9090"); // signal code for start sound beginTime = millis(); } else { if ((millis() - beginTime) >= randomSeconds) { Stop(); gameStarted = false; timerFlag = false; } else if ((millis() - beginTime) < randomSeconds ) { gameStarted = false; timerFlag = false; Serial.println("1010"); // signal code for early response Blink(3); } } } // end outer if // save the current state as the last state, //for next time through the loop lastButton = currentButton; // If true, starts the response time timer and lights up the LED if (gameStarted == true && (millis() - beginTime) >= randomSeconds && timerFlag == false) { timerFlag = true; Start(); } } // end void loop //=========================================================================================== boolean buttonPressed(boolean last) { //button debouncing function boolean current = digitalRead(switchPin); if (last != current) { delay(5); current = digitalRead(switchPin); } return current; } void Start() { startTime = millis(); Light(ledPin1, "on"); } void Stop() { if ( (millis() - beginTime)
Answers
Somehow your code is not complete at the very end
Anyway. I suggest you work with states. Like states of a program
Google state within the forum.
You can use
if(state==stateWaitForRestart) {
etc.
When you define stateWaitForRestart as
int stateWaitForRestart=6;
Before setup()
make an if else if clause for each state
Nothing I repeat nothing is allowed outside the if ... else if {...} clause in draw()
but thus you get a very readable code and all things will fall into place
Just handle the states and the Transformation between them right
Thanks @Chrisir. I've followed your advice and from everyone else and I've revamped the code to deal with states. Now the problem is that I can't manage to make the reaction timer to work. It shows an ever-increasing ammount of time.
In line 100 the else makes no sense.
I feel the version is still too complicated
You need more states: activegame_begin // led off
activegame_waiting // led on
Also you still have code outside if state== etc.
Also you have delay (1000) you shouldn't..... handle this with new states
The main goal is to make things work the way it was sketched. This program is never intended to work this way, so I think adding more states is an extra work for no purpose.
The
if
around theelse
in line 100 is the one that checks if the button is pressed before the light is turned on. Is not as elegant as declaring a state likeLIGHT_ON
but I like the fact that relies directly on the fact that the light is actually turned on.Anyways, you're right the code is messy. I solved the issue around the timer and remove some clutter. Here's the last code that does the trick.
Great that you accomplished it!
I really think states help to make a program better. You can hunt errors easier, you got better compartmentalization / sections ...
It's better readable, better maintainable
States are not a goal i itself but only a tool. A powerful tool.
You can auto-format your code with ctrl-t btw (iirc for arduino as well)
Since those above are also constants, just like TIMEOUT_MILLISECONDS, STAND_BY, OUTPUT, etc., the convention dictates they should be entirely capitalized too! Either as
const
or#define
: ;;)