Ich hab den nicht vergessen, nur beim aufräumen der Fenster geschlossen...
Es gibt ein paar zusätzliche Serielle Ausgaben.
Sollte was nicht passen, brauche ich die vollständige Ausgabe ab Controllerstart.
Was mir fehlt und unbedingt noch rein muss:
Du kannst Punkte dazurechnen, ohne dass ein Aufschlag ausgewält ist.
Das darf natürlich nicht passieren.
Mache ich noch, wenn der Aufschlag jetzt auf der richtigen Seite angezeigt wird.
// Forensketch - Schiedsrichterplatz Tischtennis
// https://forum.arduino.cc/t/ein-schiedsrichtertisch-fur-tischtennis-mit-74hc595-und-74hc165/1351812/
/*
Big-Displays haben die Segmente an den Pins der Schieberegister nach der RECHTEN Variante!
0 | 7 |
5 1 | 2 6 |
6 | 1 |
4 2 | 3 5 |
3 | 4 |
*/
/*
Digit0 Timer Hunderter // Minute Einer
Digit1 Timer zehner // Sekunde Zehner
Digit2 Timer einer // Sekunde Einer
Digit3 SpielerA Satz + Aufschlag D8
Digit4 SpielerA Punkte einer + Zehner D32
Digit5 SpielerB Satz + Aufschlag D24
Digit6 SpielerB Punkte einer + Zehner D16
*/
#include <Streaming.h>
constexpr bool segActiv {0}; // Die Segmente leuchten, wenn RegisterPin => 0!!!
constexpr uint8_t bigDisp {1}; // -> Nummer des Registerzweig aus displays
constexpr uint8_t bigDispReg {7}; // -> Anzahl der Register auf dem Zweig
bool bigDispRegOut[bigDispReg * 8] = {!segActiv}; // -> Summe aller bits auf dem Zweig
bool oldBigDisplay[bigDispReg * 8] = {!segActiv}; // Merker für Aktuallisierung
constexpr byte shiftRegs {3}; // Anzahl der Zweige mit HC-Schieberegister
struct REGPIN // Definition eines Zweiges
{
uint8_t clock;
uint8_t data;
uint8_t latch;
};
REGPIN regpin[shiftRegs]
{{5, 7, 6}, {9, 11, 10}, {12, 14, 13}}; // Pinbelegung Schieberegister
constexpr boolean dec[][8] // Umsetzungstabelle Ziffer in 7-Segmentanzeige
{
{1, 1, 0, 0, 0, 0, 0, 0}, // 0
{1, 1, 1, 1, 1, 0, 0, 1}, // 1
{1, 0, 1, 0, 0, 1, 0, 0}, // 2
{1, 0, 1, 1, 0, 0, 0, 0}, // 3
{1, 0, 0, 1, 1, 0, 0, 1}, // 4
{1, 0, 0, 1, 0, 0, 1, 0}, // 5
{1, 0, 0, 0, 0, 0, 1, 0}, // 6
{1, 1, 1, 1, 1, 0, 0, 0}, // 7
{1, 0, 0, 0, 0, 0, 0, 0}, // 8
{1, 0, 0, 1, 0, 0, 0, 0}, // 9
{1, 1, 1, 1, 1, 1, 1, 1}, // ALL OFF
};
constexpr uint8_t spielers {2}; //
struct SPIELER
{
uint8_t points;
uint8_t sets;
bool serve;
};
struct SPIEL
{
SPIELER spieler[spielers]; // Alle Spieler anlegen
uint8_t serveStart; // Merker welcher Spieler 1. Aufschlag hat
} spiel; //{{0, 0, 0}, {0, 0, 0}, 0,};
constexpr byte A = 0; // Default: Spieler A => Element von spieler[spielers]
constexpr byte B = 1;
REGPIN keypad // Schieberegister Tastenabfrage
{16, 17, 15};
struct SCOREPAD
{
// // "A" "B"
bool aufschlag; // 21 # 22
bool spielPlus; // 6 # 14
bool spielMinus; // 5 # 13
bool spielReset; // 4 # 12
bool satzPlus; // 3 # 11
bool satzMinus; // 2 # 10
bool satzReset; // 1 # 9
};
struct KEYTABLE
{
bool timeOutStart; // 20 Auszeit
bool timeOutStop; // 19
bool timeEinStart; // 18 Einspielzeit
bool timeEinStop; // 17
SCOREPAD sp[spielers]; // Spielertasten
};
constexpr bool gedrueckt {HIGH}; // Vorbelegung für Tastenabfrage
KEYTABLE kt;
KEYTABLE oldtable; // Hilfstabelle für das merken der Tastendrücke
struct ZEIT
{
/*
1+2 Minutenanzeige ( Anzeige 1 oder 2)( aber nur 2, 1 ist nicht in benutzung)
3 Sekundenanzeige zehner ( Anzeige 0-5)
4 Sekundenanzeige einer ( Anzeige 0-9)
*/
uint8_t minute = 0;
uint8_t sekunde = 0;
uint32_t lastTik = 0; // Merker, wann ausgelöst
} zeit;
void setup()
{
Serial.begin(115200);
Serial.println(F("Tischtennis Display"));
//display init
for (byte b = 0; b < shiftRegs; b++)
{
pinMode(regpin[b].clock, OUTPUT);
pinMode(regpin[b].data, OUTPUT);
pinMode(regpin[b].latch, OUTPUT);
digitalWrite(regpin[b].clock, LOW);
digitalWrite(regpin[b].data, LOW);
digitalWrite(regpin[b].latch, LOW);
};
pinMode(keypad.clock, OUTPUT);
pinMode(keypad.data, INPUT);
pinMode(keypad.latch, OUTPUT);
digitalWrite(keypad.clock, LOW);
digitalWrite(keypad.latch, LOW);
for (byte b = 0; b < spielers; b++)
{
kt.timeOutStart = !gedrueckt;
kt.timeOutStop = !gedrueckt;
kt.timeEinStart = !gedrueckt;
kt.timeEinStop = !gedrueckt;
kt.sp[b].spielPlus = !gedrueckt;
kt.sp[b].aufschlag = !gedrueckt;
kt.sp[b].spielPlus = !gedrueckt;
kt.sp[b].spielMinus = !gedrueckt;
kt.sp[b].spielReset = !gedrueckt;
kt.sp[b].satzPlus = !gedrueckt;
kt.sp[b].satzMinus = !gedrueckt;
kt.sp[b].satzReset = !gedrueckt;
oldtable.timeOutStart = !gedrueckt;
oldtable.timeOutStop = !gedrueckt;
oldtable.timeEinStart = !gedrueckt;
oldtable.timeEinStop = !gedrueckt;
oldtable.sp[b].spielPlus = !gedrueckt;
oldtable.sp[b].aufschlag = !gedrueckt;
oldtable.sp[b].spielPlus = !gedrueckt;
oldtable.sp[b].spielMinus = !gedrueckt;
oldtable.sp[b].spielReset = !gedrueckt;
oldtable.sp[b].satzPlus = !gedrueckt;
oldtable.sp[b].satzMinus = !gedrueckt;
oldtable.sp[b].satzReset = !gedrueckt;
}
}
void loop()
{
getKeys(); // Holt Tastenzustände
checkKeys(); // wertet Tasten aus
myTimer(); // CountDownTimer
displaySpieler(); // kleine Anzeige
bigDisplay(); // große Anzeige
displayTime(); // countDownDisplay
}
//
void segmentTest()
{
for (byte b = 0; b < 10; b++)
{
for (byte s = 0; s < spielers; s++)
{
spiel.spieler[s].points = spiel.spieler[s].points ? 0 : 88;
spiel.spieler[s].sets = spiel.spieler[s].sets ? 0 : 88;
spiel.spieler[s].serve = spiel.spieler[s].serve ? 0 : 1;
}
zeit.minute = zeit.minute ? 0 : 88;
zeit.sekunde = zeit.sekunde ? 0 : 88;
displaySpieler();
displayTime();
bigDisplay();
delay(500);
}
}
//
void allNew()
{
for (byte s = 0; s < spielers; s++)
{
spiel.spieler[s].points = 0;
spiel.spieler[s].sets = 0;
spiel.spieler[s].serve = false;
}
// spiel.serveIsChange = false;
spiel.serveStart = 0;
zeit.minute = 0;
zeit.sekunde = 0;
}
//
void myTimer()
{
constexpr uint32_t _oneSecond {1000};
if (zeit.minute || zeit.sekunde) // Solange Zeit aktiv
{
if (millis() - zeit.lastTik >= _oneSecond)
{
if (zeit.sekunde > 0)
{ zeit.sekunde--; }
else if (zeit.minute > 0)
{
zeit.minute--;
zeit.sekunde = 59;
}
zeit.lastTik += _oneSecond;
}
}
}
//
void setAufschlag(const byte seite) // Stellt den Aufschlag für die entsprechende Spielerseite
{
for (byte a = 0; a < spielers; a++)
{spiel.spieler[a].serve = false;} // löscht alles
Serial << "setAufschlag site " << seite << endl;
spiel.spieler[seite].serve = true; // setzt aktuellen Aufschlag
}
//
void nextAufschlag() // Nächsten Aufschlag errechnen
{
byte myAufschlag = 0;
for (byte b = 0; b < spielers; b++) // gehe durch alle Spieler
{
if (spiel.spieler[b].serve) // Spieler hat Aufschlag ?
{
myAufschlag = b + 1; // nächsten Spieler setzen
if (myAufschlag >= spielers) // Wert ist größer als Spieler, dann erster Spieler
{ myAufschlag = 0; }
}
}
// Serial << "myAufschlag " << myAufschlag << endl;
setAufschlag(myAufschlag); // Aufschlag setzen
}
//
void newSet(const byte site) // Satz aufaddieren und alle Punkte löschen
{
spiel.spieler[site].sets++; // Satz gewonnen
for (byte b = 0; b < spielers; b++)
{ spiel.spieler[b].points = 0; } // Punkte-Reset
Serial << "newSet " << spiel.serveStart << endl;
setAufschlag(spiel.serveStart); // Aufschlag setzen *****
}
//
void automatikAufschlag() // wird aufgerufen, wenn points(+/-)-Taste gedrückt wurde
{
uint8_t allPoints = 0;
for (uint8_t b = 0; b < spielers; b++)
{ allPoints += spiel.spieler[b].points; }
// Serial << "automatikAufschlag" << endl;
if (allPoints < 20) // summe points für jedes 2tes Spiel
{
if (allPoints % 2 == 0) // aktuelles Spiel ist zweites Spiel
{ nextAufschlag(); } // Aufschlag setzen
}
else // Jedes Spiel ab 10:10
{ nextAufschlag(); }
}
//
bool getSite(const bool site) // ermittelt die Seite, wo sich Spieler A und B befinden
{
byte allSet = 0; // Summenvariable für alle Sätze
for (byte b = 0; b < spielers; b++) // Alle Sätze zählen
{ allSet += spiel.spieler[b].sets; }
if (allSet != 4) // Solange nicht 4 Säze vollständig gespielt wurden normaler Seitenwechsel
{ return allSet % 2 == 0 ? !site : site; } // Seitenwechsel nach geradem / ungeradem Satzstand
// Seitenwechsel bei Satz 5 bis Spiel 5 normal - dann Seitenwechsel!
for (byte b = 0; b < spielers; b++) // durchlaufe alle Spielerpoints
{
if (spiel.spieler[b].points >= 5) // Einer hat die Grenze erreicht?
{ return !site; } // Tausche die Seite
}
Serial << "getSite site: " << site << endl;
return site; // Wenn nix passt, gib die bisherige Seite zurück
}
//
bool checkSetEnd() // Prüft ob Satz zu Ende ist
{
bool isEnd = false; // merker
constexpr uint8_t setPoint {11}; // Satzende in Punkte
constexpr uint8_t winPoint {2}; // Unterschied Spielerpunkte zum Gewinn
//
uint8_t allPoints = 0;
for (byte b = 0; b < spielers; b++) // addiere alle Spielerpunkte als Zwischenvariable
{ allPoints += spiel.spieler[b].points; } //
for (byte b = 0; b < spielers; b++) // Frage Spieler auf Siegpunkt ab
{
if (spiel.spieler[b].points >= setPoint) // Mindestpunktzahl zum Gewinn erreicht?
{
if ((spiel.spieler[b].points - winPoint) >= (allPoints - spiel.spieler[b].points)) // Unterschied passt?
{
newSet(b); // Satzpunkt setzen und Spielpunkte löschen
isEnd = true; // merker setzen
}
}
}
Serial << "checkSetEnd " << isEnd << endl;
return isEnd; //
}
//
void printSegment(const byte &segmentReihe, const bool *array, const byte &laenge)
{
for (uint8_t b = 0; b < laenge; b++)
{
digitalWrite(regpin[segmentReihe].data, array[b]); // Array auf dem Schieberegister
digitalWrite(regpin[segmentReihe].clock, HIGH);
digitalWrite(regpin[segmentReihe].clock, LOW);
digitalWrite(regpin[segmentReihe].data, LOW);
}
digitalWrite(regpin[segmentReihe].latch, HIGH);
digitalWrite(regpin[segmentReihe].latch, LOW);
}
//
void displayTime()
{
constexpr byte laenge {32};
bool time[laenge] = {0};
bool *timeSekundeEiner = &time[0];
bool *timeSekundeZehner = &time[8]; // 2.tes Register
bool *timeMinuteEiner = &time[16]; // 3.tes Register
bool *timeMinuteZehner = &time[24]; // 4.tes Register
memset(time, 0, laenge);
memcpy(timeMinuteZehner, dec[zeit.minute / 10], 8);
memcpy(timeMinuteEiner, dec[zeit.minute % 10], 8);
memcpy(timeSekundeZehner, dec[zeit.sekunde / 10], 8);
memcpy(timeSekundeEiner, dec[zeit.sekunde % 10], 8);
printSegment(2, time, laenge); // 3.ter Kanal
}
//
void displaySpieler()
{
/*
1+2 Punktanzeige Spieler A (Anzeige 0-19)
3+4 Satzanzeige Spieler A (Anzeige 0-9)( aber nur 3, 4 ist nicht in benutzung)
5+6 Satzanzeige Spieler B (Anzeige 0-9)( aber nur 5, 6 ist nicht in benutzung)
7+8 Punktanzeige Spieler B ( Anzeige 0-19)
*/
constexpr byte laenge {64};
byte allSet = 0;
for (byte b = 0; b < spielers; b++)
{ allSet += spiel.spieler[b].sets; }
bool spell[laenge] = {0};
bool *spielerBeiner = &spell[0];
bool *spielerBzehner = &spell[8];
bool *satzBeiner = &spell[24];
bool *satzAeiner = &spell[40];
bool *spielerAeiner = &spell[48];
bool *spielerAzehner = &spell[56];
memset(spell, 0, laenge);
// Das ist tricky:
// die Ausgabe der Spielerdaten ist abhängig von der Anzahl gespielter Sätze
// Mit jedem gespieltem Satz wechselt der Spieler die Seite
// Und bei Satz 5 nochmal mitten im Spiel... getSite() soll das ermitteln
memcpy(spielerAzehner, dec[spiel.spieler[getSite(A)].points / 10], 8);
memcpy(spielerAeiner, dec[spiel.spieler[getSite(A)].points % 10], 8);
memcpy(satzAeiner, dec[spiel.spieler[getSite(A)].sets % 10], 8);
memcpy(satzBeiner, dec[spiel.spieler[getSite(B)].sets % 10], 8);
memcpy(spielerBzehner, dec[spiel.spieler[getSite(B)].points / 10], 8);
memcpy(spielerBeiner, dec[spiel.spieler[getSite(B)].points % 10], 8);
printSegment(0, spell, laenge);
}
//
//
void bigDisplay()
{
constexpr uint32_t printIntervall {500};
static uint32_t lastPrint = 0;
memset(bigDispRegOut, !segActiv, bigDispReg * 8); // alle bits löschen
bool *timerHunderter = &bigDispRegOut[4 * 8]; // Register 7 | DIGIT 0
bool *timerZehner = &bigDispRegOut[5 * 8]; // Register 6 | DIGIT 1
bool *timerEiner = &bigDispRegOut[6 * 8]; // Register 5 | DIGIT 2
bool *spielerAsatz = &bigDispRegOut[1 * 8];
bool *spielerAeiner = &bigDispRegOut[2 * 8];
bool *spielerBsatz = &bigDispRegOut[3 * 8];
bool *spielerBeiner = &bigDispRegOut[0 * 8];
//
if (zeit.minute + zeit.sekunde)
{
memcpy(timerHunderter, dec[zeit.minute % 10], 8);
memcpy(timerZehner, dec[zeit.sekunde / 10], 8);
memcpy(timerEiner, dec[zeit.sekunde % 10], 8);
}
else
{
memcpy(timerHunderter, dec[10], 8);
memcpy(timerZehner, dec[10], 8);
memcpy(timerEiner, dec[10], 8);
}
memcpy(spielerAeiner, dec[spiel.spieler[getSite(A)].points % 10], 8);
memcpy(spielerAsatz, dec[spiel.spieler[getSite(A)].sets % 10], 8);
memcpy(spielerBeiner, dec[spiel.spieler[getSite(B)].points % 10], 8);
memcpy(spielerBsatz, dec[spiel.spieler[getSite(B)].sets % 10], 8);
bigDispRegOut[16] = spiel.spieler[getSite(B)].points / 10 ? segActiv : !segActiv; // spielerBZehner
bigDispRegOut[24] = spiel.spieler[getSite(B)].serve ? !segActiv : segActiv; // spielerBAufschlag
bigDispRegOut[32] = spiel.spieler[getSite(A)].points / 10 ? segActiv : !segActiv; // spielerAZehner
// Spieler 0 serve war ursprünglich 40 - falscher Chip angelötet
bigDispRegOut[8] = spiel.spieler[getSite(A)].serve ? !segActiv : segActiv; // spielerAAufschlag
for (byte b = 0; b < 56; b++)
{ bigDispRegOut[b] = !bigDispRegOut[b]; }
if ((memcmp(bigDispRegOut, oldBigDisplay, bigDispReg * 8) != 0) || // Neuer Inhalt ODER
(millis() - printIntervall > lastPrint)) // Zeit abgelaufen
{
printSegment(bigDisp, bigDispRegOut, bigDispReg * 8);
memcpy(oldBigDisplay, bigDispRegOut, bigDispReg * 8);
lastPrint = millis();
}
};
void getKeys()
// Funktion aus dem Ursprungspost übernommen und erweitert
{
// Das sind Schieberegister n:1
// Auch wenn nicht alle Pins gebraucht werden, müssen ungenutzte mitgelesen werden!
constexpr uint8_t zaehler {24}; // Anzahl Chips * 8 Pin
constexpr uint32_t interval {50}; // "debounce Time"
static uint32_t lastRead = 0; // Merker
if (millis() - lastRead > interval)
{
digitalWrite(keypad.latch, LOW); // Chip aktivieren
delay(1);
digitalWrite(keypad.latch, HIGH);
bool readIn = true;
for (uint8_t b = 0; b < zaehler; b++) // Eingänge durchzählen
{
readIn = digitalRead(keypad.data);
//Serial<<"READIN: "<<readIn<<endl;
switch (b) // Zuweisung Pin => Variable
{
//*INDENT-OFF*
case 1: kt.sp[getSite(A)].satzReset = readIn; break; // bit 1 aus Schieberegister
case 2: kt.sp[getSite(A)].satzMinus = readIn; break; // bit 2
case 3: kt.sp[getSite(A)].satzPlus = readIn; break; // bit 3
case 4: kt.sp[getSite(A)].spielReset = readIn; break;
case 5: kt.sp[getSite(A)].spielMinus = readIn; break;
case 6: kt.sp[getSite(A)].spielPlus = readIn; break;
case 9: kt.sp[getSite(B)].satzReset = readIn; break;
case 10: kt.sp[getSite(B)].satzMinus = readIn; break;
case 11: kt.sp[getSite(B)].satzPlus = readIn; break;
case 12: kt.sp[getSite(B)].spielReset = readIn; break;
case 13: kt.sp[getSite(B)].spielMinus = readIn; break;
case 14: kt.sp[getSite(B)].spielPlus = readIn; break;
case 17: kt.timeEinStop = readIn; break;
case 18: kt.timeEinStart = readIn; break;
case 19: kt.timeOutStop = readIn; break;
case 20: kt.timeOutStart = readIn; break;
case 21: kt.sp[getSite(A)].aufschlag = readIn; break;
case 22: kt.sp[getSite(B)].aufschlag = readIn; break;
//*INDENT-ON*
}
digitalWrite(keypad.clock, HIGH);
digitalWrite(keypad.clock, LOW);
}
lastRead = millis();
}
}
//
void leerZeile()
{
Serial << "\r\n" << endl;
}
void checkSpielerKeys() // ausgelesene Werte aus den Schieberegistern verarbeiten
{
for (byte b = 0; b < spielers; b++) // alle Spieler
{
//Serial<<"x"<<endl;
// aufschlag
if (kt.sp[b].aufschlag != oldtable.sp[b].aufschlag) // aktuellen Zustand und Merker vergleichen
{
if (kt.sp[b].aufschlag == gedrueckt) // Taste wurde losgelassen?
{
leerZeile();
setAufschlag(b);
} // .... ausführen
oldtable.sp[b].aufschlag = kt.sp[b].aufschlag; // Merker setzen, für Auswertesperre
}
// satz Reset
if (kt.sp[b].satzReset != oldtable.sp[b].satzReset)
{
if (kt.sp[b].satzReset == gedrueckt)
{
leerZeile();
spiel.spieler[b].sets = 0;
}
oldtable.sp[b].satzReset = kt.sp[b].satzReset;
}
// satz Minus
if (kt.sp[b].satzMinus != oldtable.sp[b].satzMinus)
{
if (kt.sp[b].satzMinus == gedrueckt)
{
leerZeile();
if (spiel.spieler[b].sets > 0) // Nur wenn was auf dem Zähler steht
{ spiel.spieler[b].sets--; }
}
oldtable.sp[b].satzMinus = kt.sp[b].satzMinus;
}
// satz Plus
if (kt.sp[b].satzPlus != oldtable.sp[b].satzPlus)
{
if (kt.sp[b].satzPlus == gedrueckt)
{
leerZeile();
spiel.spieler[b].sets++;
}
oldtable.sp[b].satzPlus = kt.sp[b].satzPlus;
}
// spiel Reset
if (kt.sp[b].spielReset != oldtable.sp[b].spielReset)
{
if (kt.sp[b].spielReset == gedrueckt)
{
leerZeile();
spiel.spieler[b].points = 0;
}
oldtable.sp[b].spielReset = kt.sp[b].spielReset;
}
// spiel Minus
if (kt.sp[b].spielMinus != oldtable.sp[b].spielMinus)
{
if (kt.sp[b].spielMinus == gedrueckt)
{
leerZeile();
if (spiel.spieler[b].points > 0) // Muss ja was drauf sein, damit man was abziehen kann :-)
{ spiel.spieler[b].points--; }
}
automatikAufschlag(); // Aufschlag muss neu berechnet werden, wenn Punkte gesetzt
// TODO!
// ACHTUNG: Wenn alle Sätze gelöscht werden, müsste auch überprüft werden,
// wie der Punktestand ist und dann den Aufschlag nochmal setzen
oldtable.sp[b].spielMinus = kt.sp[b].spielMinus;
}
// spiel Plus
if (kt.sp[b].spielPlus != oldtable.sp[b].spielPlus)
{
//Serial << b << " AA " << endl;
if (kt.sp[b].spielPlus == gedrueckt)
{
leerZeile();
// TODO!
// Den Teil evtl. auslagern
if (spiel.spieler[0].points + spiel.spieler[1].points == 0) // Noch kein Punkt gespielt?
{
Serial << "noch kein Punkt" << endl;
for (byte c = 0; c < spielers; c++) // Frage alle Aufschläge ab
if (spiel.spieler[c].serve) // Spieler hat ersten Aufschlag
{
Serial << "erster Aufschlag gemerkt: " << c << endl;
spiel.serveStart = c;
} // Merke für den Satz den ersten Aufschlag
}
// Ende auslagern
spiel.spieler[b].points++; //
Serial << "Spieler " << b << " Point " << spiel.spieler[b].points << endl;
automatikAufschlag(); // Aufschlagwechsel für Anzeige berechnen
checkSetEnd(); // Wenn Satz zu Ende wird Zählerstände gesetzt
}
oldtable.sp[b].spielPlus = kt.sp[b].spielPlus;
}
}
}
//
void checkKeys()
{
checkSpielerKeys(); // Spielertasten ausgelagert
// EinspielZeit
if (kt.timeEinStart != oldtable.timeEinStart) // Tastenstatus geändert?
{
if (kt.timeEinStart == gedrueckt) //
{
zeit.minute = 2; // Vorbelegung
zeit.sekunde = 0;
zeit.lastTik = millis(); // aktuelle Zeit für timer
}
oldtable.timeEinStart = kt.timeEinStart; // Tastenstatus merken
}
if (kt.timeEinStop != oldtable.timeEinStop)
{
if (kt.timeEinStop == gedrueckt)
{
zeit.minute = 0;
zeit.sekunde = 0;;
}
oldtable.timeEinStop = kt.timeEinStop;
}
// TimeOutZeit
if (kt.timeOutStart != oldtable.timeOutStart)
{
if (kt.timeOutStart == gedrueckt)
{
zeit.minute = 1;
zeit.sekunde = 0;
zeit.lastTik = millis();
}
oldtable.timeOutStart = kt.timeOutStart;
}
if (kt.timeOutStop != oldtable.timeOutStop)
{
if (kt.timeOutStop == gedrueckt)
{
zeit.minute = 0;
zeit.sekunde = 0;;
}
oldtable.timeOutStop = kt.timeOutStop;
}
}