Concept:
The concept is using processing and Arduino to test your reaction time when pressing a pressure sensor and a button on the computer as soon as the light next to the pressure sensor turns on. During user testing, we didn’t have this idea yet because of an accident that happened in the lab with our previous project, which led to us making this F1 concept.
Fabrication and Production:
We originally had the idea of making an interactive Whack-a-Mole type of game. The way the game worked was there were 6 sensors for the “moles” with LED lights on them. The lights would turn on randomly and you would have to hit them under 1 second. Every time you hit the right button your score would go up to 10, if you hit the wrong button it would subtract one. this project took sleepless nights to complete and lots of help from professors and fellows to help us put it together. On our last night before we presented, we had practically finished the code, just had to get the score system right, and we got the game to work once. Our user tester Son Dang was able to play the game and enjoyed it. After he played it and everything seemed fine, our Arduino short circuited and my partner claimed to see smoke and a bad smell came from inside of the game. We took it apart and after speaking with Professor Margret, we determined it was an issue with our wiring and the use of copper tape which required 2 exterior power sources. We believe that if we used pressure sensors instead of copper tape we wouldn’t have encounter this issue. Another issue we had that we’re still unclear how it happened was how and LED exploded when one of our friends was helping with our wiring. In the WAM project we used F/M wires, 220k resistors for the LEDs, copper tape with wires, and we used the Laser Cutter in order to make our design for the project. I pained the box red and white for a barn design, and added red splatters on the white to make it more gruel to mimic blood splatter, Professor Margaret later told us that it seemed unrealistic because dried up blood is darker. Something to know for the next project.
After our Arduino short circuited, we decided to change the design from using 6 moles, to only 3 in order to lower the power required but this would result in us rewriting the code and it being already 4am, 5 hours from presenting we decided the best option is to retire the project and start from scratch. Enter the “Are you Faster than an F1 Driver?” Project. It was a very simple project which would provide all necessary materials and requirements in order to fulfill the project requirements. We got the F1 idea from an instagram post that my partner saw when he was scrolling on his phone while we were trying to figure out what to do after our first project failed. The way the interaction works is is using processing and Arduino to test your reaction time when pressing on a pressure sensor and a button on the computer as soon as the light next to the pressure sensor turns on. When you click down it will tell you your time and say if your reaction is faster than an F1 driver. The quickest time we got was set by myself at 178ms. The time automatically stops at 200ms if the button isn’t clicked, this is done to not discourage the tester from not playing the game and instead for them to keep trying to get the shortest time. Our design was built like an F1 formula car. We received a lot of praise for the design of it. On the car we included some cool statistics about different reaction times including Usain Bolt’s speed, the speed of a blink, and an F1 drivers reaction time. The wiring was extremely simple. We used a pressure sensor, and LED light, and a few wires to connect everything together. A lot more simple than the WAM project. The coding for it took the longest time and considering the time constraint we had, along with the lack of professional help considering it was 6am during this. We used help from ChatGPT along with other websites that told us how to connect the two codes.
Conclusions:
The goal for our project was to create an interactive game that tested a users reaction speed. Originally we wanted to do this with the Whack-a-Mole game, however it ended up with our F1 game. Regardless of which project we chose, the goal was accomplished. The audience reacted with our project in a way that we expected which was that they’d understand the goal very quickly and continue to play it until they got their fastest time. Our project directly aligned with my idea of interaction which is that a user creates a certain output by reacting on an input. The user pressed the button (input) and received a time for how quick they did it (output). I think a major aspect of improvement is making the computer screen more creative. We had 3 screens: start screen, time screen, and “press R to restart” screen. We would like to include a leaderboard, make it more creative, and perhaps add music to it.
The main takeaway we had from our project was to not give up. Our failure was the short circuiting of our Arduino. This could have been avoided if we wired things properly and actually organized our wires. We also could have used pressure sensors and made our wiring more simple and spread out with a bigger breadboard. Although our first project failed, we remained focused and determined not to come to class empty handed. We made a brand new project implementing design and code from the old one and got it done.
Appendix
Videos of project:
Order of code:
-
Arduino (F1 project) #include SoftwareSerial serial(2, 3); // RX, TX pins // Pin definitions const int ledPin = 13; const int pressureSensorPin = A0; // Variables int ledState = LOW; int previousSensorValue = 0; unsigned long ledOnTime = 0; void setup() { pinMode(ledPin, OUTPUT); pinMode(pressureSensorPin, INPUT); randomSeed(analogRead(0)); // Turn off the LED initially digitalWrite(ledPin, ledState); Serial.begin(9600); // Start serial communication serial.begin(9600); // Start SoftwareSerial communication } void loop() { // Check if the LED is currently off if (ledState == LOW) { // Generate a random delay before turning on the LED unsigned long delayTime = random(1000, 5000); delay(delayTime); // Turn on the LED ledState = HIGH; digitalWrite(ledPin, ledState); // Store the current time ledOnTime = millis(); // Send signal to Processing serial.write('1'); } // Check if the pressure sensor reading is above 800 int sensorValue = analogRead(pressureSensorPin); if (sensorValue > 800) { // Turn off the LED ledState = LOW; digitalWrite(ledPin, ledState); // Calculate the elapsed time unsigned long elapsedTime = millis() - ledOnTime; // Send the elapsed time to Processing serial.print("Elapsed Time: "); serial.print(elapsedTime); serial.println(" ms"); } // Store the current sensor value previousSensorValue = sensorValue; // Add a small delay to debounce the sensor delay(5); }
-
Processing (F1 project) import processing.serial.*; Serial arduino; boolean gameStarted = false; boolean gameOver = false; int startTime = 0; int bestTime = Integer.MAX_VALUE; boolean showCongratsScreen = false; boolean showFourthPlaceScreen = false; void setup() { size(1200, 1000); textAlign(CENTER, CENTER); textSize(32); // Replace '/dev/cu.usbmodem101' with the appropriate port name for your Arduino arduino = new Serial(this, "/dev/cu.usbmodem101", 9600); arduino.clear(); } void draw() { background(0); if (gameStarted) { if (!gameOver) { int currentTime = millis() - startTime; if (currentTime <= 200) { fill(255); text("Time: " + currentTime + " ms", width / 2, height / 2); } else if (currentTime <= 600) { fill(255); showCongratsScreen = true; if (showCongratsScreen) { text("Congrats! You are faster than an F1 driver!", width / 2, height / 2 - 40); delay(2000); // Delay for 2 seconds showCongratsScreen = false; showFourthPlaceScreen = true; } } else { if (showFourthPlaceScreen) { text("Sorry! You are not faster than an F1 driver!", width / 2, height / 2 - 40); delay(2000); // Delay for 2 seconds showFourthPlaceScreen = false; gameOver = true; } } } else { fill(255); text("Game Over", width / 2, height / 2); text("Press R to restart", width / 2, height / 2 + 40); } } else { fill(255); text("F1 Reaction Test", width / 2, height / 2); text("Press ENTER to start", width / 2, height / 2 + 40); } } void keyPressed() { if (keyCode == ENTER) { gameStarted = true; startTime = millis(); bestTime = Integer.MAX_VALUE; gameOver = false; showCongratsScreen = false; showFourthPlaceScreen = false; } if (key == 'r' || key == 'R') { gameStarted = false; gameOver = false; } } void serialEvent(Serial arduino) { String data = arduino.readStringUntil('\n'); if (data != null) { data = trim(data); int pressureValue = int(data); if (pressureValue > 750) { int currentTime = millis() - startTime; if (currentTime < bestTime) { bestTime = currentTime; } } } }
-
Arduino (Orginal whack-a-mole) #include "SerialRecord.h" SerialRecord writer(6); SerialRecord reader(7); int val2; int val3; int val4; int val5; int val6; int val7; // Pin definitions const int ledPins[] = { 8, 9, 10, 11, 12, 13 }; // Pins for the LED lights const int switchPins[] = { 2, 3, 4, 5, 6, 7 }; // Pins for the switches // Game variables const int numMoles = 6; int activeMole = -1; // Current active mole int score = 0; void setup() { // Initialize LED pins as OUTPUT for (int i = 0; i < numMoles; i++) { pinMode(ledPins[i], OUTPUT); } // Initialize switch pins as INPUT_PULLUP for (int i = 0; i < numMoles; i++) { pinMode(switchPins[i], INPUT_PULLUP); } randomSeed(analogRead(0)); // Seed the random number generator val2 = digitalRead(2); val3 = digitalRead(3); val4 = digitalRead(4); val5 = digitalRead(5); val6 = digitalRead(6); val7 = digitalRead(7); Serial.print(val2); Serial.print(","); Serial.print(val3); Serial.print(","); Serial.print(val4); Serial.print(","); Serial.print(val5); Serial.print(","); Serial.print(val6); Serial.print(","); Serial.print(val7); Serial.println(); writer[0] = val2; writer[1] = val3; writer[2] = val4; writer[3] = val5; writer[4] = val6; writer[5] = val7; } void loop() { // Activate a random mole if (activeMole == -1) { activeMole = random(numMoles); digitalWrite(ledPins[activeMole], HIGH); } // Check for button presses for (int i = 0; i < numMoles; i++) { if (digitalRead(switchPins[i]) == LOW) { if (i == activeMole) { // Successful hit score++; digitalWrite(ledPins[i], LOW); delay(10); // Delay to show hit feedback } else { // Wrong hit score--; } activeMole = -1; // Reset active mole break; } } // Update the score Serial.println("Score: " + String(score)); // Game over condition if (score >= 10) { // Game over resetGame(); } delay(10); // Delay between loops } void resetGame() { // Reset game variables score = 0; activeMole = -1; // Turn off all LEDs for (int i = 0; i < numMoles; i++) { digitalWrite(ledPins[i], LOW); } // Wait for a brief moment before starting a new iteration delay(1000); }