RailFX Ampel-Modul

Dieses Modul des RailFX-Systems betreibt eine Ampelanlage mit zwei Fahrtrichtungen und Fußgängerampeln. Dazu gibt es noch eine Straßenbeleuchtung und eine optionale Nachtabschaltung.

Schaltplan

RailFX Ampel-Modul Schaltplan für die Modellbahn

Auch dieses Modul arbeitet mit einem Arduino Nano. An die digitalen Kanäle 2 – 11 sind die LEDs für die Ampeln angeschossen. Jeder Kanal kann bis zu 40mA liefern. Da man für eine Ampelanlage natürlich mehrere einzelne Ampeln benötigt, kann man die Schaltung durch parallel geschaltete LEDs erweitern. Allerdings verringert sich die Leuchtkraft der einzelnen LED. Am A2 und A3 wird die Straßenbeleuchtung betrieben. Sie werden als digitale Ausgänge (D16, D17) betrieben und schalten sich gesteuert durch das Control-Modul in der Nacht ein. Das grüne Kabel links (SCL) ist überflüssig – sorry.

Achtung: Am Pin A4 ist wird das Control-Signal des RailFX Control-Moduls angelegt. Es steuert die Tageszeit und ist zwingend erforderlich.

Einstellungen im Code

Im Code lassen sich mehrere Einstellungen vornehmen. Die Variable meineAdresse muss auf das System angepasst werden. Diese Adresse darf im gesamten System (also bei allen Modulen) nur einmal vorkommen. Die Variable wartezeiten speichert die Dauer der einzelnen Farbphasen der Ampelanlage. Die Variable nachtabschaltung kann man auf true oder false setzen. Bei true wird die Ampeln nachts abgeschaltet und blinkt gelb. Bei false geschieht das nicht.

long wartezeiten[10] = {5000, 2000, 500, 2000, 500, 5000, 2000, 500, 2000, 500}; // Wartezeiten der Ampelphasen
boolean nachtabschaltung = true;         // true = Ampel schaltet nachts ab (gelbe blinken), false = Ampel schaltet nicht ab

Beim Upload muss man darauf achten, dass das richtige Board im Arduino-Menü ausgewählt ist. Dazu muss ebenfalls im Werkzeugemenü im Unterpunkt Prozessor »ATmega328P (Old Bootlaoder)« ausgewählt sein.

Der folgende Programmcode kann mit den oben erwähnten Änderungen einfach kopiert und auf das Arduino-Nano geladen werden.

Code für das RailFX-Ampel-Modul

/*
     Rail-FX Ampel-Modul
     StartHardware.org
*/

/* ***** ***** Einstellungen ***** ***** ***** *****  ***** ***** ***** *****  ***** ***** ***** ***** */

long wartezeiten[10] = {5000, 2000, 500, 2000, 500, 5000, 2000, 500, 2000, 500}; // Wartezeiten der Ampelphasen
boolean nachtabschaltung = true;         // true = Ampel schaltet nachts ab (gelbe blinken), false = Ampel schaltet nicht ab

/* ***** ***** Ab hier beginnt der Programmcode, der nicht angepasst werden muss ***** ***** ***** ***** */

int strassenlampenPin1 = 16;              // an diesem Pin sind die Straßenlampen angeschlossen
int strassenlampenPin2 = 17;              // an diesem Pin sind weitere Straßenlampen angeschlossen

int ledPins[10] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11};

int ampelphasen[12][10] = {
  {1, 0, 0, 0, 1, 0, 0, 1, 1, 0},  // state 0
  {1, 0, 0, 1, 0, 0, 0, 1, 1, 0},  // state 1
  {1, 0, 0, 1, 0, 0, 1, 0, 1, 0},  // state 2
  {1, 0, 0, 1, 0, 1, 0, 0, 1, 0},  // state 3
  {1, 1, 0, 1, 0, 1, 0, 0, 1, 0},  // state 4
  {0, 0, 1, 1, 0, 1, 0, 0, 0, 1},  // state 5
  {0, 0, 1, 1, 0, 1, 0, 0, 1, 0},  // state 6
  {0, 1, 0, 1, 0, 1, 0, 0, 1, 0},  // state 7
  {1, 0, 0, 1, 0, 1, 0, 0, 1, 0},  // state 8
  {1, 0, 0, 1, 0, 1, 1, 0, 1, 0},  // state 9
  {0, 1, 0, 0, 0, 0, 1, 0, 0, 0},  // state 10 // blinken
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}   // state 11 // blinken
};

/* Speicher-Variablen */
int strassenlampenHelligkeit = 0;        // speichert, wie hell die Straßenlampen leuchten

/* Timer Variablen */
long strassenlampenTimer = 0;            // Timer der Straßenlampen
long ampelTimer = 0;
long ampelTimeout = 0;

/* State Variablen */
int ampelState = 0;

String stateName;

/* */

/* Variablen vom Controlmodul um die Uhrzeit festzustellen*/
boolean receive = false;
boolean receiveStarted = false;
int receiveTimeout = 10;
long receiveTimer = 0;
int receivedTime = 0;
int receivePulse = 0;
int lastReceivePulse = 0;
int receivePin = 18;
int myTime = 0;

#define PAYLOAD_SIZE 2                   // nötig für die Kommunikation zum Master
int uhrzeit = 0;                         // speichert die uhrzeit vom Master-Modul (0 und 255)
byte nodePayload[PAYLOAD_SIZE];          // speichert die Daten vom Master-Modul zwischen

