Introduction: Make a Reflex Measurement Device With SunFounder Nano
When I was reading some articles about games and game design, I came across an old article. Immediately the idea came to my mind, how can I measure the reaction/reflex of someone? At first, to define reflex time is, it’s the time taken to process an input (like hearing an alarm or seeing an object), processing it, and reacting accordingly.
So, this should be easy :D. It only needs a way of measuring the time of a response to a certain alarm, and my initial thought was using a single button and a buzzer. When the buzzer goes off, you press the button and that’s it. But then I thought it would be much better if I added two more buttons to have the player pressing those buttons until the buzzer goes off, this way the response distance is constant. Getting that clear, I can design the circuit and bring the measurement tool into reality.
Step 1: Preparation
SunFounder Arduino Nano http://bit.ly/2fwJNnj
USB Cable
3 x Push button (2 black, 1 yellow)
I2C LCD1602 http://bit.ly/2yShzvcLCD
5V Buzzer
Red LED
Jumper wires
Breadboard
Step 2: Connecting the Hardware
GND - SW1 - Pin 2 of Nano
GND - SW2 - Pin 3 of Nano
GND - SW3 - Pin 4 of Nano
GND - LED - Pin 5 of Nano
GND - Buzzer - Pin 6 of Nano
On the I2C LCD:
Board I2C / TWI pins
Uno, Ethernet A4 (SDA), A5 (SCL)
Mega2560 20 (SDA), 21 (SCL)
Leonardo 2 (SDA), 3 (SCL)
Due 20 (SDA), 21 (SCL), SDA1, SCL1
Nano 20 (SDA), 21 (SCL)
(refer to the Wire page on Arduino.cc: https://www.arduino.cc/en/Reference/Wire )
Note: Leave A7 on the Arduino unconnected as it’s used for seeding a random number, for like storing data temporally.
Step 3: Upload the Code
For the
initial idea that I had, the code should be something like this:
SETUP:
- Initialize the inputs, the outputs, and the LCD
- Initialize the randomSeed with a random signal
LOOP:
- Reset everything and start a new game
- Generate a random wait time
- Wait for the player to get ready (Both SW1 and SW2 are pressed and SW3 is not)
- If the player is ready, then start the random wait time
- During the random wait time, if the player releases any of the buttons or tries to press the SW3 button, he loses “Game Over”, and then a new game starts
- When the wait time is out, signal the LED and Buzzer
- Mark the time, and wait for the player to press the SW3
- When the SW3 is pressed, calculate the reflex time and display it
- Wait for some time before starting a new game
<p>#include <br>#include </p><p>LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display</p><p>const int thSW1 = 2; const int thSW2 = 3; const int rflSW = 4; const int opled = 5; const int obuzz = 6;</p><p>const long baseTime = 1000; const long randRange = 1000; long waitTime = 0; long reflexTime = 0;</p><p>#define DEBUG 1</p><p>void setup() { pinMode(thSW1, INPUT_PULLUP); pinMode(thSW2, INPUT_PULLUP); pinMode(rflSW, INPUT_PULLUP); pinMode(opled, OUTPUT); pinMode(obuzz, OUTPUT);</p><p> lcd.init(); lcd.backlight();</p><p> randomSeed(analogRead(7));</p><p>#if DEBUG Serial.begin(9600); #endif }</p><p>void loop() { //0 - reset all digitalWrite(opled, LOW); digitalWrite(obuzz, LOW); lcd.clear(); lcd.print("New Game"); delay(1000); //1 - generate a random wait time waitTime = baseTime + random(randRange) * 10; #if DEBUG Serial.print("Wait time generated: "); Serial.println(waitTime / 1000.0); #endif //2 - wait for the player to get ready lcd.clear(); lcd.print("please put your"); lcd.setCursor(0, 1); lcd.print("thumbs in place"); #if DEBUG Serial.print("pins"); Serial.println(digitalRead(thSW1) * 4 + digitalRead(thSW2) * 2 + digitalRead(rflSW) * 1); #endif while (digitalRead(thSW1) * 4 + digitalRead(thSW2) * 2 + digitalRead(rflSW) * 1 != 1); //3 - wait and make sure thumbs are not removed lcd.clear(); lcd.print("press the button"); lcd.setCursor(0, 1); lcd.print("after the signal"); long temp = millis(); bool gameNotOver = true; while ((temp + waitTime > millis()) && gameNotOver) { if (digitalRead(thSW1) || digitalRead(thSW2) || !digitalRead(rflSW)) gameNotOver = false; } #if DEBUG Serial.print("GameOver: "); Serial.println(gameNotOver); #endif if (gameNotOver) { //4 - mark the time long reflexStart = millis(); //5 - signal buzz/light digitalWrite(opled, HIGH); digitalWrite(obuzz, HIGH); //6 - wait for the press on the reflex button while (digitalRead(rflSW)); //7 - mark the time reflexTime = millis() - reflexStart; //8 - display it lcd.clear(); lcd.print("Your reflex time"); lcd.setCursor(0, 1); lcd.print(reflexTime); lcd.print(" ms"); digitalWrite(opled, LOW); digitalWrite(obuzz, LOW); delay(3000); } else { // GAME OVER lcd.clear(); lcd.print(" GAME"); lcd.setCursor(0, 1); lcd.print(" OVER"); delay(5000); } }</p>
Step 4: Simple to Measure
Now I put my two fingers, here the forefinger and the middle,
on the black buttons. Then press them one by one or altogether. The message will appear on the LCD, "press the button after the signal". So just wait and keep the fingers onside. After a few seconds, the buzzer beeps high abruptly. At once I need to press the yellow button very quickly. So the reflex time just gets measured and shown on the LCD: 447ms…that's not bad...but, I'll try again! And again….
Oh, don't forget to call your friends and families to race a game.
Step 5: Conclusion
There is room for improvement, for example:
- An enclosure
- Keeping and displaying the best score or personal record
- Adding more options like:
- Training a specific hand (for example asking the player to use the right had only or left hand only)
- Choosing the alarm type (LED only, Buzzer only, or others)
- Add a battery, so I won’t need to connect it using USB
Step 6: DIYed a Larger Reflex Measurement Set!
Another more neat set! (need a plywood or hard cardboard and laser cutting tool; to make a larger set, need 3 bigger push buttons)
I used a scrap piece of plywood, cut it using a laser cutter to a 15*15cm with three mounting holes for the buttons. (the distance between the lower 2 holes depends on your finger length)
Then organized the wires a bit (similar LCD but with a potentiometer), and insert the three buttons from the bottom of the plywood. Set the two red ones at lower two holes and the green one at top. The green one will be the major one to test your response time.