Modellbahn - Bahnübergang - Lichtschranke

Benutzeravatar
e69-fan
Beiträge: 282
Registriert: Mi 20. Jan 2021, 10:32
Wohnort: Murnau am Staffelsee

Modellbahn - Bahnübergang - Lichtschranke

Beitrag von e69-fan »

Hallo Franz,

ich habe mal folgende französische Seite gefunden:

Code: Alles auswählen

// Konstanten (weil sie sich nicht ändern) 
const int IRDetectorPin = 2; // pin du detecteur IR
const int ledPin = 13; // pin de la LED

32 / 5000
Übersetzungsergebnisse
// Variablen (weil sie sich ändern) 
int ledState = LOW; // led eteinte
int IRState; // Aktueller Status des IR-Detektors
int lastIRState = LOW; //vorheriger Zustand des IR-Detektors (um eine Änderung zu erkennen) 

// Zeitvariable in Millisekunden
long lastDebounceTime = 0; // Das letzte Mal wurde der Detektor gewechselt
long debounceDelay = 1000; // eine Sekunde Verzögerung, um eine Änderung zu validieren 

//------------------- SETUP ----------------
void setup() {
pinMode(IRDetectorPin, INPUT);
pinMode(ledPin, OUTPUT);

// initialisation de la led
digitalWrite(ledPin, ledState);
}

//-------------------- LOOP ----------------
void loop() {
// Lesen des IR-Detektors in einer lokalen Variablen
int reading = digitalRead(IRDetectorPin);

// wenn der Strahl geschnitten ist (Lesen == HIGH oder 1)
// Wir warten lange genug, um die parasitären Erkennungen zu ignorieren
// und insbesondere die Intervalle zwischen den Wagen 

// le detecteur a-t-il change
if (reading != lastIRState) {
// armement du timer
lastDebounceTime = millis();
}

if ((millis() - lastDebounceTime) > debounceDelay) {
// Wenn das Zeitlimit erreicht ist, ist die Änderung gültig
// sonst wird die Änderung ignoriert (Parasit oder Inter-Wagon)

// gültige Änderung 
if (reading != IRState) {
IRState = reading;
//Wir geben das Wechselgeld an die LED weiter
ledState = IRState;
digitalWrite(ledPin, ledState);

// Wenn IRState HIGH ist, ist es der Kopf des Zuges 
// *** rufe hier die Headend-Verarbeitung auf
// zum Beispiel: die Einfahrt des Zuges in einen Block

// Wenn IRSate LOW ist, ist dies das Ende des Zuges
// *** rufe hier die Tail-End-Verarbeitung auf
// zum Beispiel: der effektive Ausgang des Blocks 
}
}
// Wir speichern den Status des Detektors für die nächste Schleifenrunde 
lastIRState = reading;
// also die geringste Änderung vor dem Ende der debounceDelay-Verzögerung
// setzt diese Verzögerung zurück 

}
Ein weiterer Tipp für die Wartung der Detektoren
Ich benutze einen analogen Eingang des Arduino. So kann ich per Software entweder eine analoge Messung (0.1023) oder eine digitale Messung (0 oder 1) des Sensorausgangs durchführen.

Da die Sendedioden mit einer konvergenten Linse ausgestattet sind, die einen sehr schmalen Strahl ergibt, und da man mit bloßem Auge nichts sieht, kann es schwierig sein, eine gute Ausrichtung der LED und des Sensors zu erreichen. Wenn man eine analoge Wiedergabe macht, erhält man einen Wert, der von der Ausrichtung abhängt. Dieser Wert muss so niedrig wie möglich sein, wenn die 2 Dioden zu sehen sind. Das muss dem logischen Level 0 entsprechen.

Wenn das Licht nicht durchkommt, ist der Wert maximal, oder parasitäres Licht stört den Sensor!

In meiner Ausführung habe ich den analogen Wert (0.1023) durch 100 geteilt und ihn auf einem 7-Segment-Display oder LCD in einem Kalibrierungsmodus angezeigt. Dann bewege ich die ausstrahlenden Diode, um einen Wert von 2 oder weniger zu finden. So bin ich mir sicher, dass die digitale Wiedergabe dann richtig sein wird.

Dieser Trick wird sich als sehr nützlich erweisen, da die Dioden manchmal während des Baus des Dekors gestört werden und eine einfache Wartung der Sensoren ermöglicht werden muss.
Aber Du wirst das sicherlich schon kennen.

Schöne Ostern und viele Grüße an Euch alle

Wolfgang

















.
Grüße aus der Heimat der E69
Benutzeravatar
Admin
Administrator
Beiträge: 1194
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Modellbahn - Bahnübergang - Lichtschranke

