zurück

Arduino-Ampelschaltung

02.02.2018

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.

Video: Live-Demonstration der Ampelschaltung

Verwendete Bauteile

Aufbau

Der Aufbau beinhaltet nur eine Auto-Ampel, aber eine weitere Schaltung (z.B. für eine Kreuzung) ist leicht zu ergänzen.

Aufbau der Ampel-Schaltung
Abb.: Aufbau der Ampel-Schaltung

Sketch

#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;
  }
}