Der folgende Aufbau simuliert eine einfache Ampel-Schaltung. Sie schaltet automatische die Phasen für die KFZe und auf Anforderung gibt es auch eine Fußgänger-Schaltung.
Der Aufbau beinhaltet nur eine Auto-Ampel, aber eine weitere Schaltung (z.B. für eine Kreuzung) ist leicht zu ergänzen.
#define PIN_CAR_RED 2
#define PIN_CAR_ORANGE 3
#define PIN_CAR_GREEN 4
#define PIN_PEDESTRIAN_RED 8
#define PIN_PEDESTRIAN_GREEN 9
#define PIN_BUTTON 10
// Phases of the traffic lights
#define CAR_PHASE_GREEN 0
#define CAR_PHASE_ORANGE 1
#define CAR_PHASE_ORANGE_SHORT 2
#define CAR_PHASE_ORANGE_GO 3
#define CAR_PHASE_RED 4
#define CAR_PHASE_RED_SHORT 5
#define PEDESTRIAN_PHASE_GREEN 6
#define PEDESTRIAN_PHASE_RED 7
#define PEDESTRIAN_DEMAND 8
byte currentPhase;
bool phaseHasChanged = false, buttonPressed = false;
int currentTime = 0, lastTime = 0;
// Phase durations of the traffic lights in milliseconds
int phaseDurations[9] = {
12000, // CAR_PHASE_GREEN
1800, // CAR_PHASE_ORANGE
1800, // CAR_PHASE_ORANGE_SHORT
50, // CAR_PHASE_ORANGE_GO
5000, // CAR_PHASE_RED
1000, // CAR_PHASE_RED_SHORT
7000, // PEDESTRIAN_PHASE_GREEN
3000, // PEDESTRIAN_PHASE_RED
3000 // PEDESTRIAN_DEMAND
};
void setup()
{
pinMode(PIN_CAR_RED, OUTPUT);
pinMode(PIN_CAR_ORANGE, OUTPUT);
pinMode(PIN_CAR_GREEN, OUTPUT);
pinMode(PIN_PEDESTRIAN_RED, OUTPUT);
pinMode(PIN_PEDESTRIAN_GREEN, OUTPUT);
Serial.begin(9600);
currentPhase = CAR_PHASE_GREEN;
currentTime = millis();
lastTime = currentTime;
showPhase();
}
void loop()
{
phaseHasChanged = checkPhase();
if (phaseHasChanged) {
showPhase();
}
}
bool checkPhase()
{
if (!buttonPressed && digitalRead(PIN_BUTTON) == HIGH) {
if (currentPhase == CAR_PHASE_GREEN) {
buttonPressed = true;
currentPhase = PEDESTRIAN_DEMAND;
return true;
}
}
currentTime = millis();
if (currentTime - lastTime < phaseDurations[currentPhase]) {
return false;
}
switch(currentPhase)
{
case PEDESTRIAN_DEMAND:
currentPhase = CAR_PHASE_ORANGE_SHORT;
break;
case PEDESTRIAN_PHASE_RED:
currentPhase = CAR_PHASE_ORANGE_GO;
buttonPressed = false;
break;
case PEDESTRIAN_PHASE_GREEN:
currentPhase = PEDESTRIAN_PHASE_RED;
break;
case CAR_PHASE_GREEN:
currentPhase = CAR_PHASE_ORANGE;
break;
case CAR_PHASE_ORANGE:
currentPhase = CAR_PHASE_RED;
break;
case CAR_PHASE_ORANGE_SHORT:
currentPhase = CAR_PHASE_RED_SHORT;
break;
case CAR_PHASE_RED:
currentPhase = CAR_PHASE_ORANGE_GO;
break;
case CAR_PHASE_ORANGE_GO:
currentPhase = CAR_PHASE_GREEN;
break;
case CAR_PHASE_RED_SHORT:
currentPhase = PEDESTRIAN_PHASE_GREEN;
break;
}
lastTime = currentTime;
return true;
}
void showPhase()
{
if (currentPhase != PEDESTRIAN_DEMAND) {
digitalWrite(PIN_CAR_RED, LOW);
digitalWrite(PIN_CAR_ORANGE, LOW);
digitalWrite(PIN_CAR_GREEN, LOW);
digitalWrite(PIN_PEDESTRIAN_RED, LOW);
digitalWrite(PIN_PEDESTRIAN_GREEN, LOW);
}
switch(currentPhase)
{
case PEDESTRIAN_DEMAND:
Serial.println("Pedestrian demanded!");
break;
case PEDESTRIAN_PHASE_RED:
Serial.println("Pedestrians do not walk!");
digitalWrite(PIN_PEDESTRIAN_RED, HIGH);
digitalWrite(PIN_CAR_RED, HIGH);
break;
case PEDESTRIAN_PHASE_GREEN:
Serial.println("Pedestrians please walk!");
digitalWrite(PIN_PEDESTRIAN_GREEN, HIGH);
digitalWrite(PIN_CAR_RED, HIGH);
break;
case CAR_PHASE_GREEN:
Serial.println("Cars drive!");
digitalWrite(PIN_PEDESTRIAN_RED, HIGH);
digitalWrite(PIN_CAR_GREEN, HIGH);
break;
case CAR_PHASE_ORANGE:
case CAR_PHASE_ORANGE_SHORT:
Serial.println("Cars slow down!");
digitalWrite(PIN_PEDESTRIAN_RED, HIGH);
digitalWrite(PIN_CAR_ORANGE, HIGH);
break;
case CAR_PHASE_ORANGE_GO:
Serial.println("Cars please accelerate!");
digitalWrite(PIN_PEDESTRIAN_RED, HIGH);
digitalWrite(PIN_CAR_ORANGE, HIGH);
break;
case CAR_PHASE_RED:
case CAR_PHASE_RED_SHORT:
Serial.println("Cars stop!");
digitalWrite(PIN_PEDESTRIAN_RED, HIGH);
digitalWrite(PIN_CAR_RED, HIGH);
break;
}
}
zurück