Lichtschranke Impulse zählen

Guten Morgen,

ich hab da mal ne Frage, muß dazu aber ein bißchen was erklären. Also es geht um einen Achszähler für Modellbahnen.

Für alle die wo wissen wie ein Achszähler funktioniert, gehts unten weiter bei den Vorgaben. Für alle wos nicht wissen, hier eine kurze Erklärung. Im Gleis sind doppelte Zählkontakte installiert, ein Rechner wertet über den zeitlichen Verlauf der steigenden und fallenden Flanken sowohl die Fahrtrichtung aus und zählt die Achsen. Die Zählimpulse kommen daher daß ein Magnetfeld welches der Zählkontakt produziert, durch das vorbeifahrende Stahlrad verändert wird. Beim Zählerstand „Null“ ist der Abschnitt frei, bei ungleich „Null“ belegt. Soviel dazu in Kurzform.

Erstmal zu den „Vorgaben“ wo ich mir gesetzt hab:

  • Zählbereich von -252 bis +252
  • Richtungserkennung
  • basierend auf der erkannten Richtung rauf oder runter zählen
  • abschicken einer Meldung bei Zählerstand ungleich/gleich null
  • der Zug bewegt sich mit maximal 0,957854406 m/s :smiley: (300 kmh in 1:87)
  • bei einem Achsstand von 2 cm kommt alle 0,02088 s rein rechnerisch ein Impuls, also alle 20,88 ms, wenn ich richtig kalkuliert hab, das sollte für den Atmel von der Geschwindigkeit her kein Thema sein denke ich, normal fahren die Züge aber nur halb so schnell.

Gedanken zur Lösung:

  • Richtungserkennung über Doppellichtschranke
  • Flankenauswertung als Trigger für Zählimpulse
  • Meldung erstmal über serielle Schnittstelle (serial.println xyz) und eine LED als Anzeige

Bereits Geschafftes:

  • Flankenauswertung funktioniert (simuliert mit Drucktastern), über Abspeichern von altem Zustand und Vergleich mit neuem Zustand
  • Zählen rauf runter mit zwei Tastern funktioniert
  • Ausgabe der Meldung funktioniert

Was noch nicht geht:

  • das Erkennen der Richtung, dazu hab ich noch zwei Taster dazugebaut als Simulation der Doppel-Gabellichtschranke

Lösungsansatz:

Der Plan war daß der Atmel anhand des zeitlichen Verlaufs der Zustandswechsel an den Eingängen erkennt ob rauf oder runter gezählt werden soll. Also Fahrtrichtung ist vorwärts, denn geht erst die erste Lichtschranke auf „Low“, kurz danach die zweite, also muß hochgezählt werden. Geht die zweite zuerst auf „Low“ und kurz danach die erste, wird retour gefahren und es muß runtergezählt werden.

Problem dabei ist daß es keine Möglichkeit gibt, dem Atmel mitzuteilen welche Richtung gefahren wird, BEVOR der erste Zählimpuls kommt. Sprich er muß es selber merken. Es sind zwei Eingänge benutzt, an jedem ist eine Lichtschranke angeschlossen.

Meine Hoffnung ist jetzt daß mir da jemand vielleicht eine Inspiration geben kann wie ich sowas programmieren kann? Ich hab schon diverse Ansätze im Programm probiert, bisher hats aber nicht so getan wie ich wollte.

Meine jetzige Version vom Programm kann unabhängig voneinandern zwei Variablen hochzählen, es wird eine LED angeschaltet wenn eine der beiden Variablen ungleich null ist, und wenn beide Gleichstand erreicht haben, wird die LED wieder ausgemacht und die Zähler auf null gestellt. So ist es aber nur für den Einrichtungsbetrieb tauglich, weil es zählt nur hoch, also kann ich nur vorwärts fahren oder nur rückwärts fahren, und der Zug muß den Bereich immer komplett freifahren (heißt daß alle Achsen wo rein sind auch wieder raus müssen).

In Zukunft soll es aber so sein daß ich auch im Abschnitt halten kann, und in der anderen Richtung wieder wegfahren, und es trotzdem am Ende wieder auf Null steht, und da kommt die bisher fehlende Richtungserkennung ins Spiel. Bisher ist es nämlich so daß wenn vier Achsen vorwärts reinfahren, wird auf 4 hochgezählt, was ja auch richtig ist. Fahren jetzt vier Achsen rückwärts wieder raus, sollte es auf 0 runterzählen und der Abschnitt ist wieder frei. Leider zählt es wegen der fehlenden Richtungserkennung aber auf 8 statt auf 0. Und des ist eigentlich des „Problem“.

Falls was unklar ist oder noch Fragen sind, schreibt einfach, ich werd versuchen es besser zu erklären. Und sorry für den vielen Text :frowning: aber wenn man ein Problem ausführlich erklären will wird es halt viel Text.

