#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Pin-Definitionen für I2C-Displays
LiquidCrystal_I2C lcd1(0x27, 16, 2); // Erstes Display (Adresse 0x27)
LiquidCrystal_I2C lcd2(0x26, 16, 2); // Zweites Display (Adresse 0x26)
// Stage-Management
int currentStage = 1; // Aktuelle Stage
// Zufallszahl für die Anzeige
char randomNumber[17]; // Array für eine 16-stellige Zufallszahl + Nullterminator
unsigned long startTime; // Startzeit für den Timer
int counter = 0; // Zähler für die obere Zeile
// Pin-Definitionen für den CD74HC4067 MUX
const int MUX_SIG_PIN = A0; // SIG-Pin
const int MUX_S0_PIN = 10; // S0
const int MUX_S1_PIN = 11; // S1
const int MUX_S2_PIN = 12; // S2
const int MUX_S3_PIN = 13; // S3
// Liste aller Relays
int relayPins[] = {22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37}; // Relays an den Pins
// Spielereinstellungen
int maxsupportedplayer = 9; // Maximal unterstützte Spieler
int playerCount = 1; // Aktuelle Spieleranzahl
int activePlayer = 1; // Aktiver Spieler
int maxPlayers = 1; // Maximale Spieleranzahl
int ballCount = 3; // Aktuelle Ballanzahl
int scores[9] = {0}; // Punktestände für 9 Spieler
int extraBalls = 0; // Zusätzliche Bälle
// Relays-Management
int relayActivations = 6; // Anzahl der Aktivierungen pro Relay
int relayDelay = 100; // Delay für Ein- und Ausschalten der Relays in Millisekunden
// Setup-Routine
void setup() {
Serial.begin(9600);
lcd1.init();
lcd1.backlight();
lcd2.init();
lcd2.backlight();
randomSeed(analogRead(0)); // Zufallszahlengenerator initialisieren
startTime = millis(); // Startzeit speichern
// Setze die MUX-Pins als Ausgang
pinMode(MUX_S0_PIN, OUTPUT);
pinMode(MUX_S1_PIN, OUTPUT);
pinMode(MUX_S2_PIN, OUTPUT);
pinMode(MUX_S3_PIN, OUTPUT);
// Setze alle Relays als Ausgang
for (int i = 0; i < sizeof(relayPins) / sizeof(relayPins[0]); i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], LOW); // Relays standardmäßig aus
}
}
// Funktion zur Anzeige von rollendem Text (Stage 1)
void displayRollingText() {
const char* message = " -Made by PNK- -This is a Work in Progress Pinball Project- ";
int messageLength = strlen(message);
int startPos = 0;
// Unendliche Schleife für den rollenden Text
while (true) {
// Wechsle zu Stage 2, wenn der Button an MUX1 Kanal 3 gedrückt wird
if (readMuxChannel(3) > 512) {
currentStage = 2; // Wechsel zu Stage 2
break; // Schleife beenden und zu Stage 2 wechseln
}
// Setze Cursor auf die Startposition
lcd1.clear();
lcd1.setCursor(0, 0);
// Zeige den rollenden Text an
for (int i = 0; i < 16; i++) {
if (i + startPos < messageLength) {
lcd1.print(message[i + startPos]);
} else {
lcd1.print(' '); // Leere Zeichen, um den Text zu füllen
}
}
startPos++; // Text weiterrollen
if (startPos > messageLength) {
startPos = 0; // Reset, wenn der Text zu Ende ist
}
// Generiere eine neue zufällige 16-stellige Zahl
for (int i = 0; i < 16; i++) {
randomNumber[i] = random(0, 10) + '0'; // Zufällige Ziffer von 0 bis 9
}
randomNumber[16] = '\0'; // Nullterminator hinzufügen
lcd1.setCursor(0, 1);
lcd1.print(randomNumber);
// Zähler erhöhen
counter++;
// Timer berechnen
unsigned long elapsedTime = millis() - startTime; // Zeit seit dem Start
unsigned long seconds = (elapsedTime / 1000) % 60; // Sekunden
unsigned long minutes = (elapsedTime / 60000) % 60; // Minuten
unsigned long hours = (elapsedTime / 3600000); // Stunden
// Zeige Zähler und Timer auf dem zweiten Display an
lcd2.clear(); // Das Display für neue Informationen leeren
lcd2.setCursor(0, 0);
lcd2.print("Counter: ");
lcd2.print(counter); // Zähler anzeigen
lcd2.setCursor(0, 1);
lcd2.print("Time: ");
lcd2.print(hours);
lcd2.print(":");
lcd2.print(minutes < 10 ? "0" : ""); // Null für einstellige Minuten hinzufügen
lcd2.print(minutes);
lcd2.print(":");
lcd2.print(seconds < 10 ? "0" : ""); // Null für einstellige Sekunden hinzufügen
lcd2.print(seconds);
delay(2); // Wartezeit für die Animation
}
}
// Funktion für Stage 2: Relays ansteuern
void handleStage2() {
lcd1.clear();
lcd1.setCursor(0, 0);
lcd1.print("Stage 2: Relays");
// Alle Relays 5-6 Mal schnell ein- und ausschalten
for (int j = 0; j < relayActivations; j++) { // Anzahl der Aktivierungen verwenden
for (int i = 0; i < sizeof(relayPins) / sizeof(relayPins[0]); i++) {
digitalWrite(relayPins[i], HIGH); // Relay ein
delay(relayDelay); // Kurze Wartezeit
digitalWrite(relayPins[i], LOW); // Relay aus
delay(relayDelay); // Kurze Wartezeit
}
}
lcd2.clear();
lcd2.setCursor(0, 0);
lcd2.print("Relays toggled");
// Wechsel zu Stage 3
currentStage = 3;
}
// Funktion für Stage 3: maxPlayers verwalten
void handleStage3() {
lcd1.clear();
lcd1.setCursor(0, 0);
lcd1.print("Stage 3: maxPlayers");
// Überprüfen der MUX-Kanäle zur Anpassung von maxPlayers
if (readMuxChannel(1) > 512) { // Kanal 1 erhöht maxPlayers
if (maxPlayers < maxsupportedplayer) {
maxPlayers++;
Serial.print("maxPlayers increased to: ");
Serial.println(maxPlayers);
}
}
if (readMuxChannel(2) > 512) { // Kanal 2 verringert maxPlayers
if (maxPlayers > 1) {
maxPlayers--;
Serial.print("maxPlayers decreased to: ");
Serial.println(maxPlayers);
}
}
// Anzeige von maxPlayers
lcd2.clear();
lcd2.setCursor(0, 0);
lcd2.print("maxPlayers: ");
lcd2.print(maxPlayers);
delay(500); // Kurze Wartezeit für die Anzeige
}
// Funktion zum Setzen der MUX-Pins
void setMuxPins(int channel) {
digitalWrite(MUX_S0_PIN, (channel & 0x01) ? HIGH : LOW);
digitalWrite(MUX_S1_PIN, (channel & 0x02) ? HIGH : LOW);
digitalWrite(MUX_S2_PIN, (channel & 0x04) ? HIGH : LOW);
digitalWrite(MUX_S3_PIN, (channel & 0x08) ? HIGH : LOW);
}
// Funktion zum Lesen eines MUX-Kanals
int readMuxChannel(int channel) {
setMuxPins(channel); // Setze die MUX-Pins für den angegebenen Kanal
delay(5); // Kurze Verzögerung zur Stabilisierung
return analogRead(MUX_SIG_PIN); // Lies den Wert am SIG-Pin
}
// Hauptloop
void loop() {
if (currentStage == 1) {
displayRollingText(); // Funktion für Stage 1 aufrufen
} else if (currentStage == 2) {
handleStage2(); // Funktion für Stage 2 aufrufen
} else if (currentStage == 3) {
handleStage3(); // Funktion für Stage 3 aufrufen
}
// Überprüfen der MUX-Kanäle als digitale Buttons
for (int i = 0; i < 16; i++) {
if (readMuxChannel(i) > 512) { // Überprüfe, ob der Kanal gedrückt ist
lcd1.setCursor(0, 0);
lcd1.print("Pressed: ");
lcd1.print(i); // Zeige den gedrückten Kanal an
Serial.print("Channel ");
Serial.print(i);
Serial.println(" is pressed!"); // Debug-Ausgabe
delay(1000); // Wartezeit zur Anzeige
}
}
}