/* Chronometer gemäss Aufgabe 3: * Start und Stop-Taste für Zeitmessung. Die gestoppte Zeit * wird laufend und bei Betätigung der Stop-Taste angezeigt. * Zusätzlich werden die besten fünf gemessenen Zeiten inkl. deren Rang angezeigt. * Per Next-Taste kann durch die Zeiten "geblättert" werden. * Die Zeiten bleiben bei ausgeschaltetem Arduino erhalten (im EEPROM gespeichert). * Nur wenn die Reset-Taste betätigt wird, werden alle Zeiten zurückgesetzt. */ #include #include #include #include // create object of class LiquidCrytal_I22 and define parametes: LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Konstanten festlegen (für bessere Lesbarkeit des Codes): #define startPin 5 #define stopPin 4 #define resetPin 3 #define nextPin 2 #define debounce 150 // Wartezeit zur "Entprellung" der Tasten (Millisekunden) // Folgende Variable speichert den Status der Zeitmessung bool timeRunning; // Folgende Variablen speichern die Zeiten in Millisekunden: unsigned long startTime; unsigned long currentTime; unsigned long stoppedTime; unsigned long bestTimes[5]; // Array mit den besten fünf Zeiten unsigned long tempTime; // Zwischenspeicher für den Wertetausch bei der Sortierung // Folgende Variablen dienen der Anzeige im Format MM:SS:HH: unsigned int minutes; unsigned int seconds; unsigned int hundreds; char timeString[] = "00:00:00"; // Variable für den anzuzeigenden Rang: uint8_t rank; // Array für EEPROM-Adressen: int addresses[5] = {0,3,6,9,12}; void setup() { /*Für Debugging: pinMode(13, OUTPUT); Serial.begin(9600);*/ // Eingänge definieren: pinMode(startPin, INPUT_PULLUP); pinMode(stopPin, INPUT_PULLUP); pinMode(resetPin, INPUT_PULLUP); pinMode(nextPin, INPUT_PULLUP); // Variablen definieren bzw. auf Initial-Werte setzen: timeRunning = 0; startTime = 0; currentTime = 0; stoppedTime = 0; rank = 0; // Beste fünf Zeiten aus EEPROM lesen: readTimesEEP(); // Anzeige vorbereiten: lcd.begin(16,2); // initialize the lcd lcd.clear(); lcd.setCursor(0, 0); lcd.print("Jetzt:"); lcd.setCursor(0, 1); lcd.print("Rang :"); updateTimes(); } void loop() { if(timeRunning == 1){ currentTime = millis() - startTime; lcd.setCursor(8, 0); showTime(currentTime); } if (digitalRead(startPin) == LOW) { delay(debounce); startTime = millis(); stoppedTime = 0; currentTime = 0; timeRunning = 1; } if (digitalRead(stopPin) == LOW) { delay(debounce); stoppedTime = millis() - startTime; // Falls gestoppte Zeit kleiner als fünft-beste Zeit ODER falls diese = 0: if(stoppedTime < bestTimes[4] || bestTimes[4] == 0){ bestTimes[4] = stoppedTime; sortTimes(); storeTimesEEP(); } updateTimes(); timeRunning = 0; } if(digitalRead(resetPin) == LOW) { delay(debounce); stoppedTime = 0; for(uint8_t i=0;i<5;i++){ bestTimes[i] = 0; } updateTimes(); storeTimesEEP(); timeRunning = 0; } if(digitalRead(nextPin) == LOW){ delay(debounce); if(rank == 4){ rank = 0; } else{ rank +=1; } updateTimes(); } } void sortTimes(){ // Nullen im Array temporär durch hohe Zahlen ersetzen: for(uint8_t i = 0; i<5;i++){ if(bestTimes[i] == 0){ bestTimes[i] = 4000000; // max. Wert zu stoppen = 3'599'999 } } // Bubblesort: for(uint8_t n = 4; n>0; n--){ for(uint8_t i = 0; ibestTimes[i+1]){ // ...beide Werte tauschen: tempTime = bestTimes[i]; bestTimes[i] = bestTimes[i+1]; bestTimes[i+1] = tempTime; } } } // Hohe Zahlen im Array wieder durch Nullen ersetzen: for(uint8_t i = 0; i<5;i++){ if(bestTimes[i] == 4000000){ bestTimes[i] = 0; // max. Wert zu stoppen = 3'599'999 } } } void updateTimes(){ lcd.setCursor(8, 0); showTime(stoppedTime); lcd.setCursor(5,1); lcd.print(rank+1); lcd.setCursor(8, 1); showTime(bestTimes[rank]); } void showTime(unsigned long timeMS){ // Minuten, Sekunden und Hundertstel berechnen: minutes = timeMS/60000; seconds = (timeMS-minutes*60000)/1000; hundreds = (timeMS-minutes*60000-seconds*1000)/10; // Werte im gewünschten Format in Array timeString schreiben: sprintf(timeString,"%02d:%02d:%02d", minutes, seconds, hundreds); // ...und ans LCD ausgeben: lcd.print(timeString); } void storeTimesEEP(){ byte byte0; // byte0 = 0...255 byte byte1; // byte1 = 256...65'535 byte byte2; // byte2 = 65'536...16'777'215 for(uint8_t i=0;i<5;i++){ byte0 = (bestTimes[i] & 0x0000FF); byte1 = (bestTimes[i] & 0x00FF00) >> 8; byte2 = (bestTimes[i] & 0xFF0000) >> 16; EEPROM.write(addresses[i],byte0); EEPROM.write(addresses[i]+1,byte1); EEPROM.write(addresses[i]+2,byte2); } } void readTimesEEP(){ byte byte0; // byte0 = 0...255 byte byte1; // byte1 = 256...65'535 byte byte2; // byte2 = 65'536...16'777'215 for(uint8_t i=0;i<5;i++){ byte0 = EEPROM.read(addresses[i]); byte1 = EEPROM.read(addresses[i]+1); byte2 = EEPROM.read(addresses[i]+2); bestTimes[i] = byte0 + (byte1 << 8) + (byte2 << 16); } }