Wenn ich rausfind wie ich Code anhängen kann mach ich des nachher noch.

Danke fürs Lesen und Eure Tipps, schönes Wochenende.

Viele Grüße Gregor.

Test_Az_auf_ab.ino (3.15 KB)

Setze Deinen Sketch einfach in Codetags (</> oben links im Forumseditor).

Gruß Tommy

Hallo,

Da hast Du für den Anfang fast zu viel Geschrieben. Ich hab mich bemüht Dir zu folgen aber irgendwo hab ich den Faden verloren, vielleicht hilfst Du mir ihn wieder zu finden. :wink: Als Kind hatte ich auch mal eine Modellbahn.
Wenn Du den Code direkt postest aber bitte in Code Tags, hast Du mehr potentielle Helfer.

Nun gut, lass uns den Faden finden.
Also Du hast NICHT alle 2cm einen Sensor sondern pro Abschnitt zwei Sensoren, stimmt das?
Wenn pro Abschnitt, sollte die Richtungsbestimmung sehr einfach sein, aber vielleicht hat das einen Nachteil den ich jetzt noch übersehe.

Sagen wir mal, die Sensoren sind 2 Taster so wie Du es getestet hast. Kommt er Zug von links, wir zuerst der Linke Taste gedrückt und dann, ein paar ms später, die rechte Taste. Jetzt weißt Du das er Zug von links kommt und nach rechts fährt. ← Wenn Du Dir eine lange Gerade (zB: Einfahrt in Bahnhof) vorstellst.
Verstehst Du was ich meine? Wenn das nicht geht, warum nicht?

Übrigens: Du verwendest wahrscheinlich Hall Sensoren, als Magnet Feld Sensoren. Such mal nach “attach_interrupt”. (link) Das Arduino Uno hat nur 2 Interrupt Pins, reicht für die ersten Tests. Welches Arduino verwendest Du? Der Vorteil beim Interrupt ist, das Sichergestellt ist, das jeder Flankenwechsel regestriert wird.
Die Funktion die durch den Interrupt aufgerufen wird, sollte allerdings nur einen Zähler und eine Variable für die Richtung haben. Warum das so ist, kannst Du einfach herausfinden wenn Du in eine Interrupt Funktion ein Serial.print() einbaust.

Taster müssen allerdings entprellt werden und eignen sich daher nicht für Interrupts.

Was mich Interessieren würde, Welche Sensoren sind auf den Schienen, und wie schaut das ganze aus, vielleicht hast Du ein aussagekräftiges Foto? Oder erzähl einfach.

Gruß,
Donny

N’Abend zämmä,

Tommy56:
Setze Deinen Sketch einfach in Codetags (</> oben links im Forumseditor).

Gruß Tommy

Danke für den Tipp, habs zwar schon angehängt als Download aber nochmal schadet ja nix, also hier ist was ich bis jetzt hab. Bitte nich hauen ist der erste Versuch und dementsprechend holperig geschrieben, ein Profi täts sicher anders machen^^

int Zp1_1_Status;
int Zp1_2_Status;
int Zp2_1_Status;
int Zp2_2_Status;

int Zp1_1_Speicher = HIGH;
int Zp1_2_Speicher = HIGH;
int Zp2_1_Speicher = HIGH;
int Zp2_2_Speicher = HIGH;

int entprellzeit_1_1 = 200;
int entprellzeit_1_2 = 200;
int entprellzeit_2_1 = 200;
int entprellzeit_2_2 = 200;

int Achsen1_1;
int Achsen1_2;
int Achsen2_1;
int Achsen2_2;

int reset;

unsigned long Zp1_1_Zeit = 0;
signed long Zp1_2_Zeit = 0;
unsigned long Zp2_1_Zeit = 0;
signed long Zp2_2_Zeit = 0;
  
void setup() { 

  Serial.begin(9600);

  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  
}

