// Setzen der Bibliotheken
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
// Servo-Objekt erstellen
Servo servo_barrier;
// Adressierung des LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Setzen der Schranke
int servo_winkel = 0;
// Belegung für den Servo
#define servo_pin 15
// 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
#define warning_light_pin 13
// Belegung der Taster
#define input_button1 6
#define input_sensor 4
#define input_button2 5
#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
WARNUNG, // 11
SCHRANKE_SCHLIESSEN, // 12
SCHRANKE_OEFFNEN, // 13
};
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 den Taster 2
bool button2_read = false;
bool button2_on = false;
bool switch2 = false;
// Variablen für den Sensor
bool sensor_read = false;
bool sensor_on = false;
bool switch3 = false;
// Variablen Fussgänger-Ampel
bool block_ampel = false;
bool ampel_flag = false;
// Variablen Ampel1
bool red = false;
bool yellow = false;
bool green = false;
bool red2 = false;
bool yellow2 = false;
bool green2 = false;
bool warning_light = false;
// Variablen Fussgänger-Ampel
bool fuss_red = false;
bool fuss_green = false;
// Setzen der Timer
unsigned long serial_millis = 0;
unsigned long lcd_millis = 0;
unsigned long button1_millis = 0;
unsigned long button2_millis = 0;
unsigned long sensor_millis = 0;
unsigned long ampel_millis = 0;
unsigned long ampel2_millis = 0;
unsigned long ampel_fuss_millis = 0;
unsigned long blink_millis = 0;
unsigned long blink_warning_millis = 0;
unsigned long servo_millis = 0;
unsigned long winkel_millis = 0;
// 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 toggle_sensor();
void set_ampel();
void handle_ampel();
void set_ampel_fuss();
void handle_ampel_fuss();
void set_barrier();
void handle_barrier();
void setup() {
// Servo mit Pin 15 des Arduino verbinden
servo_barrier.attach(servo_pin);
// 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);
// Setzten der Outputs für das Andreaskreuz
pinMode(warning_light_pin, OUTPUT);
// Setzen der inputs der Taster
pinMode(input_button1, INPUT_PULLUP);
pinMode(input_sensor, INPUT_PULLUP);
pinMode(input_button2, 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() {
// Setzen der Funktion für den Serial_Monitor
update_serial_monitor();
// Setzen der Funktion für den LCD
update_lcd();
// Setzen der Funktion für den Toggle_Switch
toggle_switch();
// Setzen der Funktion für den Fussgänger-Taster
toggle_switch_fuss();
// Setzen der Funktion für den Sensor
toggle_sensor();
// Setzen der Funktion für die Auto-Ampeln
set_ampel();
// Setzen der Funktion für die Auto-Ampeln
handle_ampel();
// Setzen der Funktion für die Fussgänger-Ampeln
set_ampel_fuss();
// Setzen der Funktion für die Fussgänger-Ampeln
handle_ampel_fuss();
// Setzen der Funktion für die Schranke
set_barrier();
// Setzen der Funktion für die Schranke
handle_barrier();
}
//===============================================//
//===============Funktionen======================//
//===============================================//
// Abschnitt für den Serial_monitor
void update_serial_monitor() {
// Variablen für diese Funktion
unsigned long serial_timer = millis() - serial_millis;
if (serial_timer > 150) {
Serial.print(" Service = ");
Serial.println(switch1);
Serial.print("Fuss-Taster = ");
Serial.print(switch2);
Serial.print(" Sensor = ");
Serial.print(switch3);
Serial.print(" Ampel_Zustand = ");
Serial.print(ampel_state);
Serial.print(" Servo_winkel = ");
Serial.print(servo_winkel);
serial_millis = millis();
}
}
//===============================================//
//===============Funktionen======================//
//===============================================//
// Abschnitt für den LCD
void update_lcd() {
// Variablen für diesen Abschnitt
unsigned long lcd_timer = millis() - lcd_millis;
lcd.setCursor(0, 0);
lcd.print("Ampel_state :");
lcd.setCursor(0, 1);
lcd.print("Winkel :");
lcd.setCursor(13, 1);
lcd.print(servo_winkel);
lcd.setCursor(15, 1);
lcd.write(223);
lcd.setCursor(0, 2);
lcd.print("F-Button :");
if (switch2) {
lcd.setCursor(13, 2);
lcd.print("ON ");
}
else {
lcd.setCursor(13, 2);
lcd.print("OFF");
}
lcd.setCursor(0, 3);
lcd.print("Sensor :");
if (switch3) {
lcd.setCursor(13, 3);
lcd.print("ON ");
}
else {
lcd.setCursor(13, 3);
lcd.print("OFF");
}
switch(ampel_state) {
case BLINKEN:
lcd.setCursor(13, 0);
lcd.print("Blinken");
break;
case ROT:
lcd.setCursor(13, 0);
lcd.print("Rot ");
break;
case ROT_GELB:
lcd.setCursor(13, 0);
lcd.print("RotGelb");
break;
case GRUEN:
lcd.setCursor(13, 0);
lcd.print("Gruen ");
break;
case GELB:
lcd.setCursor(13, 0);
lcd.print("Gelb ");
break;
case ROT2:
lcd.setCursor(13, 0);
lcd.print("Rot2 ");
break;
case ROT_GELB2:
lcd.setCursor(13, 0);
lcd.print("RotGelb");
break;
case GRUEN2:
lcd.setCursor(13, 0);
lcd.print("Gruen2 ");
break;
case GELB2:
lcd.setCursor(13, 0);
lcd.print("Gelb2 ");
break;
case FUSS_ROT:
lcd.setCursor(13, 0);
lcd.print("F Rot ");
break;
case FUSS_GRUEN:
lcd.setCursor(13, 0);
lcd.print("F Gruen");
break;
case WARNUNG:
lcd.setCursor(13, 0);
lcd.print("Warnung");
break;
case SCHRANKE_SCHLIESSEN:
lcd.setCursor(13, 0);
lcd.print("S. Zu");
break;
case SCHRANKE_OEFFNEN:
lcd.setCursor(13, 0);
lcd.print("S. Auf ");
break;
}
}
//===============================================//
//===============Funktionen======================//
//===============================================//
// Abschnitt für den Toggle-Schalter
void toggle_switch() {
// Variablen für diesen Abschnitt
unsigned long button1_timer = millis() - button1_millis;
button1_read = digitalRead(input_button1);
// Implementierung der Logik
if (button1_read == true) {
button1_millis = millis();
}
if (button1_read == false && button1_on == false && button1_timer > 20) {
button1_on = true;
}
if (button1_read == true && button1_on == true) {
button1_on = false;
switch1 = !switch1;
block_ampel = false;
ampel_millis = millis();
}
}
//===============================================//
//===============Funktionen======================//
//===============================================//
// Abschnitt für den Fussgänger-Taster
void toggle_switch_fuss() {
// Variablen für diesen Abschnitt
unsigned long button2_timer = millis() - button2_millis;
button2_read = digitalRead(input_button2);
// Implementierung der Logik
if (button2_read == true) {
button2_millis = millis();
}
if (button2_read == false && button2_on == false && button2_timer > 20) {
button2_on = true;
}
if (button2_read == true && button2_on == true) {
button2_on = false;
switch2 = !switch2;
}
}
//===============================================//
//===============Funktionen======================//
//===============================================//
// Abschnitt für den Sensor
void toggle_sensor() {
// Variablen für diesen Abschnitt
unsigned long sensor_timer = millis() - sensor_millis;
sensor_read = digitalRead(input_sensor);
// Implementierung der Logik
if (sensor_read == true) {
sensor_millis = millis();
}
if (sensor_read == false && sensor_on == false && sensor_timer > 20) {
sensor_on = true;
}
if (sensor_read == true && sensor_on == true) {
sensor_on = false;
switch3 = !switch3;
}
}
//===============================================//
//===============Funktionen======================//
//===============================================//
void set_ampel() {
// Unterschiedliche Timer für die zwei Phasen
unsigned long ampel_timer = millis() - ampel_millis;
unsigned long ampel2_timer = millis() - ampel2_millis;
if (switch1) {
if (!ampel_flag) { // Erste Ampelphase
if (ampel_timer <= 3000 && !block_ampel) ampel_state = ROT; // 3sec ROT
else if (ampel_timer <= 5000 && !block_ampel) ampel_state = ROT_GELB; // 2sec ROT_GELB
else if (ampel_timer <= 8000 && !block_ampel) ampel_state = GRUEN; // 3sec GRUEN
else if (ampel_timer <= 10000 && !block_ampel) ampel_state = GELB; // 2sec GELB
else if (ampel_timer > 10000) {
ampel_flag = true;
ampel2_millis = millis(); // Timer für zweite Phase starten
}
} else { // Zweite Ampelphase
if (ampel2_timer <= 3000 && !block_ampel) ampel_state = ROT2; // 3sec ROT2
else if (ampel2_timer <= 5000 && !block_ampel) ampel_state = ROT_GELB2; // 2sec ROT_GELB2
else if (ampel2_timer <= 8000 && !block_ampel) ampel_state = GRUEN2; // 3sec GRUEN2
else if (ampel2_timer <= 10000 && !block_ampel) ampel_state = GELB2; // 2sec GELB2
else if (ampel2_timer > 10000) {
ampel_flag = false;
ampel_millis = millis(); // Timer für erste Phase zurücksetzen
}
}
} else {
ampel_state = BLINKEN; // Zustand, wenn switch1 aus ist
}
}
//===============================================//
//===============Funktionen======================//
//===============================================//
// Abschnitt für die Auto-Ampeln
void handle_ampel() {
// Variablen für diesen Anschnitt
unsigned long blink_timer = millis() - blink_millis;
switch (ampel_state) {
case ROT:
red = true;
yellow = false;
green = false;
red2 = true;
yellow2 = false;
green2 = false;
fuss_red = true;
fuss_green = false;
warning_light = false;
break;
case ROT_GELB:
red = true;
yellow = true;
green = false;
red2 = true;
yellow2 = false;
green2 = false;
fuss_red = true;
fuss_green = false;
warning_light = false;
break;
case GRUEN:
red = false;
yellow = false;
green = true;
red2 = true;
yellow2 = false;
green2 = false;
fuss_red = true;
fuss_green = false;
warning_light = false;
break;
case GELB:
red = false;
yellow = true;
green = false;
red2 = true;
yellow2 = false;
green2 = false;
fuss_red = true;
fuss_green = false;
warning_light = false;
break;
case ROT2:
red = true;
yellow = false;
green = false;
red2 = true;
yellow2 = false;
green2 = false;
fuss_red = true;
fuss_green = false;
warning_light = false;
break;
case ROT_GELB2:
red = true;
yellow = false;
green = false;
red2 = true;
yellow2 = true;
green2 = false;
fuss_red = true;
fuss_green = false;
warning_light = false;
break;
case GRUEN2:
red = true;
yellow = false;
green = false;
red2 = false;
yellow2 = false;
green2 = true;
fuss_red = true;
fuss_green = false;
warning_light = false;
break;
case GELB2:
red = true;
yellow = false;
green = false;
red2 = false;
yellow2 = true;
green2 = false;
fuss_red = true;
fuss_green = false;
warning_light = false;
break;
case BLINKEN:
if (blink_timer > 1000) {
red = false;
yellow = true;
green = false;
red2 = false;
yellow2 = true;
green2 = false;
fuss_red = false;
fuss_green = false;
warning_light = false;
}
if (blink_timer > 2000) {
red = false;
yellow = false;
green = false;
red2 = false;
yellow2 = false;
green2 = false;
fuss_red = false;
fuss_green = false;
warning_light = false;
blink_millis = millis();
}
break;
}
// 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);
}
//===============================================//
//===============Funktionen======================//
//===============================================//
// Abschnitt für die Fussgänger-Ampel
void set_ampel_fuss() {
if (switch1 && switch2 && ampel_state == ROT2) {
if (ampel_state != FUSS_ROT) {
ampel_fuss_millis = millis(); // Timer starten
ampel_state = FUSS_ROT;
block_ampel = true;
}
}
// Berechnung der Zeit für die Fußgängerampel
unsigned long ampel_fuss_timer = millis() - ampel_fuss_millis;
if (ampel_state == FUSS_ROT) {
if (ampel_fuss_timer >= 2000) { // 2 Sekunden gewartet
ampel_state = FUSS_GRUEN;
}
} else if (ampel_state == FUSS_GRUEN) {
if (ampel_fuss_timer >= 4000) { // 2 Sekunden gewartet
ampel2_millis = millis();
ampel_millis = millis();
ampel_state = ROT2;
block_ampel = false;
switch2 = false;
ampel_flag = true;
}
}
}
//===============================================//
//===============Funktionen======================//
//===============================================//
// Abschnitt für die Fussgänger-Ampel
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;
warning_light = false;
break;
case FUSS_GRUEN:
red = true;
yellow = false;
green = false;
red2 = true;
yellow2 = false;
green2 = false;
fuss_red = false;
fuss_green = true;
warning_light = false;
break;
}
// Ampel Fussgänger
digitalWrite(ampel_fuss_red, fuss_red);
digitalWrite(ampel_fuss_green, fuss_green);
}
//===============================================//
//===============Funktionen======================//
//===============================================//
// Abschnitt für die Zug-Schranke
void set_barrier() {
if (switch3 && (ampel_state == ROT || ampel_state == ROT2)) {
if (ampel_state != WARNUNG) {
servo_millis = millis();
ampel_state = WARNUNG;
block_ampel = true;
}
}
unsigned long servo_timer = millis() - servo_millis;
if (ampel_state == WARNUNG) {
if (servo_timer >= 4000) {
ampel_state = SCHRANKE_SCHLIESSEN;
}
}
else if (ampel_state == SCHRANKE_SCHLIESSEN && !switch3) {
if (servo_timer >= 8000) {
ampel_state = SCHRANKE_OEFFNEN;
servo_millis = millis();
}
}
else if (ampel_state == SCHRANKE_OEFFNEN && servo_winkel == 0) {
if (servo_timer >= 4000) {
ampel_millis = millis();
ampel2_millis = millis();
ampel_state = ROT;
ampel_flag = false;
block_ampel = false;
}
}
}
//===============================================//
//===============Funktionen======================//
//===============================================//
// Abschnitt für die Zug-Schranke
void handle_barrier() {
// Variablen für diesen Abschnitt
unsigned long blink_warning_timer = millis() - blink_warning_millis;
unsigned long winkel_timer = millis() - winkel_millis;
switch (ampel_state) {
case WARNUNG:
// Kontrolliere das Blinken des Warnlichts
if (blink_warning_timer >= 1000) {
warning_light = !warning_light; // Ändere den Zustand des Warnlichts
blink_warning_millis = millis(); // Zurücksetzen des Timers
}
break;
case SCHRANKE_SCHLIESSEN:
warning_light = true;
if (winkel_timer > 50 && servo_winkel <= 90) {
servo_winkel++;
winkel_millis = millis();
}
if (servo_winkel >= 90) {
servo_winkel = 90;
}
break;
case SCHRANKE_OEFFNEN:
warning_light = true;
if (winkel_timer > 50 && servo_winkel >= 0) {
servo_winkel--;
winkel_millis = millis();
}
if (servo_winkel <= 0) {
servo_winkel = 0;
}
break;
}
// Eintrag der Variablen
digitalWrite(warning_light_pin, warning_light);
servo_barrier.write(servo_winkel); // Servo auf Grad einstellen
}