Introduction
In this tutorial I combine three previous videos and write some code to create an Arduino based Reaction Timer. The entire circuit is built on a breadboard using an ATmega328P on its own, which is combined with a Newhaven Display LCD Module that has an RGB backlight. I work through the code in some detail and explain how to write the code for the reaction timer. At the end of the video I provide links to the previous videos that show how to build the three individual circuits: Breadboard PSU, Arduino on a Breadboard and Arduino LCD Tutorial.
[youtube id=”o8V3zl6pmLw” width=”600″ height=”350″]
The Code
The code for this application is at (Please note it was developed on a 2011 version of the Arduino development environment, so changes to the libraries may introduce errors):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
/* Arduino Reaction Timer using an RGB LCD 16x2 Character Display Derek Molloy, DCU, Ireland. Using LCD library from: http://www.arduino.cc/en/Tutorial/LiquidCrystal */ #include <LiquidCrystal.h> // include LCD library // Set up the display with 4 bits - R/W tied to GND LiquidCrystal lcd(13, 12, 5, 6, 7, 8); // RS, E, D4-D7 int lcdRedPWMPin = 11; // red channel of the RGB backlight int lcdGreenPWMPin = 10; // green channel of the RGB backlight int lcdBluePWMPin = 9; // blue channel of the RGB backlight int ledPin = 2; // red stop LED int buttonPin = 3; // reaction timer button // States of execution long randomDelayTime; // holds the random time amount boolean prepareState = true; // in introduction mode boolean isTiming = false; // timing the press state long timerStartMillis; // the time when the timer started long timerEndMillis; // the time when the timer finished // A function to set the backlight colour using rgb values void setDisplayRGB(int r, int g, int b) { analogWrite(lcdRedPWMPin, r); // using PWM pins, means any shade analogWrite(lcdGreenPWMPin, g); // of red, green, blue analogWrite(lcdBluePWMPin, b); // 2^24 combinations } // Setup function - called only once void setup() { pinMode(ledPin, OUTPUT); // red LED is an output pinMode(buttonPin, INPUT); // button is an input setDisplayRGB(255,255,255); // white display lcd.begin(16, 2); // 16 Columns by 2 Rows randomSeed(analogRead(0)); // use unconnected pin to seed random sequence } void loop() { if(prepareState){ // prepare state - give out the instruction to press button lcd.setCursor(0,0); // set cursor to 0,0 (top left) lcd.print("Reaction Tester:"); // string on the top row lcd.setCursor(0,1); // next row lcd.print(" [Press Button] "); // string on the next row if (digitalRead(buttonPin)==true) // if the button is pressed { lcd.clear(); // clear the display lcd.setCursor(0,0); lcd.print("---- Ready -----"); randomDelayTime = random(10000); // this is the random amount to be used 0-10 seconds while (digitalRead(buttonPin)==true) {} // wait until the button is released prepareState = false; // finished prepare state - lets move on } } else // not in prepare state { if (!isTiming) // the timer isn't running, so we are pausing for random amount { delay(randomDelayTime); // delay for the random amount digitalWrite(ledPin, HIGH); // when finished - set red LED high setDisplayRGB(255,0,0); // set the LCD backlight to be red lcd.setCursor(0,0); // press now message lcd.print(" <PRESS NOW> "); isTiming = true; // now we are ready to start timing reactions timerStartMillis = millis(); // get the current time } else // now we are timing person's reaction { if (digitalRead(buttonPin)==true) // when they press the button { timerEndMillis = millis(); // get the current time digitalWrite(ledPin, LOW); // turn off the red led long difference = timerEndMillis - timerStartMillis; // time taken is difference between times lcd.clear(); // clear the LCD lcd.setCursor(0,0); if (difference == 0) // If the difference is 0 they held the button - or are supermen! { setDisplayRGB(255,0,0); // Error message in red lcd.print(" Shenanigans "); lcd.setCursor(5,1); lcd.print("Afoot"); } else // valid time { setDisplayRGB(0,255,0); // Final message in green lcd.print("Your time was:"); lcd.setCursor(0,1); lcd.print(difference); lcd.print("ms"); // milliseconds } delay(5000); // leave the message on the screen for 5 seconds isTiming = false; // ready to start timing again prepareState = true; // ready to start all over setDisplayRGB(255,255,255); // set the LCD backlight to white } } } } |