void loop() {

//*****   

Zp1_1_Status = digitalRead(4);

//***** 

if(Zp1_1_Speicher == HIGH && Zp1_1_Status == LOW) 
  {
    Zp1_1_Zeit = millis();
    Zp1_1_Speicher = Zp1_1_Status;
   } 

//***** 

if(millis() - Zp1_1_Zeit >= entprellzeit_1_1 && Zp1_1_Speicher == LOW)
  {
    Achsen1_1 ++;
    Zp1_1_Speicher = HIGH;
    Serial.println(Achsen1_1);
  }

//***** 

  Zp1_2_Status = digitalRead(5);

//***** 

if(Zp1_2_Speicher == HIGH && Zp1_2_Status == LOW) 
  {
    Zp1_2_Zeit = millis();
    Zp1_2_Speicher = Zp1_2_Status;
   } 

//***** 

if(millis() - Zp1_2_Zeit >= entprellzeit_1_2 && Zp1_2_Speicher == LOW)
  {
    Achsen1_2 ++;
    Zp1_2_Speicher = HIGH;
    Serial.println(Achsen1_2);
  }

//*****   

Zp2_1_Status = digitalRead(6);

//***** 

if(Zp2_1_Speicher == HIGH && Zp2_1_Status == LOW) 
  {
    Zp2_1_Zeit = millis();
    Zp2_1_Speicher = Zp2_1_Status;
   } 

//***** 

if(millis() - Zp2_1_Zeit >= entprellzeit_2_1 && Zp2_1_Speicher == LOW)
  {
    Achsen2_1 ++;
    Zp2_1_Speicher = HIGH;
    Serial.println(Achsen2_1);
  }

//*****   

Zp2_2_Status = digitalRead(7);

//***** 

if(Zp2_2_Speicher == HIGH && Zp2_2_Status == LOW) 
  {
    Zp2_2_Zeit = millis();
    Zp2_2_Speicher = Zp2_2_Status;
   } 

//***** 

if(millis() - Zp2_2_Zeit >= entprellzeit_2_2 && Zp2_2_Speicher == LOW)
  {
    Achsen2_2 ++;
    Zp2_2_Speicher = HIGH;
    Serial.println(Achsen2_2);
  }

//*****  

if(Achsen1_1 > Achsen1_2 || Achsen2_1 > Achsen2_2)       //wenn die Anzahl gezählter Achsen an Zähler 1 > Zähler 2 ist
  {
    digitalWrite(9, HIGH);     //wird Fahrtrichtung vorwärts angezeigt
  }

//***** 

if(Achsen1_1 < Achsen1_2 || Achsen2_1 < Achsen2_2)       //wenn die Anzahl gezählter Achsen an Zähler 1 < Zähler 2 ist
  {
    digitalWrite(10, HIGH);     //wird Fahrtrichtung retour angezeigt
  }  
  
//***** 

if(Achsen1_1 != 0 || Achsen1_2 != 0 || Achsen2_1 != 0 || Achsen2_2 != 0)
  {
    digitalWrite(13, HIGH);      //wenn die Anzahl gezählter Achsen an einem der Zähler ungleich
                                 //null ist, wird der Block belegt gemeldet
    //Serial.println(Achsen1_1);
    //Serial.println(Achsen1_2);
  }

if(Achsen1_1 == Achsen2_1 && Achsen1_2 == Achsen2_2)
  {
    digitalWrite(13, LOW);      //wenn die Anzahl gezählter Achsen an den Zählern gleich ist
                                 //null ist, wird der Block frei gemeldet
                                 //Obacht, funktioniert so nicht bei Rangierfahrt mit
                                 //Fahrtrichtungswechsel im Block, bloß bei Durchfahrt!!!
    Achsen1_1 = 0;
    Achsen1_2 = 0;
    Achsen2_1 = 0;
    Achsen2_2 = 0;
    digitalWrite(9, LOW);
    digitalWrite(10, LOW);
    //Serial.println(Achsen1_1);
    //Serial.println(Achsen1_2);
  }  

reset = digitalRead(8);  

if(reset == LOW)
  {
    digitalWrite(9, LOW);
    digitalWrite(10, LOW);
    digitalWrite(13, LOW);
    Achsen1_1 = 0;
	  Achsen1_2 = 0;
    Achsen2_1 = 0;
    Achsen2_2 = 0;
    Serial.println(Achsen1_1);
	  Serial.println(Achsen1_2);
  }
  
//***** 

}

dony:
Da hast Du für den Anfang fast zu viel Geschrieben. Ich hab mich bemüht Dir zu folgen aber irgendwo hab ich den Faden verloren, vielleicht hilfst Du mir ihn wieder zu finden. :wink: Als Kind hatte ich auch mal eine Modellbahn.
Wenn Du den Code direkt postest aber bitte in Code Tags, hast Du mehr potentielle Helfer.

Tut mir Leid hab mir schon gedacht es ist zu viel Text…natürlich helfe ich den Faden wieder zu finden.

Nun gut, lass uns den Faden finden.
Also Du hast NICHT alle 2cm einen Sensor sondern pro Abschnitt zwei Sensoren, stimmt das?

Stimmt. Ein Zählpunkt (Zp) besteht aus zwei Sensoren.

Sagen wir mal, die Sensoren sind 2 Taster so wie Du es getestet hast. Kommt er Zug von links, wir zuerst der Linke Taste gedrückt und dann, ein paar ms später, die rechte Taste. Jetzt weißt Du das er Zug von links kommt und nach rechts fährt. ← Wenn Du Dir eine lange Gerade (zB: Einfahrt in Bahnhof) vorstellst.
Verstehst Du was ich meine?

