// Setzen der Bibliotheken
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Adressierung des LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Belegung der Ampeln
#define ampel_fuss_red 22
#define ampel_fuss_green 24
#define ampel1_red 12
#define ampel1_yellow 11
#define ampel1_green 10
#define ampel2_red 9
#define ampel2_yellow 8
#define ampel2_green 7
// Belegung der Taster
#define input_button1 6
#define input_button2 5
#define input_button3 4
#define input_button4 3
#define input_button5 2
// Variablen Global
// Variable State
enum current_state_ampel {
BLINKEN, // 0
ROT, // 1
ROT_GELB, // 2
GRUEN, // 3
GELB, // 4
ROT2, // 5
ROT_GELB2, // 6
GRUEN2, // 7
GELB2, // 8
FUSS_ROT, // 9
FUSS_GRUEN // 10
};
current_state_ampel ampel_state = BLINKEN;
// Variablen für Taster 1
bool button1_read = false;
bool button1_on = false;
bool switch1 = false;
// Variablen für Taster 2
bool button2_read = false;
bool button2_on = false;
bool switch2 = false;
// Variablen Ampel1
bool red = false;
bool yellow = false;
bool green = false;
bool red2 = false;
bool yellow2 = false;
bool green2 = false;
// Variablen Fussgänger-Ampel
bool fuss_red = false;
bool fuss_green = false;
bool block_ampel = false;
// Setzen der Timer
unsigned long serial_timer = 0;
unsigned long lcd_timer = 0;
unsigned long button1_timer = 0;
unsigned long button2_timer = 0;
unsigned long ampel_timer = 0;
unsigned long ampel_fuss_timer = 0;
unsigned long blink_timer = 0;
bool fuss_active = false; // Flag, um zu überprüfen, ob die Fußgängerampel aktiv ist
// Belegung der Potis
#define poti1 A0
#define poti2 A1
#define poti3 A2
// Vorrausdeklarierung der Void-Abschnitte
void update_serial_monitor();
void update_lcd();
void toggle_switch();
void toggle_switch_fuss();
void set_ampel();
void handle_ampel();
void set_ampel_fuss();
void handle_ampel_fuss();
void setup() {
// Initialisierung des LCD
lcd.init();
lcd.backlight();
// Setzen der outputs Ampel 1 und 2
pinMode(ampel1_red, OUTPUT);
pinMode(ampel1_yellow, OUTPUT);
pinMode(ampel1_green, OUTPUT);
pinMode(ampel2_red, OUTPUT);
pinMode(ampel2_yellow, OUTPUT);
pinMode(ampel2_green, OUTPUT);
// Setzen der outputs für die Fußgängerampel
pinMode(ampel_fuss_red, OUTPUT);
pinMode(ampel_fuss_green, OUTPUT);
// Setzen der inputs der Taster
pinMode(input_button1, INPUT_PULLUP);
pinMode(input_button2, INPUT_PULLUP);
pinMode(input_button3, INPUT_PULLUP);
pinMode(input_button4, INPUT_PULLUP);
pinMode(input_button5, INPUT_PULLUP);
// Setzen der analogen inputs der Potis
pinMode(poti1, INPUT);
pinMode(poti2, INPUT);
pinMode(poti3, INPUT);
// Starten des Serial-Monitors
Serial.begin(9600);
}
void loop() {
// Aufrufen der Funktionen zum Updaten des Serial_Monitors
update_serial_monitor();
// Aufrufen der Funktionen zum Updaten des LCD
update_lcd();
// Aufrufen der Funktionen für den Toggle-Schalter
toggle_switch();
// Aufrufen des Toggle-Switches für dei Fussgänger
toggle_switch_fuss();
// Aufrufen der Funktionen für die Ampeln-Steuerung
set_ampel();
// Aufrufen der Funktionen für die Ampeln
handle_ampel();
// Aufrufen der Funktion für dei Fussgängerampel
set_ampel_fuss();
// Aufrufen der Funktion für die Fussgängerampel-Steuerung
handle_ampel_fuss();
// Schreiben der Ampel_Pins
// Ampel1
digitalWrite(ampel1_red, red);
digitalWrite(ampel1_yellow, yellow);
digitalWrite(ampel1_green, green);
//Ampel2
digitalWrite(ampel2_red, red2);
digitalWrite(ampel2_yellow, yellow2);
digitalWrite(ampel2_green, green2);
// Ampel Fussgänger
digitalWrite(ampel_fuss_red, fuss_red);
digitalWrite(ampel_fuss_green, fuss_green);
}
//-------------------------------------------------------------//
//-------------------------------------------------------------//
// Abschnitt für den Serial_Monitor
void update_serial_monitor(){
// Variablen für den Serial-Monitor
unsigned long serial_millis = millis() - serial_timer;
if (serial_millis > 250){
Serial.print(" S1 = ");
Serial.println(switch1);
Serial.print(" S2 = ");
Serial.print(switch2);
Serial.print(" Ampel = ");
Serial.print(ampel_state);
Serial.print(" Ampel_B = ");
Serial.print(block_ampel);
serial_timer = millis();
}
}
//-------------------------------------------------------------//
// Abschnitt für den LCD
void update_lcd() {
// Variablen für das LCD
unsigned long lcd_millis = millis() - lcd_timer;
// LCD dauerhafte Anzeige
lcd.setCursor(0, 0);
lcd.print("Ampel1 = ");
lcd.setCursor(0, 1);
lcd.print("Ampel2 = ");
// Aktualisierung des LCD alle 250 Millisekunden
if (lcd_millis > 250) {
}
}
//-------------------------------------------------------------//
// Abschnitt für den Toggle-Schalter
void toggle_switch(){
// Variablen für den Toggle-Schalter
unsigned long button_millis = millis() - button1_timer;
button1_read = digitalRead(input_button1);
if (button1_read == true){
button1_timer = millis();
}
if (button1_read == false && button1_on == false && button_millis > 20){
button1_on = true;
}
if (button1_read == true && button1_on == true){
button1_on = false;
switch1 = !switch1;
ampel_timer = millis();
}
}
//-------------------------------------------------------------//
// Abschnitt für den Toggle-Schalter
void toggle_switch_fuss(){
// Variablen für den Toggle-Schalter_fuss
unsigned long button_millis = millis() - button2_timer;
button2_read = digitalRead(input_button2);
if (button2_read == true){
button2_timer = millis();
}
if (button2_read == false && button2_on == false && button_millis > 20){
button2_on = true;
}
if (button2_read == true && button2_on == true){
button2_on = false;
switch2 = !switch2;
}
}
//-------------------------------------------------------------//
// Abschnitt für die Ampel-Steuerung
void set_ampel(){
// Setzen der internen Variablen
unsigned long ampel_millis = millis() - ampel_timer;
if (switch1){
if (ampel_millis <= 2000 && block_ampel == false) ampel_state = ROT;
else if (ampel_millis <= 3000 && block_ampel == false) ampel_state = ROT_GELB;
else if (ampel_millis <= 11000 && block_ampel == false) ampel_state = GRUEN;
else if (ampel_millis <= 13000 && block_ampel == false) ampel_state = GELB;
else if (ampel_millis <= 15000 && block_ampel == false) ampel_state = ROT2;
else if (ampel_millis <= 16000 && block_ampel == false) ampel_state = ROT_GELB2;
else if (ampel_millis <= 24000 && block_ampel == false) ampel_state = GRUEN2;
else if (ampel_millis <= 26000 && block_ampel == false) ampel_state = GELB2;
else if (ampel_millis > 26000 && block_ampel == false) ampel_timer = millis();
}
else{
ampel_state = BLINKEN;
}
}
//-------------------------------------------------------------//
// Abschnitt für die Ampeln
void handle_ampel(){
// Setzen der internen Variablen
unsigned long blink_millis = millis() - blink_timer;
switch(ampel_state){
case ROT:
red = true;
yellow = false;
green = false;
red2 = true;
yellow2 = false;
green2 = false;
fuss_red = true;
fuss_green = false;
break;
case ROT_GELB:
red = true;
yellow = true;
green = false;
red2 = true;
yellow2 = false;
green2 = false;
fuss_red = true;
fuss_green = false;
break;
case GRUEN:
red = false;
yellow = false;
green = true;
red2 = true;
yellow2 = false;
green2 = false;
fuss_red = true;
fuss_green = false;
break;
case GELB:
red = false;
yellow = true;
green = false;
red2 = true;
yellow2 = false;
green2 = false;
fuss_red = true;
fuss_green = false;
break;
case ROT2:
red = true;
yellow = false;
green = false;
red2 = true;
yellow2 = false;
green2 = false;
fuss_red = true;
fuss_green = false;
break;
case ROT_GELB2:
red = true;
yellow = false;
green = false;
red2 = true;
yellow2 = true;
green2 = false;
fuss_red = true;
fuss_green = false;
break;
case GRUEN2:
red = true;
yellow = false;
green = false;
red2 = false;
yellow2 = false;
green2 = true;
fuss_red = true;
fuss_green = false;
break;
case GELB2:
red = true;
yellow = false;
green = false;
red2 = false;
yellow2 = true;
green2 = false;
fuss_red = true;
fuss_green = false;
break;
case BLINKEN:
if (blink_millis > 1000){
red = false;
yellow = true;
green = false;
red2 = false;
yellow2 = true;
green2 = false;
fuss_red = false;
fuss_green = false;
}
if (blink_millis > 2000){
red = false;
yellow = false;
green = false;
red2 = false;
yellow2 = false;
green2 = false;
fuss_red = false;
fuss_green = false;
blink_timer = millis();
}
break;
}
}
//-------------------------------------------------------------//
void set_ampel_fuss() {
// Überprüfen, ob beide Schalter aktiv sind und die Ampel rot ist
if (switch1 && switch2 && (ampel_state == ROT || ampel_state == ROT2)) {
// Nur den Timer setzen, wenn der Zustand auf FUSS_ROT gesetzt wird
if (ampel_state != FUSS_ROT) {
ampel_fuss_timer = millis(); // Timer starten
ampel_state = FUSS_ROT;
block_ampel = true;
}
}
// Berechnung der Zeit für die Fußgängerampel
unsigned long ampel_fuss_millis = millis() - ampel_fuss_timer;
if (ampel_state == FUSS_ROT) {
if (ampel_fuss_millis >= 2000) { // 2 Sekunden gewartet
ampel_state = FUSS_GRUEN;
}
}
else if (ampel_state == FUSS_GRUEN) {
if (ampel_fuss_millis >= 4000) { // 2 Sekunden gewartet
ampel_state = ROT;
block_ampel = false;
switch2 = false;
ampel_timer = millis();
}
}
}
//-------------------------------------------------------------//
// Abschnitt für die Fussgängerampel
void handle_ampel_fuss(){
switch(ampel_state){
case FUSS_ROT:
red = true;
yellow = false;
green = false;
red2 = true;
yellow2 = false;
green2 = false;
fuss_red = true;
fuss_green = false;
break;
case FUSS_GRUEN:
red = true;
yellow = false;
green = false;
red2 = true;
yellow2 = false;
green2 = false;
fuss_red = false;
fuss_green = true;
break;
}
}
//-------------------------------------------------------------//