#include #include #include #include #include // Set the LCD address to 0x27 for a 16 chars and 2 line display LiquidCrystal_I2C lcd(0x27, 16, 2); #ifndef APSSID #define APSSID "DUEL" //#define APPSK "duel" #endif IPAddress apIP(192, 168, 1, 1); /* Set these to your desired credentials. */ const char *ssid = APSSID; //const char *password = APPSK; ESP8266WebServer server(80); const int sensor1Pin = 14; const int sensor2Pin = 12; const int relayRed = 1; const int relayGreen = 13; const int relayWinner1 = 0; const int relayWinner2 = 2; const int startButtonIn = 3; // Create variables to store the reaction times for both players float player1ReactionTime = 0; float player2ReactionTime = 0; bool finished = false; bool webTrigger = false; int sensitivity = 300; void handleRoot() { Serial.println("HTTP root called"); String button = finished ? "RESET" : "START"; char temp[800]; snprintf(temp, 800,"\ \ \ DUEL\ \ \

Player 1

Player 2

%.2f

\ %.2f

\ Click here to %s GAME.


Click here to REFRESH.\


SENSITIVITY

LOW EXTRA_LOW EXTRA_EXTRA_LOW

\ \ ", player1ReactionTime, player2ReactionTime, button ); server.send(200, "text/html", temp); } void setup() { delay(1000); Serial.begin(115200); Serial.setDebugOutput(false); Serial.println(); Serial.println("Configuring access point..."); WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); WiFi.softAP(ssid); //WiFi.softAP(ssid, password); IPAddress myIP = WiFi.softAPIP(); Serial.println("AP IP address: "); Serial.println(myIP); server.on("/", handleRoot); server.on("/H", []() { Serial.println("HTTP /H called"); webTrigger = true; server.send(200, "text/html", "

OK. Click here to REFRESH.

"); }); server.on("/L", []() { Serial.println("HTTP /L called"); sensitivity = 500; server.send(200, "text/html", "

OK Sensitivity LOW. Click here to REFRESH.

"); reset(); }); server.on("/X", []() { Serial.println("HTTP /X called"); sensitivity = 800; server.send(200, "text/html", "

OK Sensitivity EXTRA LOW. Click here to REFRESH.

"); reset(); }); server.on("/Y", []() { Serial.println("HTTP /Y called"); sensitivity = 1000; server.send(200, "text/html", "

OK Sensitivity EXTRA EXTRA LOW. Click here to REFRESH.