Jep, ich verstehe. So wollte ich es auch machen, über den zeitlichen Verlauf. Macht ja der Achszähler draußen beim Original auch so. Habs aber noch nicht hingekriegt also dachte ich suchst mal professionelle Hilfe :wink:

Wenn das nicht geht, warum nicht?

Tja das ist die Frage.

Übrigens: Du verwendest wahrscheinlich Hall Sensoren, als Magnet Feld Sensoren.

Momentan noch Taster wegen dem Aufbau aufm Steckbrett. Später sollen aber Gabellichtschranken montiert werden.

Such mal nach “attach_interrupt”. (link) Das Arduino Uno hat nur 2 Interrupt Pins, reicht für die ersten Tests. Welches Arduino verwendest Du? Der Vorteil beim Interrupt ist, das Sichergestellt ist, das jeder Flankenwechsel regestriert wird.
Die Funktion die durch den Interrupt aufgerufen wird, sollte allerdings nur einen Zähler und eine Variable für die Richtung haben. Warum das so ist, kannst Du einfach herausfinden wenn Du in eine Interrupt Funktion ein Serial.print() einbaust.

Ich hab ein Arduino Uno, und ein paar Atmega328P rumfahren. Die sollen später auf die Zählplatine. Wenn der aber bloß zwei Int Eingänge hat kann ich ja auch bloß einen Zählpunkt zählen gell? Ist irgendwie nicht so optimal weil es sollte mindestens zwei Zählpunkte zählen können, besser aber vier (Kreuzung). Kann ich da was mit einem MCP23017 erreichen?

Was mich Interessieren würde, Welche Sensoren sind auf den Schienen, und wie schaut das ganze aus, vielleicht hast Du ein aussagekräftiges Foto? Oder erzähl einfach.

Gruß,
Donny

Es sind wie gesagt Gabellichtschranken, jedenfalls im unsichtbaren Bereich, diese da:

Lichtschranke

Die wollte ich als einen Zählpunkt nehmen weils ja schon von Haus aus doppelt ist. Obs geht keine Ahnung. Flott genug sollte der Atmel ja sein mit 16 MHz?

Wieder zuviel geschrieben…hmmm…sorry.

meep meep

Gruß Roadrunner.

Roadrunner:
Wieder zuviel geschrieben…hmmm…sorry.

Nein, diesmal nicht. :wink:

Ich hab ein Arduino Uno, und ein paar Atmega328P rumfahren. Die sollen später auf die Zählplatine. Wenn der aber bloß zwei Int Eingänge hat kann ich ja auch bloß einen Zählpunkt zählen gell? Ist irgendwie nicht so optimal weil es sollte mindestens zwei Zählpunkte zählen können, besser aber vier (Kreuzung).

Ja damit hast Du Recht, leider hat sogar ein Arduino Mega nicht viele Interrupt Pins.

Also ich weiß ja nicht wie fit Du bist und eigentlich würde ich das folgende einem Anfänger nicht empfehlen:
Interrupts ← Wie Du siehst haben die 3,3 Volt Arduinos viel mehr Interrupts, das Arduino Due hat über 50 Pins und jeder kann als Interrupt verwendet werden. WARNUNG: Ein 3,3 Volt Arduino kann auf der Hardware Seite nicht mit einem viel robusteren Arduino Uno vergleichen werden. Ein Fehler in der Schaltung kann den Controller leichter zerstören als beim Arduino Uno.

Jep, ich verstehe. So wollte ich es auch machen, über den zeitlichen Verlauf…

Ja, über die Zeit rechnest Du die Geschwindigkeit. Indem Du ‘schaust’ welcher Taster (Gabellichtschranken) der Zug zuerst überfährt, bestimmst Du die Richtung.

Wegen der 16 MHz, bei Interrupts sollte es keine Probleme geben. Beim Polling, (Abfrage über digitalRead() ) kommt es drauf an wie das Sketch geschrieben ist, aber grundsätzlich auch kein Problem bei 20ms.

Gruß,
Donny

Auch der UNO/MEGA kann an jedem Input-Pin PCINT also PinChangeInterrupt. Man muss nur selbst ermitteln, welcher Pin eines Ports der Auslöser war.

Gruß Tommy

Hi

Wollte auch gerade schreiben, daß bei 20ms Laufzeit keine Probleme bei Polling zu erwarten sind.
Wenn die loop() 20ms pro Durchgang braucht, ist schon was faul (selbst 1ms empfinde ich als unangenehm lahm).

Damit solltest Du pro zwei DigitalIN eine Zählstelle realisieren können - man muß dort dann halt nur schauen, von welcher Richtung abgezogen und in welcher Richtung aufaddiert wird und diese ganzen Gleise 'im Hinterkopf' behalten.

MfG

PS: Die Ermittlung des auslösenden Pin des PCINT ist bei jedem AVR und an jedem Port, also kein Mangel am Arduino.
Wie geschrieben sehe ich aber keine Notwendigkeit, dafür einen INT einzusetzen, beide Wege sollten zum Ziel führen.