Beitrag von Admin »

Ich dachte du hast das letztemal einen Scherz gemacht, als du gesagt hast dass du mir auch schon Französiche Programme geschickt hast :)

Dabei war das tatsächlich so. Ich habe das aber erst jetzt gesehen. Weil ich das Forum jetzt mal anders geöfnet habe. Indem ich auf "ungelesene Beiträge" geklickt habe :)

Da habe ich Beiträge von dir gesehen die ich jetzt das erste mal gelesen habe :O: War also keine Absicht, dass ich darauf nicht reagiert haben. Habe in nur einfach nicht gesehen :oops:

Ich habe mal den Französischen Text einigermassen übersetzt. :(V):
Benutzeravatar
Admin
Administrator
Beiträge: 1194
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Modellbahn - Bahnübergang - Lichtschranke

Beitrag von Admin »

Ich habe jetzt mal meine Infrarot Lichtschanke wieder ausgegraben und getestet. Wenn du Lust und Zeit hast, dann komme mal vorbei. Dann könnten wir das mal ein bischen Testen / Besprechen.

Damit hast du natürlich auch die Möglichkeit , wenn mehrere Gleise nebeneinander sind, zu sagen auf welchem Gleis der Zug fährt, weil die ja auf den cm genau den Abstand zum IR-Seder/Empfänger rausgibt.

Schönes WE
Franz :(V):
Benutzeravatar
e69-fan
Beiträge: 282
Registriert: Mi 20. Jan 2021, 10:32
Wohnort: Murnau am Staffelsee

Re: Modellbahn - Bahnübergang - Lichtschranke

Beitrag von e69-fan »

:(V):

Ich hätte die ganze nächste Woche bis zur jeweiligen Ausgangssperre Zeit - lege Bitte einen Termin fest.

Bin sehr gespannt welche Lösung Du gefunden hast.

Schönes Wochende
Grüße aus der Heimat der E69
Benutzeravatar
Admin
Administrator
Beiträge: 1194
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Modellbahn - Bahnübergang - Lichtschranke

Beitrag von Admin »

Von mir aus gleich Montag Nachmittag. Also nach 13:00 Uhr.

Wenn dir was dazwischen kommt, dann sag bescheid. Ich habe auch die ganze Woche noch Zeit.

Servus
Franz :(V):
Benutzeravatar
e69-fan
Beiträge: 282
Registriert: Mi 20. Jan 2021, 10:32
Wohnort: Murnau am Staffelsee

Re: Modellbahn - Bahnübergang - Lichtschranke

Beitrag von e69-fan »

Servus,

Montag, ab 15:00 Uhr wäre super.
:(V):
Grüße aus der Heimat der E69
Benutzeravatar
Admin
Administrator
Beiträge: 1194
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Modellbahn - Bahnübergang - Lichtschranke

Beitrag von Admin »

OK, alles klar.

Schönen Sonntag noch.
Und nen schönen Gruß an deine Regierung :(V):
Franz
Benutzeravatar
e69-fan
Beiträge: 282
Registriert: Mi 20. Jan 2021, 10:32
Wohnort: Murnau am Staffelsee

Re: Modellbahn - Bahnübergang - Lichtschranke

Beitrag von e69-fan »

Hallo Franz,

ich habe mal ein paar Fotos vom Einbauort der Lichtschranken gemacht.
Der Mindestabstand könnte eingehalten werden.
Lichtschranke_Ausfahrt_rechts.JPG
Lichtschranke_Ausfahrt_rechts.JPG (161.8 KiB) 1189 mal betrachtet
Lichtschranke (3).JPG
Lichtschranke (3).JPG (163.25 KiB) 1189 mal betrachtet
Lichtschranke (2).JPG
Lichtschranke (2).JPG (127.72 KiB) 1189 mal betrachtet
Lichtschranke (1).JPG
Lichtschranke (1).JPG (112.11 KiB) 1189 mal betrachtet
Ist halt "testen" angesagt.

Vielleicht kann man auf den folgenden Sketch aufbauen ?

Code: Alles auswählen

#include <MobaTools.h>

/* Demo: Wechselblinker modifiziert von Bodo
 *  
 *  
 * Dieses Demo ist etwas komplexer und zeigt die Realisierung eines
 * Wechselblinker, der per Schalter ein- und ausgeschaltet wird.
 * Wie bei Wechselblinkern an einem BÜ üblich, starten die beiden Lampen
 * gleichzeitig, um dann im Wechseltakt zu blinken
 * Dieses Demo verwendet auch die 'Eieruhr' um Zeitverzögerungen zu realisieren
 * Die 'Eieruhr' ist ein Zeitzähler, der aufgezogen werden kann und im loop kann
 * abgefragt werden, ob er abgelaufen ist.
*/

