Zum Inhalt springen
RailFX Ampel-Modul für die Modellbahn

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.

    Wir benötigen Ihre Zustimmung um den Inhalt von YouTube laden zu können.

    Mit dem Klick auf das Video werden durch den mit uns gemeinsam Verantwortlichen Youtube [Google Ireland Limited, Irland] das Video abgespielt, auf Ihrem Endgerät Skripte geladen, Cookies gespeichert und personenbezogene Daten erfasst. Damit kann Google Aktivitäten im Internet verfolgen und Werbung zielgruppengerecht ausspielen. Es erfolgt eine Datenübermittlung in die USA, diese verfügt über keinen EU-konformen Datenschutz. Weitere Informationen finden Sie hier.

    Jmx0O2RpdiBjbGFzcz0mcXVvdDtudi1pZnJhbWUtZW1iZWQmcXVvdDsmZ3Q7Jmx0O2lmcmFtZSB0aXRsZT0mcXVvdDtSYWlsRlggQW1wZWxhbmxhZ2UgJm5kYXNoOyBFZmZla3RlIGYmdXVtbDtyIE1vZGVsbGJhaG4gdW5kIE1vZGVsbGJhdSBtaXQgQXJkdWlubyZxdW90OyB3aWR0aD0mcXVvdDsxMjAwJnF1b3Q7IGhlaWdodD0mcXVvdDs2NzUmcXVvdDsgc3JjPSZxdW90O2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2VtYmVkL3FJbWVvMHY2MTZFP2ZlYXR1cmU9b2VtYmVkJnF1b3Q7IGZyYW1lYm9yZGVyPSZxdW90OzAmcXVvdDsgYWxsb3c9JnF1b3Q7YWNjZWxlcm9tZXRlcjsgYXV0b3BsYXk7IGNsaXBib2FyZC13cml0ZTsgZW5jcnlwdGVkLW1lZGlhOyBneXJvc2NvcGU7IHBpY3R1cmUtaW4tcGljdHVyZSZxdW90OyBhbGxvd2Z1bGxzY3JlZW4mZ3Q7Jmx0Oy9pZnJhbWUmZ3Q7Jmx0Oy9kaXYmZ3Q7

    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 das Control-Signal des RailFX Control-Moduls angelegt. Es steuert die Tageszeit und ist zwingend erforderlich.


    Sieh dir jetzt meinen neuen Arduino-Videokurs an: Jetzt ansehen!


    Bauteile

    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 Werkzeuge-Menü 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
    }

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

    • Die beliebtesten Arduino-Projekte von StartHardware
    • Inklusive Schaltplan, Beschreibung und Code
    • Arduino-Schnellstart-Kapitel
    • Kompakter Programmierkurs


    10 Gedanken zu „RailFX Ampel-Modul“

    1. Volker Tschirner

      Hallo Stefan, Ampel ist im Betrieb, was sie aber perfekt machen würde, wäre das tackern an der Fußgängerampel für Blinde. Bei rot ein langsames tackern und bei grün ein schnelles tackern. Wäre das ein Anreiz dies noch mit einzubinden?

      1. Stefan Hermann

        Hi Volker, gute Idee, ist aber erstmal nicht geplant. Meine Liste ist zurzeit ziemlich lang. Den Sound könntest du aber selber realisieren. Viele RailFX-Module haben ja schon einen MP3-Player. Das kannst du ja in den Code einbauen und den Sound auslösen, wenn die Fußgängerampeln umschalten.

        Liebe Grüße

        Stefan

    2. Hallo, tolle Sache Deine Module. Was aber fehlt ist die Nachtdimmung der Deckenbeleuchtung wie es in Hamburg auch realisiert wurde. Hast Du da noch eine Idee??

      1. Hallo Volker, hm, noch nicht, ist aber eine echt spannende Idee! Ich denk drüber nach. Wird bestimmt das nächste Modul :-)

        1. Volker Tschirner

          Hallo Stefan, der Dimmer an sich ist ja nicht das Problem, aber das Einbinden des Contolmoduls ist schon eine Herausforderung. Kannst Du mir sagen wie lange Du dafür brauchst??

          1. Hi Volker, wie willst du die Lampen dimmen? LED-Strips? Wenn ich die Art des Outputs kenne, geht es auf jeden Fall schneller ;-) Liebe Grüße

            1. Volker Tschirner

              Hallo Stefan, noch ein Nachtrag, in Hamburg wird das Licht dunkel und rot geht dann an für die Nacht, wäre das im Automatikbetrieb möglich?

      Schreibe einen Kommentar

      Deine E-Mail-Adresse wird nicht veröffentlicht.

       

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