Hallo zusammen,

danke für Eure zahlreichen Hinweise. Arg viel verstanden hab ich davon bisher nicht aber ich bin auch noch nicht so fit ich tu mir teils schon noch arg herb :wink:

Gruß Roadrunner

Hallo,

mit Polling an x beliebigen Pins funktioniert das. Nur das mit der zeitlichen Unterscheidung wird nicht funktionieren. Spätestens wenn eine 3. und nachfolgende Achsen vorbeikommen gibts Kaos. Die Erfindung dafür lautet Graycode auswerten. Optimal ist es wenn die Achsen und Sensoren im Abstand so verbaut sind dass sie sich im gleichen Abstand überlappen. Du brauchst also 2 Sensoren für ein Achsenpaar. Wenn alle Achsenpaare ungefähr gleich überlappend drüber rauschen, gibts mit Graycode Auswertung keine Probleme. Drehgeber, Encoder oder was auch immer in der Art arbeiten nach dem gleichen Prinzip.

https://www.mikrocontroller.net/articles/Drehgeber
https://www.mikrocontroller.net/topic/drehgeber-auslesen

Tommy56:
Auch der UNO/MEGA kann an jedem Input-Pin PCINT also PinChangeInterrupt.

Der Mega kann es nicht an jedem Pin. Es gibt nur 3 Interrupt Vektoren und Maskenregister. Also 24 Pin Change Interrupts

Wenn der Achsenabstand einiges größer als der Abstand der Lichtschranken und der Verschattung ist, sollte es trotzdem funktionieren. Du kannst aus Rädern keinen Graycode machen, zumal es Wagons mit verschiedenen Radabständen geben dürfte.
Der kleinstmögliche Radabstand zur Radabschattung der Lichtschranken bestimmt die Möglichkeiten.
Bei den Abmessungen der geplanten Gabellichtschranken (wenn da alle Räder durch passen) sehe ich eher kein Problem mit einer sauberen Erfassung- Auch ohne Interrupt, wenn der Loop nicht ausgebremst wird, wie schon geschrieben wurde.

Gruß Tommy

Hi

Ich ging davon aus, daß eh pro Rad-Richtungserkennung ZWEI Sensoren zum Einsatz kommen und Diese minimal versetzt das vorbei rollende Rad detektieren.
Klar, daß der Abstand der Sensoren so gering sein muß, daß Beide wieder freigegeben sind, bevor das nächste Rad den ersten Sensor verdecken kann.

Die Nennung vom Gray-Code dürfte in die Richtung A/B der Rotary-Encoder gehen, wo die Folge 00 01 11 10 einem 2-Bit-Gray-Code entspricht - finde ich durchaus sinnig für das Verständnis.

MfG

postmaster-ino:
Die Nennung vom Gray-Code dürfte in die Richtung A/B der Rotary-Encoder gehen, wo die Folge 00 01 11 10 einem 2-Bit-Gray-Code entspricht - finde ich durchaus sinnig für das Verständnis.

Aber nicht sinnig für das zu lösende Problem der Achsen. Gießkannenprinzip geht oft vorbei.

Gruß Tommy

Hi,

postmaster-ino:
Ich ging davon aus, daß eh pro Rad-Richtungserkennung ZWEI Sensoren zum Einsatz kommen und Diese minimal versetzt das vorbei rollende Rad detektieren....

Es sind auch 2 Sensoren pro Achsenzähler und wenn ich es richtig verstanden habe ein Achsenzähler (2 Sensoren) pro Streckenabschnitt.

Ich stell mir das so vor: Die erste Achse der Lok fährt über den ersten Sensor (daraus kann dann auch die Richtung ermittelt werden) und die Zeit gemessen bis die erste Achse über den zweiten Sensor fährt. Dann kann auch die Geschwindigkeit ermittelt werden.

Edit: Jede Achse zu zählen, das wird so nichts. Es gibt Lokomotiven, die haben 2x2 Achsen vorne 2 und hinten 2. Eine Dampflok kann mit Tender bis zu 10 Achsen haben. Bei den Waggons ist es ähnlich. Also alles ab der erste Achse ignorieren. Aber vielleicht stell ich mir das zu leicht vor.

Grüße,
Donny

Hi

Die Geschwindigkeit wäre - in meiner Überlegung - ein Abfall-Produkt.
Weiter wären diese Sensoren für zwei benachbarte Streckenabschnitte 'gut'.
Die zwei Sensoren pro Rad-Erkennung ergeben, auch wenn Tommy56 Es nicht hören will, einen Gray-Code.
Diesen kann ich in jedem loop()-Durchlauf auf die entsprechende Richtung auswerten.
Der zeitliche Versatz der Sensoren A und B würden die Geschwindigkeit ergeben, sind aber für die State-Maschine 'Achsen auf Gleisabschnitt' nicht relevant.
00 Ruhe-Pegel
01 Rad von rechts
11 Rad auf beiden Sensoren, bei Wechsel auf 11 wird auf der VON-Richtung 1 abgezogen
10 Rad auf links, beim Wechsel von 11 weg wird in ZU-Richtung 1 dazu addiert
00 wieder Ruhe