// Festlegen der Ports
const int Blinker1P  =  6;  // Die beiden Led's des
const int Blinker2P  =  7;  // Wechselblinkers.

const int Gleis1onP  =  8;  // Gleis 1 Start-Kontakt
const int Gleis1offP =  9;  // Gleis 1 Ende--Kontakt

const int Gleis2onP  = 10;  // Gleis 2 Start-Kontakt
const int Gleis2offP = 11;  // Gleis 2 Ende--Kontakt

const int Gleis3onP  =  4;  // Gleis 3 Start-Kontakt
const int Gleis3offP =  5;  // Gleis 3 Ende--Kontakt



boolean SchalterP = false;  // Blinkschaltung on/off

boolean Gleis1    = false;  // Gleis 1 belegt/frei
boolean Gleis2    = false;  // Gleis 2 belegt/frei
boolean Gleis3    = false;  // Gleis 3 belegt/frei

// Weitere Konstante
const int wbZykl = 1100;    // Zykluszeit des Wechselblinkers
const int wbSoft = 400;     // Auf/Abblendzeit der Lampen

// Zustand des Wechselblinker
byte wblZustand = 0;        // In dieser Variable wird hinterlegt, in welchem Zustand
						                // sich der Wechselblinker gerade befindet
#define   WBL_AUS     0 	  // beide Lampen sind aus
#define   WBL_START   1   	// Startphase: beide Lampen sind an
#define   WBL_BLINKT  2   	// Die Lampen blinken normal im Wechsel
byte ledState;              // HIGH : Blinker1 ist an, LOW Blinker2 ist an

MoToSoftLed Blinker1;
MoToSoftLed Blinker2;

MoToTimer BlinkUhr;

void setup() {
    pinMode(Gleis1onP, INPUT_PULLUP); 
    pinMode(Gleis1offP, INPUT_PULLUP); 
    
    pinMode(Gleis2onP, INPUT_PULLUP); 
    pinMode(Gleis2offP, INPUT_PULLUP); 

    pinMode(Gleis3onP, INPUT_PULLUP); 
    pinMode(Gleis3offP, INPUT_PULLUP); 
 
    Blinker1.attach(Blinker1P);     // die Ausgänge werden automatisch auf OUTPUT gesetzt
    Blinker1.riseTime( wbSoft );    // Aufblendzeit in ms
    
    Blinker2.attach(Blinker2P);     
    Blinker2.riseTime( wbSoft );    // Aufblendzeit in ms
}

void loop() {

   if ( digitalRead(Gleis1onP)  == LOW ) { Gleis1 = true; }
   if ( digitalRead(Gleis1offP) == LOW ) { Gleis1 = false; }
   
   if ( digitalRead(Gleis2onP)  == LOW ) { Gleis2 = true; }
   if ( digitalRead(Gleis2offP) == LOW ) { Gleis2 = false; }
   
   if ( digitalRead(Gleis3onP)  == LOW ) { Gleis3 = true; }
   if ( digitalRead(Gleis3offP) == LOW ) { Gleis3 = false; }
   
   SchalterP = Gleis1 || Gleis2  || Gleis3 ;                                 // Blinken, wenn Gleis 1 oder Gleis 2 oder Gleis 3 belegt 
  
    // Wechselblinker
    switch (wblZustand) {
      case WBL_AUS:
        // Beide Lampen sind aus, warten auf einschalten
        if ( SchalterP == true && BlinkUhr.running() == false ) {
            // Beide Leds einschalten, Timer für gemeinsames Startleuchten
            Blinker1.on();
            Blinker2.on();
            BlinkUhr.setTime( wbSoft );
            wblZustand = WBL_START;
        }
        break;
      case WBL_START:
        // Startphase: Nach Zeitablauf erste Led wieder aus
        if ( BlinkUhr.running() == false ) {
            // Die Startzeit ist abgelaufen, Übergang zur normalen Blinkphase
            ledState = HIGH;
            Blinker2.off();
            BlinkUhr.setTime(wbZykl/2); // Zeitverzögerung setzen
            wblZustand = WBL_BLINKT;
        }
        break;
      case WBL_BLINKT:
        if ( BlinkUhr.running() == false ) {
            BlinkUhr.setTime(wbZykl/2); // Zeitverzögerung setzen
            if ( ledState == LOW ) {
                Blinker1.on();
                Blinker2.off();
                ledState = HIGH;
            } else {
                ledState = LOW;
                Blinker2.on();
                Blinker1.off();
            }
        }
        if ( SchalterP == false ) {
            // Wechselblinker abschalten
            Blinker1.off();
            Blinker2.off();
            wblZustand = WBL_AUS;
            BlinkUhr.setTime(wbZykl);   // minimale 'Aus' zeit des Blinkers
                                        //( schützt vor Schalterprellen )
        }
        break;
            
    } // Ende switch Wechselblinker
}
Grüße aus der Heimat der E69
Benutzeravatar
Admin
Administrator
Beiträge: 1194
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Modellbahn - Bahnübergang - Lichtschranke