"); reset(); }); server.begin(); Serial.println("HTTP server started"); // initialize the LCD lcd.begin(); // Turn on the blacklight and print a message. lcd.backlight(); lcd.print("SETUP INIT"); Serial.println("Configuring PINOUT"); pinMode(sensor1Pin, INPUT); pinMode(sensor2Pin, INPUT); pinMode(startButtonIn, INPUT); pinMode(relayRed, OUTPUT); pinMode(relayGreen, OUTPUT); pinMode(relayWinner1, OUTPUT); pinMode(relayWinner2, OUTPUT); Serial.println("Lights ON"); delay(5000); digitalWrite(relayGreen, LOW); webTrigger = false; reset(); } void loop() { server.handleClient(); if (digitalRead(startButtonIn) == LOW || webTrigger == true) { webTrigger = false; Serial.println("Button pressed - starting Game"); startGame(); } } void reset() { webTrigger = false; finished = false; player1ReactionTime = 0; player2ReactionTime = 0; // Display the "PUSH BUTTON to Start" message on the LCD Serial.println("PUSH BUTTON to Start"); lcd.clear(); lcd.setCursor(0, 0); lcd.print("PUSH BUTTON"); lcd.setCursor(0, 1); lcd.print("TO START GAME"); if (sensitivity == 500) { Serial.println("Sensitivity - LOW"); lcd.print(" LO"); } else if (sensitivity == 800) { Serial.println("Sensitivity - EXTRA LOW"); lcd.print(" XL"); } else if (sensitivity == 1000) { Serial.println("Sensitivity - EXTRA EXTRA LOW"); lcd.print(" XX"); } else { Serial.println("Sensitivity - HIGH"); lcd.print(" HI"); } digitalWrite(relayRed, HIGH); digitalWrite(relayGreen, HIGH); digitalWrite(relayWinner1, HIGH); digitalWrite(relayWinner2, HIGH); } void ready() { // Display the "Ready" message on the LCD Serial.println("Ready"); lcd.clear(); lcd.setCursor(0, 0); lcd.print("READY"); lcd.setCursor(0, 1); lcd.print("!!!"); digitalWrite(relayRed, HIGH); digitalWrite(relayGreen, HIGH); digitalWrite(relayWinner1, LOW); digitalWrite(relayWinner2, LOW); delay(3000); } void set() { // Display the "Set" message on the LCD Serial.println("Set"); lcd.clear(); lcd.setCursor(0, 0); lcd.print("SET"); lcd.setCursor(0, 1); lcd.print("!!!"); digitalWrite(relayRed, LOW); digitalWrite(relayGreen, HIGH); digitalWrite(relayWinner1, HIGH); digitalWrite(relayWinner2, HIGH); delay(3000); } void go() { // Generate a random number on the back end to determine when the "GO!" message will be displayed int delayTime = random(1000, 5000); // Wait for the delayTime before displaying the "GO!" message delay(delayTime); // Display the "GO!" message on the LCD Serial.println("GO!"); lcd.clear(); lcd.setCursor(0, 0); lcd.print("GO"); lcd.setCursor(0, 1); lcd.print("!!!"); digitalWrite(relayRed, HIGH); digitalWrite(relayGreen, LOW); digitalWrite(relayWinner1, HIGH); digitalWrite(relayWinner2, HIGH); } void winner1(float player1ReactionTime, float player2ReactionTime) { digitalWrite(relayRed, LOW); digitalWrite(relayGreen, HIGH); digitalWrite(relayWinner1, LOW); digitalWrite(relayWinner2, HIGH); Serial.println("Winner: Sensor 1"); Serial.println("Reaction Time: Sensor 1"); Serial.println(player1ReactionTime); Serial.println("Loser: Sensor 2"); Serial.println(player2ReactionTime); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Winner <- Looser"); lcd.setCursor(0, 1); lcd.print(player1ReactionTime); lcd.print(" "); lcd.print(player2ReactionTime); } void winner2(float player1ReactionTime, float player2ReactionTime) { digitalWrite(relayRed, LOW); digitalWrite(relayGreen, HIGH); digitalWrite(relayWinner1, HIGH); digitalWrite(relayWinner2, LOW); Serial.println("Winner: Sensor 2"); Serial.println("Reaction Time: Sensor 2"); Serial.println(player2ReactionTime); Serial.println("Loser: Sensor 1"); Serial.println(player1ReactionTime); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Looser <- Winner"); lcd.setCursor(0, 1); lcd.print(player1ReactionTime); lcd.print(" "); lcd.print(player2ReactionTime); } void nowinner(float player1ReactionTime, float player2ReactionTime) { digitalWrite(relayRed, LOW); digitalWrite(relayGreen, HIGH); digitalWrite(relayWinner1, LOW); digitalWrite(relayWinner2, LOW); Serial.println("TIE"); Serial.println("Reaction Time: Sensor 2"); Serial.println(player2ReactionTime); Serial.println("Reaction Time: Sensor 1"); Serial.println(player1ReactionTime); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Looser -- Looser"); lcd.setCursor(0, 1); lcd.print(player1ReactionTime); lcd.print(" "); lcd.print(player2ReactionTime); } void hit1(float player1ReactionTime) { Serial.println("Hit: Sensor 1"); Serial.println("Reaction Time: Sensor 1"); Serial.println(player1ReactionTime); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Left -- Right"); lcd.setCursor(0, 1); lcd.print(player1ReactionTime); } void hit2(float player2ReactionTime) { Serial.println("Hit: Sensor 2"); Serial.println("Reaction Time: Sensor 2"); Serial.println(player2ReactionTime); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Left -- Right"); lcd.setCursor(0, 1); lcd.print(" "); lcd.print(player2ReactionTime); } void startGame() { ready(); set(); go(); // Start the reaction time timer unsigned long startTime = millis(); // Create variables to store the state of each piezoelectric sensor int sensor1State = LOW; int sensor2State = LOW; // Wait for a response from both piezoelectric sensors and record their reaction times while (sensor1State == LOW || sensor2State == LOW) { if ((millis() - startTime) > 1000) { digitalWrite(relayGreen, HIGH); } // New condition: Set state to HIGH if time exceeds 5 seconds if ((millis() - startTime) > 5000) { float endTime = (millis() - startTime) / 1000.0; if (sensor1State == LOW) { sensor1State = HIGH; player1ReactionTime = endTime; } if (sensor2State == LOW) { sensor2State = HIGH; player2ReactionTime = endTime; } } if (analogRead(sensor1Pin) > sensitivity && sensor1State == LOW) { sensor1State = HIGH; player1ReactionTime = (millis() - startTime) / 1000.0; hit1(player1ReactionTime); } if (analogRead(sensor2Pin) > sensitivity && sensor2State == LOW) { sensor2State = HIGH; player2ReactionTime = (millis() - startTime) / 1000.0; hit2(player2ReactionTime); } yield(); } // Determine the winner and display the result on the LCD, along with the reaction times in seconds if (player1ReactionTime < player2ReactionTime) { winner1(player1ReactionTime, player2ReactionTime); } else if (player1ReactionTime > player2ReactionTime) { winner2(player1ReactionTime, player2ReactionTime); } else { nowinner(player1ReactionTime, player2ReactionTime); } Serial.println("PUSH BUTTON to Reset"); finished = true; while (digitalRead(startButtonIn) == HIGH && webTrigger == false) { server.handleClient(); yield(); } endGame(); } void endGame() { Serial.println("reseting ..."); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Reseting"); lcd.setCursor(0, 1); lcd.print("..."); digitalWrite(relayRed, HIGH); delay(1000); digitalWrite(relayRed, LOW); delay(1000); digitalWrite(relayRed, HIGH); delay(1000); reset(); }