void setup() {
  Serial.begin(115200);                  // started die serielle Kommunikation
  pinMode(receivePin, INPUT);     // Empfangspin vom Control-Modul
  for (int i = 0; i < 10; i++) {
    pinMode(ledPins[i], OUTPUT);
  }
  pinMode(strassenlampenPin1, OUTPUT);
  pinMode(strassenlampenPin2, OUTPUT);
  strassenlampenAus();
}

void loop() {
  receiveFunction();                // Führe Anweisungen für Empfang aus
  if (receiveStarted == false) {    // Falls gerade keine Daten empfangen werden:
    if (myTime > 22) {              // ***** Später Abend *****
      strassenlampenAn();           // Straßenlampen an
      zeigeAmpelphase();            // Ampel an
    } else if (myTime > 18) {       // ***** Abend *****
      strassenlampenAn();           // Straßenlampen an
      zeigeAmpelphase();            // Ampel an

    } else if (myTime > 12) {       // ***** Nachmittag *****
      strassenlampenAus();          // Straßenlampen aus
      zeigeAmpelphase();            // Ampel an

    } else if (myTime > 9) {        // ***** Vormittag *****
      strassenlampenAus();          // Straßenlampen aus
      zeigeAmpelphase();            // Ampel an

    } else if (myTime > 7) {        // ***** Morgen *****
      strassenlampenAn();           // Straßenlampen an
      zeigeAmpelphase();            // Ampel an

    } else {                        // ***** Nacht *****
      strassenlampenAn();           // Straßenlampen an
      if (nachtabschaltung == true) {
        zeigeAmpelAus();            // Ampel aus
        ampelTimer = millis();      // resetten des Ampel-Timers für die nächste Phase
        ampelState = 3;             // resetten des Ampel-Zustands
      } else {
        zeigeAmpelphase();          // Ampel an
      }
    }
  }
}

void strassenlampenAn() {
  digitalWrite(strassenlampenPin1, LOW);
  digitalWrite(strassenlampenPin2, LOW);
}

void strassenlampenAus() {
  digitalWrite(strassenlampenPin1, HIGH);
  digitalWrite(strassenlampenPin2, HIGH);
}

void zeigeAmpelphase() {
  if (ampelTimer + ampelTimeout < millis()) {
    ampelTimer = millis();
    ampelState++;
    if (ampelState >= 10) ampelState = 0;
    ampelTimeout = wartezeiten[ampelState];
    zeigeAmpelphase();
  }

  for (int i = 0; i < 10; i++) {
    if (ampelphasen[ampelState][i] == 1) {
      digitalWrite(ledPins[i], LOW);
    } else {
      digitalWrite(ledPins[i], HIGH);
    }
  }
}

void zeigeAmpelAus() {
  // Blink-Funktion für abgeschaltetet Ampel
  if (millis() % 2000 > 1000) {
    for (int i = 0; i < 10; i++) {
      if (ampelphasen[11][i] == 1) {
        digitalWrite(ledPins[i], LOW);
      } else {
        digitalWrite(ledPins[i], HIGH);
      }
    }
  } else {
    for (int i = 0; i < 10; i++) {
      if (ampelphasen[10][i] == 1) {
        digitalWrite(ledPins[i], LOW);
      } else {
        digitalWrite(ledPins[i], HIGH);
      }
    }
  }
}

void receiveFunction() {                      // Empfängt die Uhrzeit vom Control-Modul
  receivePulse = digitalRead(receivePin);     // Lies den Empfangspin aus
  
  if ((receiveTimer + receiveTimeout < millis()) && (receiveStarted == true)) {
    // Bei Timeout und aktivem Empfang
    receiveStarted = false;                   // beende aktiven Empfang
    myTime = receivedTime - 1;                // speichere die empfangene Zeit
    receivedTime = 0;                         // setze die Hilfsvariable zum Zeitempfang zurück
    Serial.println(myTime);                   // serielle Ausgabe
  }
  // falls ein Puls am Empfangspin erfasst wird, der vorher nicht da war
  if ((receivePulse == 0) && (lastReceivePulse == 1)) {
    receiveTimer = millis();                  // starte Timer neu
    if (receiveStarted == false) receiveStarted = true;  // starte aktiven Empfang, wenn noch nicht geschehen
    receivedTime++;                           // es gab einen Puls, also erhöhe die Hilfsvariable zum Zeitempfang
  }
  lastReceivePulse = receivePulse;            // aktuellen Zustand am Pin für nächsten Durchlauf merken
}

RailFX-Module

Zurzeit gibt es folgende Projekt-Module:


Wenn dir das Projekt gefallen hat und du von weiteren interessanten Projekten inspiriert werden willst, sieh dir doch mal mein neues E-Book an!

Darin findest du die beliebtesten Arduino-Projekte von StartHardware. Jedes Projekt umfasst Schaltplan, Bauteile, Beschreibung und Code. Für Einsteiger gibt es ein Arduino-Schnellstart-Kapitel und einen kompakten Programmierkurs. Zusätzlich findest du Zwischenkapitel mit Expertenwissen zu den Komponenten, die verwendet werden. Alle Code-Beispiele gibt es natürlich als Download.

Weitere Informationen findest du auf der Produktseite. Klicke jetzt auf den Button, um Details anzusehen.


Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

 

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.