#include <Arduino.h>
// Intigrierte Bibliotheken
#include <Wire.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
// Adressierung des LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Belegung der Status-LED's der Ventile
#define on_off_led A2
#define status_led1 12
#define status_led2 10
#define status_led3 8
#define status_led4 6
// Belegung der Magnet-Ventile
#define valve1 11
#define valve2 9
#define valve3 7
#define valve4 5
// State_Machine Implementieren
enum operating_state {
state_off,
state_on,
state_select_valve,
state_open_valve,
state_flush,
};
operating_state operating_state = state_off;
// Belegung des Start-Knopfes
#define start_button_input 4
#define flush_button_input A3
// Belegung der Kippschalter
#define toggle_switch1_input 3
#define toggle_switch2_input 2
#define toggle_switch3_input A0
#define toggle_switch4_input A1
// Variablen für den Start-Knopf
bool button_read = false;
bool button_on = false;
bool switch0 = false;
// Variable für den Zufallsgenerartor
int analog_value = 0;
// Variablen für den Flush-Knopf
bool flush_button_read = false;
bool flush_button_on = false;
bool switch_flush = false;
// Variablen für die Toggle_Schalter
bool toggle_switch1 = false;
bool toggle_switch2 = false;
bool toggle_switch3 = false;
bool toggle_switch4 = false;
// Setzen der Timer
// Timer perating_state
unsigned long operating_state_millis = 0;
// Serial_Monitor
unsigned long serial_millis = 0;
// Timer für den LCD
unsigned long lcd_millis = 0;
// Taster
unsigned long button_millis = 0;
unsigned long flush_button_millis = 0;
// Status_leds
unsigned long led_millis = 0;
// Timer für den Counter
unsigned long counter_millis = 0;
unsigned long eeprom_millis = 0;
// Flags für die Status_LED's und die Ventile
bool led_v = false;
bool led1_v = false;
bool led2_v = false;
bool led3_v = false;
bool led4_v = false;
// Flags für die Magnet-Ventile
bool valve1_v = false;
bool valve2_v = false;
bool valve3_v = false;
bool valve4_v = false;
// Variablen für den Zufallsgenerator
byte rand_number1 = 0;
byte rand_number2 = 0;
byte rand_number3 = 0;
byte rand_number4 = 0;
// Counter für die Spieler
byte counter_1 = 0;
byte counter_2 = 0;
byte counter_3 = 0;
byte counter_4 = 0;
// Speicheradressen im EEPROM anlegen
int eeprom_address_1 = 0;
int eeprom_address_2 = 1;
int eeprom_address_3 = 2;
int eeprom_address_4 = 3;
// Vorausdeklaration für die Void-Funktionen
void serial_monitor();
void update_lcd();
void start_button();
void flush_butto();
void manage_valves();
void execute_valves();
void setup() {
// Setzen der OUTPUTS für die Status-LED's
pinMode(on_off_led, OUTPUT);
pinMode(status_led1, OUTPUT);
pinMode(status_led2, OUTPUT);
pinMode(status_led3, OUTPUT);
pinMode(status_led4, OUTPUT);
// Setzen der OUTPUTS für die Ventile
pinMode(valve1, OUTPUT);
pinMode(valve2, OUTPUT);
pinMode(valve3, OUTPUT);
pinMode(valve4, OUTPUT);
// Setzen der INPUTS für die Taster und Kippschalter
pinMode(start_button_input, INPUT_PULLUP);
pinMode(flush_button_input, INPUT_PULLUP);
pinMode(toggle_switch1_input, INPUT_PULLUP);
pinMode(toggle_switch2_input, INPUT_PULLUP);
pinMode(toggle_switch3_input, INPUT_PULLUP);
pinMode(toggle_switch4_input, INPUT_PULLUP);
// Die aktuellen Counter aus dem Speicher lesen
counter_1 = EEPROM.read(eeprom_address_1);
counter_2 = EEPROM.read(eeprom_address_2);
counter_3 = EEPROM.read(eeprom_address_3);
counter_4 = EEPROM.read(eeprom_address_4);
// Wenn der Wert im EEPROM ungültig ist (z.B. 255), dann auf 0 setzen
if (counter_1 == 255) counter_1 = 0;
if (counter_2 == 255) counter_2 = 0;
if (counter_3 == 255) counter_3 = 0;
if (counter_4 == 255) counter_4 = 0;
// Initialisierung des LCD
lcd.init();
lcd.backlight();
// Starten des Serial.Monitors
Serial.begin(9600);
// Begrüßungstext aus LCD Anzeigen
lcd.setCursor(0, 0);
lcd.print(" !!! AGONIZER !!!");
lcd.setCursor(0, 1);
lcd.print(" !!! 9000 !!!");
lcd.setCursor(0, 2);
lcd.print(" Pandora");
lcd.setCursor(0, 3);
lcd.print(" Arid Badlands");
delay(3500);
lcd.clear();
}
void loop() {
// Abruf der Funktionen für den Serial.Monitor
serial_monitor();
// Abruf der Funktion für den LCD
update_lcd();
// Abruf der Funktionen für den Start-Knopf
start_button();
// Abschnitt für den Flush_Button
flush_butto();
// Abruf der Funktionen zum Timen für dei Ventile
manage_valves();
// Abruf der Funktionen zum Steuern der Ventile
execute_valves();
}
//----------------------------------------------------//
//-----------Abschnitt Serial.Monitor----------------//
void serial_monitor() {
// Variablen für diesen Abschnitt
unsigned long serial_timer = millis() - serial_millis;
if (serial_timer > 250) {
Serial.print(" switch0 = ");
Serial.println(switch0);
Serial.print(" T1 = ");
Serial.print(valve1_v);
Serial.print(" T2 = ");
Serial.print(valve2_v);
Serial.print(" T3 = ");
Serial.print(valve3_v);
Serial.print(" T4 = ");
Serial.print(valve4_v);
Serial.print(" Flush = ");
Serial.print(switch_flush);
Serial.print(" Betr. = ");
Serial.print(operating_state);
Serial.print(" SEED = ");
Serial.print(analog_value);
serial_millis = millis();
}
}
//----------------------------------------------------//
//-----------Abschnitt Serial.Monitor----------------//
void update_lcd() {
switch(operating_state) {
case state_off:
if (led1_v) {
lcd.setCursor(0, 0);
lcd.print("TOURGE = ");
lcd.setCursor(11, 0);
lcd.print(counter_1);
lcd.setCursor(14, 0);
lcd.print("Punkte");
} else {
lcd.setCursor(0, 0);
lcd.print("WAS DA LOS ?!?");
}
if (led2_v) {
lcd.setCursor(0, 1);
lcd.print("KRIEG = ");
lcd.setCursor(11, 1);
lcd.print(counter_2);
lcd.setCursor(14, 1);
lcd.print("Punkte");
} else {
lcd.setCursor(0, 1);
lcd.print("KEINER BOCK ?!?");
}
if (led3_v) {
lcd.setCursor(0, 2);
lcd.print("PAIN = ");
lcd.setCursor(11, 2);
lcd.print(counter_3);
lcd.setCursor(14, 2);
lcd.print("Punkte");
} else {
lcd.setCursor(0, 2);
lcd.print("KOMM RAN !!!");
}
if (led4_v) {
lcd.setCursor(0, 3);
lcd.print("TERROR = ");
lcd.setCursor(11, 3);
lcd.print(counter_4);
lcd.setCursor(14, 3);
lcd.print("Punkte");
} else {
lcd.setCursor(0, 3);
lcd.print("SIEH ZU HIER !!!");
}
break;
case state_on:
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" SAMMELT EUCH ");
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(" ");
break;
case state_select_valve:
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" DIE OPFER ");
lcd.setCursor(0, 2);
lcd.print(" WURDEN AUSERKOREN ");
lcd.setCursor(0, 3);
lcd.print(" ");
break;
case state_open_valve:
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" SAUFT ");
lcd.setCursor(0, 2);
lcd.print(" !!!!! ");
lcd.setCursor(0, 3);
lcd.print(" ");
break;
case state_flush:
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" FLUTEN ");
lcd.setCursor(0, 2);
lcd.print(" !!!!!! ");
lcd.setCursor(0, 3);
lcd.print(" ");
break;
}
}
//----------------------------------------------------//
//-----------Abschnitt Start-Button------------------//
void start_button() {
// Variablen für diesen Abschnitt
unsigned long button_timer = millis() - button_millis;
unsigned long eeprom_timer = millis() - eeprom_millis;
// Auslesen des Start-Tasters
button_read = digitalRead(start_button_input);
if (button_read == true) {
button_millis = millis();
eeprom_millis = millis();
}
if (button_read == false && button_on == false && button_timer > 20) {
button_on = true;
}
if (button_read == true && button_on == true) {
button_on = false;
switch0 = !switch0;
}
if (button_read == false && eeprom_timer > 3000) {
counter_1 = 0;
counter_2 = 0;
counter_3 = 0;
counter_4 = 0;
EEPROM.write(eeprom_address_1, counter_1);
EEPROM.write(eeprom_address_2, counter_2);
EEPROM.write(eeprom_address_3, counter_3);
EEPROM.write(eeprom_address_4, counter_4);
}
}
//----------------------------------------------------//
//-----------Abschnitt Flush_button------------------//
void flush_butto() {
// Varaiblen für deisen Abschnitt
unsigned long flush_button_timer = millis() - flush_button_millis;
flush_button_read = digitalRead(flush_button_input);
if (flush_button_read == true) {
flush_button_millis = millis();
}
if (flush_button_read == false && flush_button_on == false && flush_button_timer > 20) {
flush_button_on = true;
}
if (flush_button_read == true && flush_button_on == true) {
flush_button_on = false;
switch_flush = !switch_flush;
}
}
//----------------------------------------------------//
//-----------Abschnitt Managment Ventile-------------//
void manage_valves() {
// Variablen für diesen Abschnitt
unsigned long operating_state_timer = millis() - operating_state_millis;
// Auslesen der Toggle_Schalter
toggle_switch1 = !digitalRead(toggle_switch1_input);
toggle_switch2 = !digitalRead(toggle_switch2_input);
toggle_switch3 = !digitalRead(toggle_switch3_input);
toggle_switch4 = !digitalRead(toggle_switch4_input);
// Steuerung
if (switch_flush == true) {
operating_state = state_flush;
switch0 = false;
}
if (switch0 && switch_flush == false) {
if (operating_state_timer <= 5000) operating_state = state_on;
else if (operating_state_timer <= 10000) operating_state = state_select_valve;
else if (operating_state_timer <= 15000) operating_state = state_open_valve;
else if (operating_state_timer > 15000) switch0 = false;
} else if (switch0 == false && switch_flush == false) {
operating_state = state_off;
operating_state_millis = millis();
led_millis = millis();
counter_millis = millis();
}
}
//----------------------------------------------------//
//-----------Abschnitt Steuerung der Ventile---------//
void execute_valves() {
// Variablen für diesen Abschnitt
unsigned long led_timer = millis() - led_millis;
unsigned long counter_timer = millis() - counter_millis;
analog_value = analogRead(A6);
randomSeed(analog_value);
// Steueruung
switch (operating_state) {
case state_off:
if (toggle_switch1) {
led1_v = true;
} else {
led1_v = false;
}
if (toggle_switch2) {
led2_v = true;
} else {
led2_v = false;
}
if (toggle_switch3) {
led3_v = true;
} else {
led3_v = false;
}
if (toggle_switch4) {
led4_v = true;
} else {
led4_v = false;
}
valve1_v = valve2_v = valve3_v = valve4_v = false;
led_v = true;
operating_state_millis = millis();
break;
case state_on:
rand_number1 = random(1, 3);
rand_number2 = random(1, 3);
rand_number3 = random(1, 3);
rand_number4 = random(1, 3);
if (led_timer > 1000) {
led_v = false;
}
if (led_timer > 2000) {
led_v = true;
led_millis = millis();
}
if (toggle_switch1) {
if (led_timer > 1000) {
led1_v = false;
}
if (led_timer > 2000) {
led1_v = true;
led_millis = millis();
}
} else {
led1_v = false;
}
if (toggle_switch2) {
if (led_timer > 1000) {
led2_v = false;
}
if (led_timer > 2000) {
led2_v = true;
led_millis = millis();
}
} else {
led2_v = false;
}
if (toggle_switch3) {
if (led_timer > 1000) {
led3_v = false;
}
if (led_timer > 2000) {
led3_v = true;
led_millis = millis();
}
} else {
led3_v = false;
}
if (toggle_switch4) {
if (led_timer > 1000) {
led4_v = false;
}
if (led_timer > 2000) {
led4_v = true;
led_millis = millis();
}
} else {
led4_v = false;
}
break;
case state_select_valve:
// Status LED blinkt
if (led_timer > 1000) {
led_v = false;
}
if (led_timer > 2000) {
led_v = true;
led_millis = millis();
}
// Ventile werden ausgewählt
if (toggle_switch1 && rand_number1 == 2) {
led1_v = true;
if (counter_timer > 6000) {
counter_1++;
EEPROM.write(eeprom_address_1, counter_1);
counter_millis = millis();
}
} else {
led1_v = false;
}
if (toggle_switch2 && rand_number2 == 2) {
led2_v = true;
if (counter_timer > 6000) {
counter_2++;
EEPROM.write(eeprom_address_2, counter_2);
counter_millis = millis();
}
} else {
led2_v = false;
}
if (toggle_switch3 && rand_number3 == 2) {
led3_v = true;
if (counter_timer > 6000) {
counter_3++;
EEPROM.write(eeprom_address_3, counter_3);
counter_millis = millis();
}
} else {
led3_v = false;
}
if (toggle_switch4 && rand_number4 == 2) {
led4_v = true;
if (counter_timer > 6000) {
counter_4++;
EEPROM.write(eeprom_address_4, counter_4);
counter_millis = millis();
}
} else {
led4_v = false;
}
break;
case state_open_valve:
// Status LED blinkt
if (led_timer > 1000) {
led_v = false;
}
if (led_timer > 2000) {
led_v = true;
led_millis = millis();
}
// Öffne die Ventile, deren zugehörige Status-LEDs aktiv sind
valve1_v = led1_v;
valve2_v = led2_v;
valve3_v = led3_v;
valve4_v = led4_v;
break;
case state_flush:
valve1_v = true;
valve2_v = true;
valve3_v = true;
valve4_v = true;
led1_v = true;
led2_v = true;
led3_v = true;
led4_v = true;
}
// Abrufen und schreiben der Flags
// Einschreiben der Ventile
digitalWrite(valve1, valve1_v);
digitalWrite(valve2, valve2_v);
digitalWrite(valve3, valve3_v);
digitalWrite(valve4, valve4_v);
// Einschreiben der Status_LED's
digitalWrite(on_off_led, led_v);
digitalWrite(status_led1, led1_v);
digitalWrite(status_led2, led2_v);
digitalWrite(status_led3, led3_v);
digitalWrite(status_led4, led4_v);
}
//----------------------------------------------------//
//---------------------------------------------------//