#include <Keypad.h>
#include <TM1637Display.h>
// Definities voor display pinnen
#define CLK1 22 // Gewijzigde pin voor het eerste display
#define DIO1 23 // Gewijzigde pin voor het eerste display
#define CLK2 21 // Gewijzigde pin voor het tweede display
#define DIO2 19 // Gewijzigde pin voor het tweede display
// Definities voor rotary encoder en knoppen
#define ROTARY_PIN1 26 // Gewijzigde pin voor rotary encoder
#define ROTARY_PIN2 27 // Gewijzigde pin voor rotary encoder
#define ROTARY_BUTTON 25 // Gewijzigde pin voor rotary button
// Definities voor debounce tijden
#define DEBOUNCE_DELAY 200
#define RESET_DEBOUNCE_DELAY 100
// Initialisatie van display modules
TM1637Display display1(CLK1, DIO1);
TM1637Display display2(CLK2, DIO2);
// Keypad configuratie
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {16, 17, 18, 0}; // Specifieke pinnen voor de rijen
byte colPins[COLS] = {2, 4, 5, 15}; // Specifieke pinnen voor de kolommen
// Initialisatie van het keypad
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
int lastEncoded = 0;
unsigned long lastDebounceTime = 0;
int availableScores[] = {201, 301, 401, 501, 601, 701, 801, 901};
int playerScores[2] = {0, 0};
int scoreIndex = 3;
bool scoreLocked = false;
int currentPlayer = 1;
String currentInput = "";
int previousScore = 0; // Opslaan van de laatst ingevoerde score voor undo-functie
int lastPlayer = 0; // Bijhouden van de laatste speler die scoorde
void handleRotaryEncoder() {
if (scoreLocked) return;
int MSB = digitalRead(ROTARY_PIN1);
int LSB = digitalRead(ROTARY_PIN2);
int currentEncoded = (MSB << 1) | LSB;
int sum = (lastEncoded << 2) | currentEncoded;
unsigned long currentTime = millis();
if (currentTime - lastDebounceTime > DEBOUNCE_DELAY) {
if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) {
scoreIndex = min(scoreIndex + 1, (int)(sizeof(availableScores) / sizeof(availableScores[0]) - 1));
display1.showNumberDec(availableScores[scoreIndex], false);
lastDebounceTime = currentTime;
} else if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) {
scoreIndex = max(scoreIndex - 1, 0);
display1.showNumberDec(availableScores[scoreIndex], false);
lastDebounceTime = currentTime;
}
}
lastEncoded = currentEncoded;
}
void handleButtonPress() {
bool buttonState = digitalRead(ROTARY_BUTTON) == LOW;
if (buttonState && !scoreLocked && millis() - lastDebounceTime > DEBOUNCE_DELAY) {
scoreLocked = true;
playerScores[0] = availableScores[scoreIndex];
playerScores[1] = availableScores[scoreIndex];
currentPlayer = 1;
updateDisplays();
lastDebounceTime = millis();
}
}
void handleKeypad() {
if (!scoreLocked) return;
char key = customKeypad.getKey();
if (key) {
if (key == 'A') { // Gebruik A knop als reset
scoreIndex = 3;
scoreLocked = false;
display1.showNumberDec(availableScores[scoreIndex], false);
display2.clear();
} else if (key == 'B') { // Gebruik B knop om laatste score te annuleren
playerScores[lastPlayer - 1] += previousScore;
currentPlayer = lastPlayer; // Ga verder met dezelfde speler
updateDisplays();
} else if (key == '#') {
if (currentInput.length() > 0) {
int score = currentInput.toInt();
previousScore = score; // Sla de laatst ingevoerde score op
lastPlayer = currentPlayer; // Onthoud welke speler scoorde
playerScores[currentPlayer - 1] -= score;
currentInput = "";
currentPlayer = currentPlayer % 2 + 1; // Wissel van speler
updateDisplays();
}
} else if (isdigit(key)) {
currentInput += key;
displayCurrentInput();
}
}
}
uint8_t* getDigitSegments(int num) {
static uint8_t segData[4];
for (int i = 0; i < 4; i++) {
segData[i] = 0;
}
int digitPos = 3;
do {
segData[digitPos--] = display1.encodeDigit(num % 10);
num /= 10;
} while (num > 0 && digitPos >= 0);
return segData;
}
void updateDisplays() {
uint8_t segPlayer1[4] = {0x00, 0x00, 0x00, 0x00};
uint8_t segPlayer2[4] = {0x00, 0x00, 0x00, 0x00};
memcpy(segPlayer1, getDigitSegments(playerScores[0]), 4);
memcpy(segPlayer2, getDigitSegments(playerScores[1]), 4);
if (currentPlayer == 1) {
segPlayer1[0] |= 0x40; // Voeg streepje toe bij speler 1
} else {
segPlayer2[0] |= 0x40; // Voeg streepje toe bij speler 2
}
display1.setSegments(segPlayer1);
display2.setSegments(segPlayer2);
}
void displayCurrentInput() {
uint8_t segData[4] = {0x00, 0x00, 0x00, 0x00};
memcpy(segData, getDigitSegments(currentInput.toInt()), 4);
if (currentPlayer == 1) {
display1.setSegments(segData);
} else {
display2.setSegments(segData);
}
}
void setup() {
Serial.begin(9600);
pinMode(ROTARY_PIN1, INPUT_PULLUP);
pinMode(ROTARY_PIN2, INPUT_PULLUP);
pinMode(ROTARY_BUTTON, INPUT_PULLUP);
display1.setBrightness(0x0f);
display2.setBrightness(0x0f);
display1.showNumberDec(availableScores[scoreIndex], false);
display2.clear();
}
void loop() {
if (!scoreLocked) {
handleRotaryEncoder();
}
handleButtonPress();
handleKeypad();
}