Beitrag von Admin »

Hallo Wolfgang

Ich habe gerade mal deine Lichtschranken getestet. Da geht nur ja/nein. Keine Entfernung. Aber wenn man nicht mehr braucht, ist das ja ok. Das Ding hat keinerlei Messaufwand. Da bekommt man am Pin. einfach High oder Low. Die entfernung auf die er regieren soll, stellt man mit dem Poti ein. ISt also viel leichter in einem Programm zusätzlich unter zu bringen. Ohne Library, einfach nur einen Digitalen Pin abfragen, fertig.

Gute Nacht
Franz :)
Benutzeravatar
Admin
Administrator
Beiträge: 1194
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Modellbahn - Bahnübergang - Lichtschranke

Beitrag von Admin »

Ich habe jetzt mal in dein Programm oben deine Lichtschranke eingebaut.
Lichtschranke ist auf Pin.3 das Relais zur Lichtschranke ist auf Pin.2
Und ich habe mal 1000ms also eine Sekunde Überbrückung eingebaut. Also wenn die Lichtschranke zwischen die Wagons leuchte, bleibt das Relais 1000ms angezogen. Wenn dann kein neuer Wagon kommt, fällt das Relais ab. Kannst du bei der Pausezeit01 einstellen.

Gute Nacht
Franz
:(V):

Code: Alles auswählen

#include <MobaTools.h>
/* Demo: Wechselblinker modifiziert von Bodo


   Dieses Demo ist etwas komplexer und zeigt die Realisierung eines
   Wechselblinker, der per Schalter ein- und ausgeschaltet wird.
   Wie bei Wechselblinkern an einem BÜ üblich, starten die beiden Lampen
   gleichzeitig, um dann im Wechseltakt zu blinken
   Dieses Demo verwendet auch die 'Eieruhr' um Zeitverzögerungen zu realisieren
   Die 'Eieruhr' ist ein Zeitzähler, der aufgezogen werden kann und im loop kann
   abgefragt werden, ob er abgelaufen ist.
*/

// Festlegen der Ports
const int Blinker1P  =  6;  // Die beiden Led's des
const int Blinker2P  =  7;  // Wechselblinkers.

const int Gleis1onP  =  8;  // Gleis 1 Start-Kontakt
const int Gleis1offP =  9;  // Gleis 1 Ende--Kontakt

const int Gleis2onP  = 10;  // Gleis 2 Start-Kontakt
const int Gleis2offP = 11;  // Gleis 2 Ende--Kontakt

const int Gleis3onP  =  4;  // Gleis 3 Start-Kontakt
const int Gleis3offP =  5;  // Gleis 3 Ende--Kontakt
// ----------- Lichtschranke aktivieren -------------------------------------------------
const byte Lichtschranke01 = 3; // Pin 3 ist für Lichtschranke
const byte LS_Relais01 = 2; // Pin 2 ist für Relais Lichtschranke
unsigned long LS_Laufzeit01 = 0; // Lichtschranke01 Ablauf Zeit
const unsigned long LS_Pausezeit01 = 1000; // Lichtschranke01 Prüfzeit Überbrückung
unsigned long milli_aktuell = 0;
byte LS_Status01 = 0;
// --------------------------------------------------------------------------------------
boolean SchalterP = false;  // Blinkschaltung on/off

boolean Gleis1    = false;  // Gleis 1 belegt/frei
boolean Gleis2    = false;  // Gleis 2 belegt/frei
boolean Gleis3    = false;  // Gleis 3 belegt/frei

// Weitere Konstante
const int wbZykl = 1100;    // Zykluszeit des Wechselblinkers
const int wbSoft = 400;     // Auf/Abblendzeit der Lampen

// Zustand des Wechselblinker
byte wblZustand = 0;        // In dieser Variable wird hinterlegt, in welchem Zustand
// sich der Wechselblinker gerade befindet
#define   WBL_AUS     0     // beide Lampen sind aus
#define   WBL_START   1     // Startphase: beide Lampen sind an
#define   WBL_BLINKT  2     // Die Lampen blinken normal im Wechsel
byte ledState;              // HIGH : Blinker1 ist an, LOW Blinker2 ist an