(oder Ruhe bei 11, beide Lichtschranken nicht unterbrochen, dann Umschalten bei Wechsel zu 00 bzw dem Verlassen von 00)

So habe ich IMMER die Anzahl der Achsen vor und hinter dem Sensor - muß ja nicht beide Informationen benutzen.
In der Einlernzeit, also wenn noch gar nicht bekannt ist, wie viele ungezählte Achsen auf einem Gleis sind, muß ich natürlich drauf achten, daß ich keine negativen Achszahlen errechne - also nur Abziehen, wenn >0 Achsen auf dem Gleis vorhanden sind.
'eingeschwungen' ist das System, wenn JEDE Achse 1x über einen Sensor drüber gefahren ist (da Diese dann abgezogen wurde, sofern mehr als 0 Achsen auf dem Gleis vorhanden waren, und eben dazu gezählt wurden, wo diese Achsen jetzt sind)
Um Sich das Bewegen sämtlichen fahrenden Material bei jedem Start der Anlage zu ersparen, muß man sich die 'Achsen pro Abschnitt' merken und beim nächsten Start erst einlesen.

Zum Eingleisen wäre dann ein separates End-Gleis sinnig, da dort keine 'Achse' über bleiben kann, wenn der Zug hier runter fährt.
Bei einem Bahnhof o.Ä. könnten durch ungezähltes Aufsetzen der Gleisabschnitt fälschlich auf Null runtergezählt werden, obwohl dort noch rollendes Material steht.

MfG

Hallo,

okay, wenn der Achsabstand nicht gleich ist wird das nichts. Gibt ja auch einachsige Wagen etc. Leuchtet ein. Mit Lichtschranke wird das auch nichts. Wie soll die Achse zwischen die Gabel? Schon beim Thema zeitlicher Bezug versagt das Vorhaben. Man kann ja langsam und schnell vorbeifahren. Oder man bleibt drüber stehen und fährt plötzlich rückwärts. Wie will man dann feststellen welche Achse das ist. Am Prinzip des Graycodes kommt man laut meiner festen Überzeugung nicht vorbei, wenn man die Richtung eindeutig erkennen möchte. Belehrt mich gern wenn anders. Achszähler zählen nur sturr die Anzahl der einzelnen Achsen die vorbeikommen, egal welche das ist.

Ich löse das wie folgt. Ich klebe zwei kleine Neomagneten unter die Lok/Wagen. Zwischen den Schwellen sind Hallsensoren. Der Rest macht der µC mit seiner Graycodeauswertung. Die Richtungserkennung ist das “Abfallprodukt” der Auswertung. Völlig unabhängig von der Geschwindigkeit. Du kannst auch direkt drüberstehen und vor- und rückwärts zucken. Die Richtung wird sofort richtig angezeigt.

Bei deiner H0 hast du keinerlei Platzprobleme. Abstand Magnet = Abstand Sensoren. Das Magnetfeld muss sich überlappen. Stichwort Wahrheitstabelle. Fertig ist der Graycode.

Ich erzähle das so mit voller Überzeugung weil ich das schon seit langer Zeit getestet habe. Mit allen verteilten Sensorpaaren kannste noch die Geschwindigkeit messen oder was auch immer. Am Ende werden bei mir damit automatisch Weichen gestellt wenn der Zug anrollt.

Guten Tag,

hier wird ja fleißig diskutiert, denn scheint meine Idee ja doch nicht so fad zu sein wie ursprünglich gedacht :slight_smile:

So Begriffe wie Gießkannenprinzip und Graycode sagen mir zur Zeit noch nicht viel, aber des ist wohl auch Insiderwissen, bin eher noch Anfänger, bitte nicht hauen :wink:

Ich glaub aber ich muß doch ein bißchen mehr auf die Funktionsweise von Achszählern eingehen...aber der Reihe nach.

Tommy56:
Bei den Abmessungen der geplanten Gabellichtschranken (wenn da alle Räder durch passen) sehe ich eher kein Problem mit einer sauberen Erfassung.

So war der Plan. Es muß eigentlich auch nicht das ganze Rad reinpassen, es reicht der Spurkranz und der ist bloß ca 1 mm dick.

postmaster-ino:
Hi

Ich ging davon aus, daß eh pro Rad-Richtungserkennung ZWEI Sensoren zum Einsatz kommen und Diese minimal versetzt das vorbei rollende Rad detektieren.
Klar, daß der Abstand der Sensoren so gering sein muß, daß Beide wieder freigegeben sind, bevor das nächste Rad den ersten Sensor verdecken kann.

