// software for http://www.kreativekiste.de/wasserfussball-mit-spritzpistolen-bauen // developed by Timo Denk (Aug 2014) // optimized for Arduino Micro. // // wiring: // 12: goal 1 // 11: goal 2 // 10: start button // 5: buzzer // 4: restart // A1: game time // Arduino Micro, 2: display SDA, Arduino Uno, A4 display SDA // Arduino Micro, 3: display SCL, Arduino Uno, A5 3: display SCL #include #include LiquidCrystal_I2C lcd(0x3F,20,4); const byte goal1Pin = 12, goal2Pin = 11, startButtonPin = 10, gameTimePin = A1, buzzerPin = 5, restartPin = 9; // pins const byte minGameLength = 1, maxGameLength = 10; // [t] = 1 min const String playingTimeString = "Spielzeit", finalScoreString = "Endstand", timeString = "Zeit: ", commercialString = "www.kreativekiste.de", goalString = "TOOOOOOR", currentScoreString = "Spielstand: "; long gameLength; // [t] = 1 min int goals[2]; long millisStart, millisEnd; bool showGameFinishedScreen; void setup () { Serial.begin(9600); lcd.init(); lcd.backlight(); pinMode(goal1Pin, INPUT); pinMode(goal2Pin, INPUT); pinMode(startButtonPin, INPUT); pinMode(restartPin, INPUT); pinMode(buzzerPin, OUTPUT); digitalWrite(buzzerPin, LOW); } void loop () { // waiting for game start clearScreen(); showCommercial(); printStringCenter(2, playingTimeString); long lastGameLength = 0; while (digitalRead(startButtonPin) == LOW) { gameLength = map(analogRead(gameTimePin), 500, 1000, minGameLength, maxGameLength+1); if (lastGameLength != gameLength) { clearRow(3); printStringCenter(3, String(gameLength) + " min"); lastGameLength = gameLength; } } // game running goals[0] = 0; goals[1] = 0; millisStart = millis(); millisEnd = millisStart + (long)(gameLength * 60 * 1000); // convert game length from minutes to milliseconds Serial.println(millisStart); Serial.println(gameLength); Serial.println(millisEnd); clearScreen(); gameRunningScreen(); showGameFinishedScreen = true; while (millis() < millisEnd) { lcd.setCursor(timeString.length(), 2); lcd.print(sec2MinSecString((int)((millisEnd - millis()) / 1000))); lcd.setCursor(currentScoreString.length(), 3); lcd.print(scoreString()); if (digitalRead(goal1Pin) == LOW) { goals[0]++; goalScreen(); while (digitalRead(goal1Pin) == LOW) { ; } } if (digitalRead(goal2Pin) == LOW) { goals[1]++; goalScreen(); while (digitalRead(goal2Pin) == LOW) { ; } } if (digitalRead(restartPin) == HIGH) { millisEnd = 0; showGameFinishedScreen = false; } delay(10); } // game finished if (showGameFinishedScreen) { clearScreen(); showCommercial(); printStringCenter(2, finalScoreString); printStringCenter(3, scoreString()); delay(10000); } } String sec2MinSecString(int input) { // converts seconds to a string like "minutes:seconds" String minutes = String((int)(input / 60)); String seconds = String(input % 60); if (seconds.length() == 1) seconds = "0" + seconds; //if (minutes.length() == 1) // minutes = "0" + minutes; return minutes + ":" + seconds + " "; } String scoreString() { return String(goals[0]) + ":" + String(goals[1]); } void showCommercial() { clearRow(0); printStringCenter(0, commercialString); } void clearScreen() { for (byte i = 0; i < 4; i++) clearRow(i); } void printStringCenter(byte row, String string) { lcd.setCursor((int)((20 - string.length()) / 2), row); lcd.print(string); } void goalScreen() { digitalWrite(buzzerPin, HIGH); long millisPauseStart = millis(); clearScreen(); printStringCenter(1, goalString); printStringCenter(3, scoreString()); delay(3000); digitalWrite(buzzerPin, LOW); gameRunningScreen(); long millisPauseEnd = millis(); millisEnd += millisPauseEnd - millisPauseStart; // pause game time while goal screen is shown } void gameRunningScreen() { clearScreen(); showCommercial(); lcd.setCursor(0, 2); lcd.print(timeString); lcd.setCursor(0, 3); lcd.print(currentScoreString); } void clearRow(byte row) { lcd.setCursor(0, row); lcd.print(" "); }