MoToSoftLed Blinker1;
MoToSoftLed Blinker2;

MoToTimer BlinkUhr;
//------------------------------------------------------------------SETUP----------------------------------------------------
void setup() {
  pinMode(Gleis1onP, INPUT_PULLUP);
  pinMode(Gleis1offP, INPUT_PULLUP);

  pinMode(Gleis2onP, INPUT_PULLUP);
  pinMode(Gleis2offP, INPUT_PULLUP);

  pinMode(Gleis3onP, INPUT_PULLUP);
  pinMode(Gleis3offP, INPUT_PULLUP);

  digitalWrite (LS_Relais01, HIGH); // Relaisausgang beim Start "aus"
  pinMode(LS_Relais01, OUTPUT);
  pinMode(Lichtschranke01, INPUT);

  Blinker1.attach(Blinker1P);     // die Ausgänge werden automatisch auf OUTPUT gesetzt
  Blinker1.riseTime( wbSoft );    // Aufblendzeit in ms

  Blinker2.attach(Blinker2P);
  Blinker2.riseTime( wbSoft );    // Aufblendzeit in ms
}
//------------------------------------------------------------------------LOOP----------------------------------------------
void loop() {
  // ---Millis übergeben----------------------------
  milli_aktuell = millis();
  // ---Lichtschranke01 Kontrolle-------------------
  LS_Status01 = digitalRead(Lichtschranke01);
  if (LS_Status01 == LOW) {
    digitalWrite (LS_Relais01, LOW); // Relais01 auf Pin2 einschalten
    LS_Laufzeit01 =  milli_aktuell;
  }
  else {
    if (milli_aktuell - LS_Laufzeit01 >= LS_Pausezeit01) // Überbrückungszeit abgelaufen ?
    {
      digitalWrite (LS_Relais01, HIGH); // Relais01 auf Pin2 ausschalten
    }
  }
  if ( digitalRead(Gleis1onP)  == LOW ) {
    Gleis1 = true;
  }
  if ( digitalRead(Gleis1offP) == LOW ) {
    Gleis1 = false;
  }

  if ( digitalRead(Gleis2onP)  == LOW ) {
    Gleis2 = true;
  }
  if ( digitalRead(Gleis2offP) == LOW ) {
    Gleis2 = false;
  }

  if ( digitalRead(Gleis3onP)  == LOW ) {
    Gleis3 = true;
  }
  if ( digitalRead(Gleis3offP) == LOW ) {
    Gleis3 = false;
  }
  SchalterP = Gleis1 || Gleis2  || Gleis3 ;                                 // Blinken, wenn Gleis 1 oder Gleis 2 oder Gleis 3 belegt

  // Wechselblinker
  switch (wblZustand) {
    case WBL_AUS:
      // Beide Lampen sind aus, warten auf einschalten
      if ( SchalterP == true && BlinkUhr.running() == false ) {
        // Beide Leds einschalten, Timer für gemeinsames Startleuchten
        Blinker1.on();
        Blinker2.on();
        BlinkUhr.setTime( wbSoft );
        wblZustand = WBL_START;
      }
      break;
    case WBL_START:
      // Startphase: Nach Zeitablauf erste Led wieder aus
      if ( BlinkUhr.running() == false ) {
        // Die Startzeit ist abgelaufen, Übergang zur normalen Blinkphase
        ledState = HIGH;
        Blinker2.off();
        BlinkUhr.setTime(wbZykl / 2); // Zeitverzögerung setzen
        wblZustand = WBL_BLINKT;
      }
      break;
    case WBL_BLINKT:
      if ( BlinkUhr.running() == false ) {
        BlinkUhr.setTime(wbZykl / 2); // Zeitverzögerung setzen
        if ( ledState == LOW ) {
          Blinker1.on();
          Blinker2.off();
          ledState = HIGH;
        } else {
          ledState = LOW;
          Blinker2.on();
          Blinker1.off();
        }
      }
      if ( SchalterP == false ) {
        // Wechselblinker abschalten
        Blinker1.off();
        Blinker2.off();
        wblZustand = WBL_AUS;
        BlinkUhr.setTime(wbZykl);   // minimale 'Aus' zeit des Blinkers
        //( schützt vor Schalterprellen )
      }
      break;

  } // Ende switch Wechselblinker
}
Antworten

Zurück zu „Hardware / Schaltungstechnik“

Wer ist online?

Mitglieder in diesem Forum: Ahrefs [Bot] und 1 Gast