So ist es. Erklärung siehe weiter unten.

dony:
Hi,
Es sind auch 2 Sensoren pro Achsenzähler und wenn ich es richtig verstanden habe ein Achsenzähler (2 Sensoren) pro Streckenabschnitt.

Fast richtig, Erklärung siehe unten.

Ich stell mir das so vor: Die erste Achse der Lok fährt über den ersten Sensor (daraus kann dann auch die Richtung ermittelt werden) und die Zeit gemessen bis die erste Achse über den zweiten Sensor fährt. Dann kann auch die Geschwindigkeit ermittelt werden.

Des mit der Richtung stimmt ja. Wie es genau abläuft weiß ich noch nicht, es geht aber auf jeden Fall über den zeitlichen Verlauf, sagt der Besitzer von den Achszählern :wink:

Edit: Jede Achse zu zählen, das wird so nichts. Es gibt Lokomotiven, die haben 2x2 Achsen vorne 2 und hinten 2. Eine Dampflok kann mit Tender bis zu 10 Achsen haben. Bei den Waggons ist es ähnlich. Also alles ab der erste Achse ignorieren. Aber vielleicht stell ich mir das zu leicht vor.

Naja eigentlich soll ja jede Achse gezählt werden sonst bringt es nicht viel. Auf die Art wird auch die Vollständigkeit der Züge geprüft, aber das steht momentan nicht zur Debatte, und würde wohl auch zu weit in die Weite führen. Auch hier Erklärung s.u.

postmaster-ino:
In der Einlernzeit, also wenn noch gar nicht bekannt ist, wie viele ungezählte Achsen auf einem Gleis sind, muß ich natürlich drauf achten, daß ich keine negativen Achszahlen errechne - also nur Abziehen, wenn >0 Achsen auf dem Gleis vorhanden sind.

Normalerweise werden Vorwärtsfahrten hochgezählt und Rückwärtsfahrten runter.

Um Sich das Bewegen sämtlichen fahrenden Material bei jedem Start der Anlage zu ersparen, muß man sich die 'Achsen pro Abschnitt' merken und beim nächsten Start erst einlesen.

Das wollte ich umgehen indem ich die Zählerstände abspeichere...weiß nur noch nicht wo und wie^^

Zum Eingleisen wäre dann ein separates End-Gleis sinnig, da dort keine 'Achse' über bleiben kann, wenn der Zug hier runter fährt.

Des ist richtig, und eine gute Idee dazu noch. Hab ich so noch gar nicht dran gedacht, danke!

Bei einem Bahnhof o.Ä. könnten durch ungezähltes Aufsetzen der Gleisabschnitt fälschlich auf Null runtergezählt werden, obwohl dort noch rollendes Material steht.

Des kann auch sein ja. Man sollte es vermeiden einfach irgendwo was draufzustellen.


So, jetzt zur versprochenen Erklärung für alle Interessierten. Beim Vorbild läuft die ganze Sach so. Die Strecke ist in Abschnitte (Blöcke) geteilt. Ein Block hat zwei Zählpunkte (Zp), einer am Anfang und einer am Ende. Die bestehen aus zwei voneinander unabhängigen Zähleinheiten. Kommt ein Rad vorbei, wird erst eine Zähleinheit ausgelöst, dann die andere. So weiß der Zp die Fahrtrichtung, und kann dann sagen "He, ich muß rauf oder runter zählen". **Wichtig:**Vorwärtsfahrten werden immer hochgezählt, Retourfahrten immer runter. Deswegen ist auch für den Block eine Richtung als Vorwärts definiert, die andere dementsprechend als retour. Die Besetztmeldung erfolgt immer dann, wenn einer von den Zp wo zum Block gehören einen Zählwert ungleich null hat. Bei Null sind keine Achsen im Block, und es ist frei.

Fährt ein Zug auf einer Strecke, zählen die Zähler am Blockanfang und Blockende die vorbeifahrenden Achsen. Haben beide Gleichstand erreicht, ist der Zug durch, die Zähler setzen sich zurück und sind wieder in Ruhestellung.

Ja des war jetzt die Kurzform, hoffe es ist ein bißchen klarer geworden wie ichs mir vorstelle. Obs möglich ist, keine Ahnung...

Gruß

Hi

