// software for http://www.kreativekiste.de/elektro/dem-heissen-draht-auf-der-spur
// developed by Timo Denk (Nov 2014)
//
// wiring: 
// 0: start
// 1: stop
// 2: mistake
// 3: buzzer
// A0: penalty time
// A4: display SDA
// A5: display SCL
// libraries
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,20,4);
const byte startPin = 0, stopPin = 1, mistakePin = 2, buzzerPin = 3, penaltyTimePin = A0;
const byte minPenaltyTime = 1, maxPenaltyTime = 17; // [t] = 1 s
const String penaltyTimeString = "Fehler", finalTimeString = "Endzeit", timeString = "Zeit", commercialString = "www.kreativekiste.de", mistakeString = "Berührt!!!", totalTime = "Gesamtzeit";
long millisStart, millisEnd;
int mistakes, penaltyTime, lastPenaltyTime;
void setup() {
 lcd.init();
 lcd.backlight();
 
 pinMode(startPin, INPUT); 
 pinMode(stopPin, INPUT);
 pinMode(mistakePin, INPUT);
 pinMode(buzzerPin, OUTPUT); 
 digitalWrite(buzzerPin, LOW); 
 digitalWrite(startPin, HIGH);
 digitalWrite(stopPin, HIGH);
 digitalWrite(mistakePin, HIGH);
}
void loop() {
 clearScreen();
 printStringCenter(1, "Heisser Draht");
printStringCenter(2, "Strafzeit einstellen"); 
 lastPenaltyTime = 0, penaltyTime = 0; 
 // waiting for game to start
 while (digitalRead(startPin) == HIGH) {
 penaltyTime = (byte)round(map(analogRead(penaltyTimePin), 0, 1023, minPenaltyTime, maxPenaltyTime));
 if (penaltyTime != lastPenaltyTime) {
 clearRow(3); 
 printStringCenter(3, String(penaltyTime) + " s");
 lastPenaltyTime = penaltyTime; 
 }
 }
 
 // game running
 millisStart = millis(); 
 clearScreen();
 mistakes = 0; 
 while (digitalRead(stopPin) == HIGH) {
 // check for mistakes
 printStatusOnScreen();
 if (digitalRead(mistakePin) == LOW) {
 mistakes++; 
 digitalWrite(buzzerPin, HIGH); 
 printStatusOnScreen(); 
 delay(500);
 digitalWrite(buzzerPin, LOW);
 }
 delay(10); 
 }
 
 // game finished
 millisEnd = millis(); 
 clearScreen();
 clearRow(0);
 printStringCenter(0, "Spiel beendet!");
 printStatusOnScreen();
 delay(10000);
}
void printStatusOnScreen() {
 int playingTime = round((millis() - millisStart)/1000), penaltyTimeSum = mistakes * penaltyTime;
 printStringCenter(1, "Spielzeit: " + sec2MinSecString(playingTime)); 
 printStringCenter(2, "Fehler: " + String(mistakes) + " x " + String(penaltyTime) + "s"); 
 printStringCenter(3, "Gesamt: " + sec2MinSecString(playingTime + penaltyTimeSum)); 
}
void showCommercial() {
 clearRow(0); 
 printStringCenter(0, commercialString); 
}
void clearScreen() {
 for (byte i = 0; i < 4; i++)
 clearRow(i); 
 
 showCommercial();
}
void printStringCenter(byte row, String string) {
 lcd.setCursor((int)((20 - string.length()) / 2), row); 
 lcd.print(string); 
}
void clearRow(byte row) {
 lcd.setCursor(0, row); 
 lcd.print(" "); 
}
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 + " ";
}