Deckt sich doch fast mit meiner Denkweise :slight_smile:
'Vorwärts' und 'Retoure' ist reine Definitionssache, wie in meinem Beispiel 'links' und 'rechts' (man kann ja auch von der anderen Gleisseite gucken).
Wichtig ist nur, daß bei jedem Zp auf der 'Von-Seite' die Achse abgezogen wird und auf der 'Zu-Seite' hin-zugezählt.
Auch könnte man jedem Zp beibringen, auf welche Streckenabschnitte Diese zählen.
Bei den Ausmaßen der Eisenbahn wird I²C wohl nicht mehr klappen, da ich selber mit CAN spiele, wäre Das meine Variante.

  • jeder Zp hat eine ID
  • bei jeder Überfahrt wird Diese der 'Zentrale' gemeldet wie die Fahrtrichtung
  • die Zentrale liest die dem Zp anliegenden Streckenabschnittsnummern
  • Sie liest dann Deren aktuelle Achsenzahlen
  • addiert/subtrahiert 1 (je nach Richtung
  • speichert diese Achsenzahlen wieder ab

Speichermedium: Fram

Vorteil hierbei: Beliebig oft beschreiben, sau schnell, Datenerhalt bei Spannungsverlust, die aktuellen Werte kommen aus dem Fram und gehen dort hin auch wieder direkt zurück, Ansteuerung per I²C, SPI, Parallel erhältlich
Meine Exemplare haben 32kB Größe - sollte für einige Zp reichen.
Wenn jeder Zp zwei 16bit Werte für die angrenzenden Streckenabschnittsnummern enthält, sind Das 4 Byte pro Zp als Lookup-Tabelle.
Jeder Streckenabschnitt hat einen 16bit Wert für die Anzahl der gezählten Achsen (0...65535 Achsen, bei 24bit bis 16777215)

Pro Zp 4 Byte, pro Abschnitt 2 Byte

Man muß sich vorher klar sein, wie viele Zp man hat (damit die Tabelle ein definiertes Ende hat bzw. eher die Tabelle der Achsenzahlen der Streckenabschnitte ein definierten Anfang hat)

Kommunikation per CAN hätte

  • die Kollisionserkennung integriert (wenn zwei Fp gleichzeitig sabbeln, werden Die sich einig, Beide kommen durch)
  • Arbitrierung (Aushandeln der Reihenfolge bei Kollision)
  • 8 Byte Daten, sollte für Zp-ID und Richtung reichen - auch mit Geschwindigkeit
  • 11bit ID-Vorrat in Standard, 29bit in Extended (2048 bzw 536870912 mögliche IDs für die Zp)
  • bräuchte nur 2 Drähte zwischen den einzelnen Komponenten

Auch könnte ein Arduino mehrere Zp aufnehmen/bedienen, Er muß 'nur wissen', welche ID diese Zp jeweils haben und in welcher Richtung Diese 'vorwärts' erkennen - damit man die angrenzenden Streckenabschnitte korrekt eintragen kann.

Die Grundstellung in den Fram rein bekommen könnte etwas Arbeit darstellen - so weit bin ich bei mir nämlich auch noch nicht.
(bekomme hier sekündlich Temperaturen/Luftdrücke/Luftfeuchte (BME280), Die aufgezeichnet und/oder zu einer Grafik verarbeitet werden wollen)

MfG

============;===============;==============;================;============
Abschnitt 1  Abschnitt 2      Abschnitt 3     Abschnitt 4        Abschnitt 5
           Fp1            Fp2              Fp3             Fp4

Der Fram enthielte dann folgende Struktur
Fp1 Abschnitt1 Abschnitt2
Fp2 Abschnitt2 Abschnitt3
Fp3 Abschnitt3 Abschnitt4
Fp4 Abschnitt4 Abschnitt5
.....
Abschnitt1 0 Achsen
Abschnitt2 0 Achsen
Abschnitt3 0 Achsen
Abschnitt4 0 Achsen
Abschnitt5 0 Achsen

Verständlich?

MfG

Guten Morgen,

postmaster-ino:
Bei den Ausmaßen der Eisenbahn wird I²C wohl nicht mehr klappen, da ich selber mit CAN spiele, wäre Das meine Variante.

  • jeder Zp hat eine ID
  • bei jeder Überfahrt wird Diese der 'Zentrale' gemeldet wie die Fahrtrichtung
  • die Zentrale liest die dem Zp anliegenden Streckenabschnittsnummern
  • Sie liest dann Deren aktuelle Achsenzahlen
  • addiert/subtrahiert 1 (je nach Richtung
  • speichert diese Achsenzahlen wieder ab

Die Idee hab ich auch schon gehabt, meine Steuerungssoftware zählen zu lassen. Habs denn aber wieder verworfen weil die den PC schon genug auslastet mit der Blockberechnung. Deswegen war mein anderer Ansatz, ich zähle oder lasse dezentral einen uC zählen und schicke denn "bloß" die Meldung frei oder nicht frei in den CAN Bus.

Jeder Streckenabschnitt hat einen 16bit Wert für die Anzahl der gezählten Achsen (0...65535 Achsen, bei 24bit bis 16777215)

Eigentlich reichts bis 252 :wink:

Verständlich?

Teilweise. Bin wie gesagt noch recht neu...

Gruß