MOBA Wechsel-/Pendelsteuerung

Hier mal das Bild der Anlage, fährt in Pfeilrichtung:
Edit, kann immer noch keine Dateien hochladen. Oje.
Hier wieder der Link auf die Dateien: WeTransfer - Send Large Files & Share Photos Online - Up to 2GB Free

Ich denke auch, dass wild probieren nicht gut ist, daher hätte ich gerne den Ansatz verfolgt mal nur mit dem kopierten Code diese Bahnhofs Routine in Gang zu bekommen mit Deinem OOP, na dann gehe ich nun die zweite Steuerung löten. Für den manuellen Betrieb, kann ich jedoch nur an einem Ort sein :face_with_monocle:
PS: Habe die mehrfacherkennung durch die Weiche1_stellung resp. weiche3_stellung verriegelt. Das länger On bleiben der Reed Leds habe ich mit der block[6] Variable realisiert, die nur ein einziger Eintritt in den Abschnitt erlaubt.

Hallo,

wenn das GPIO Signal entprellt ist, dann wäre nach dem Gedanken, wenn die Logik hoffentlich erhalten bleibt.
Edit:
Habs korrigiert, weil der Trigger bzw. Flankenerkennung ist ja nur einmal vorhanden, sonst wäre es keine Flankenerkennung. Das zur Vollständigkeit.

Code
DetectSignalEdge signal_U4_Reed7;
// ====================================================
signal_U4_Reed7.init();
// ====================================================

// Reed Sensor 7 - Bahnhof 2 anhalten
if (signal_U4_Reed7.risingEdge(GPIO_U4_Led18_Reed7)) {
  if(block[6] == 0  && bahnhof2_stop == 0 && GPIO_U1_Bahnhof2 == 1) { 
    // Block 7 resp. 6 sperren
    block[6] = 1;
    bahnhof2_stop = 1;
    Fahrspannung_anhalten();  // Verlangsamen und anhalten
    // Serial.priintln("Bahnhof 2 ein");
    init8Time = currentTime;  // Wartezeit Bahnhof 2
    Serial.println("bahnhof 2.1, Anhalten, Warten");
  }

  if (block[6] == 2  && bahnhof2_stop == 2 && GPIO_U1_Bahnhof2 == 1) { 
    block[6] = 3;
    // Startwert in Warteschlaufe mitgegeben, da Fahrspannung_Anfahren(); übergangen wird
    Fahrspannung_anfahren(); // anfahren
    Serial.println("bahnhof 2.2, anfahren");
  }

  if (block[6] == 3 && bahnhof2_stop == 2 && (fahrregler_PWM_auto >= 110) && GPIO_U1_Bahnhof2 == 1) { 
    block[6] = 4;
    bahnhof2_stop = 4;
    Fahrspannung_schneller();              // weiter fahren Rangierspannung bis max Trimmer Geschwindigkeit
    // vorherigen Block[0] frei geben
    block[0] = 0;
    Serial.println("bahnhof 2.3, Schneller");
  }
}

Die Instanz und der GPIO Parameter in Klammer müssen immer zusammengehören. Wenn du das für jedes Signal sauber benennst, hast du getrennte Flankenerkennung.
Vielleicht rettet dich das noch. Ist dann damit leider etwas mehr verschachtelt.

Mit den MobaTools wird das schöner. :wink:

Ok, dann geht es Richtung MobaTools Library, habe mich eingelesen. Dem Example zu folge wäre das für mich machbar. Das Array[] der Pins habe ich ja schon Muss noch schauen welche Files es benötigt: sicher die MoToButtons.h und noch eine?, die Button_I2C.ino müsste ich anpassen auf den MCP23017, benötige da ja nur den einen Port (7 Bit, das 8 Bit hat Microchip ab 2020 gestrichen) als "langsame" Taster....

Die MoBaTools resp. MoToButtons.h sind eingebunden und erkennen nun bei jeder Durchfahrt des Zuges die Magnete der Lok und Wagen, jedenfalls im Seriell Montor. Die Leds haben nur selten aufgeläuchtet daher habe ich diesen Abschnitt in eine Funktion ree2led gepackt und rufe sie am Schluss des keypressed auf. Nun leuchten die Leds immer beim überfahren des Reed Sensors.

-> Als nächstes möchte ich nun dieses Bahnhofanhalten von Post #40 (MOBA Wechsel-/Pendelsteuerung - #40 by train_control) ebenfalls auf Basis der MoBaTools umbauen. Welche der Funktionen bieten sich da am besten an? Es müsste eine Funktion einer Ablaufkette sein:
-> Block Led vorhergehenden Block löschen
-> Langsamer fahren (ist selber schon eine Kette, siehe Post #40
-> Anhalten (ist selber schon eine Kette, siehe Post #40
-> Warten z.B. 12 sec
-> Langsam anfahren (ist selber schon eine Kette, siehe Post #40
-> Auf Fahrgeschwindigkeit erhöhen (ist selber schon eine Kette, siehe Post #40

Hallo,

bezüglich Flankenerkennung? Würde sagen wollen entweder
pressed() oder released() je nach Flanke.

Das sehe ich auch so.

Das wäre ein Plan... ( Auch wenn es nach deinem Bildchen - so wie ich das verstehe - nicht wirklich eine 'Pendelsteuerung' ist.

Was soll denn da wie fahren - und wie ist der Fahrstrom angeschlossen? Kann der gleisspezifisch abgeschaltet werden - wenn ja wo. Solange Du nicht mal ordentlich erklärst, was da ablaufen soll, kann man nicht wirklich helfen.

Ich würde auch deine Timer komplett auf MoToTimer.h umstellen. Das geht in die Richtung, die @Doc_Arduino auch schon angesprochen hat. Dann sind die ganzen Timer ordentlich entkoppelt und kommen sich auch nicht in die Quere. Einfach Zeit setzen und dann abfragen ob abgelaufen. Wobei es da auch so eine Art 'Flankenerkennung' gibt. timer.expired() wird nur einmal nach dem Timerablauf wahr. Da kannst Du ganz einfach einmalige Aktionen nach Timerablauf starten. Erst wenn Du den Timer neu startest kann das timer.expired() wieder wahr werden.

Grundsätzlich kannst Du aber auch einfach die MobaTools.h einbinden, da ist alles dabei. Was Du nicht nutzt, wird auch nicht als Code eingebunden.

So ist es :sunglasses:

Es wäre wesentlich übersichtlicher, wenn Du solche 'Ketten' zumindest in getrennte Funktionen auslagern würdest. Das wäre schonmal etwas weniger 'Spaghetti'. Als Klasse wäre natürlich noch schöner :wink:

Ich seh da nur einen Schienenkreis mit einem Ausweichgeleise. F0: Ist das alles?
F1: Was hängt an welchem Port / welchem Portexpander?

F2: Gibt es nur eine Fahrspannung?

F3: Wird Abstellgleis 1 und/oder Hauptgleis abgeschalten? Wenn ja womit?

F4: Ich nehme an, das sind 6 Reed Kontakte und zwei Weichen? (warum gibts im Code 4 Weichen?)

F5: Was gibt es alles an Taster - wie gibst du welche Befehle ein?

Zu F0: Ja es gibt nur ein Schienen Kreis mit 2 Weichen und somit einem Abstellgleis
Zu F1: An den 4x GPIO MCP23017 hängen vorallem die LED's und die 3 Taster Run, Stop und Stopping (Dies funktioniert ja mit der MoBaTools Library auch (würde ich nicht in den Fokus nehmen).
Zu F2: J es gibt nur eine Fahrspannung die wechselt mit den 4 Funktionen wie oben beschrieben in #40
Zu F3: Die Weichen schalten auch den Fahrstrom
Zu F4: Dieses zweite Abstellgeleise könnte noch nachgerüstet werden, ist aktuell nicht in Betrieb. Wird per J11 / 1 Ein oder Ausgeschalten -> Per Setup() beim Starten , Redkontakt 4 (Block[3]) wird hier (noch) nicht verwendet

Ja wie schreibe ich da eine Klasse? Leider fehlt mir für OOP aktuell die Zeit zum begreifen und umsetzen bis am 9.1. und kompl. das Wissen inkl. das abstrakte Denken. Es sind schon alles einzelne Blöcke / Funkltionen dahinter die ich mit der block[n] immer auf den nächsten Abschnitt schalte. In #40 der Bahnhof "Aktionen" schön zu sehen.

Beim Zug durchfahren hat jeder Wagen und die Lok vorne und hinten ein Magnet, somit wird dieser Sensor mehrfach erkannt :wink:
Habe desshalb die Led als Merker resp. Blockbesetzt definiert welche beim durchfahren des nächsten Abschnittes dann zurückgesetzt wird.

Hallo,

wenn du für OOP sowieso aktuell keine Zeit hast, brauchen wir darüber auch nicht reden. Wäre derzeit Zeitverschwendung - denke ich.
Wenn du alles in einzelne Funktionen zerlegt hast, dann wäre es vielleicht noch machbar einen Zustandsautomaten zu schreiben.
Stichworte. enum und switch case

Im Deutschen PDF habe ich nicht so viel über die Funktionen gelesen, im Code jedoch war einiges. Muss das nach dem zweiten Kaffee nochmals durchlesen und mal auf Grund des Bahnhofes versuchen zum zu setzen. Den Alten Code habe ich ja noch, wobei manuelles fahren ja auch noch immer geht ....

Ja habe da gestern in der Not diese beiden Beiträge gefunden:

Das mit dem millis() kenne ich nun und würde die so umsetzen können.

  • habe das Gefühl, weil im geschachtelnen init3btime zum Bsp. dann die init5atime oder auch ein init7time aufgerufen wird, das dies dann für das currentime = millis() welches am Anfang der Schlaufe steht zu spät ist? Müsste nicht in jeder millis - if Schlaufe das aktuelle millis() abgefragt werden oder ist das normalisiert auf den currentime zu beginn des loop() so wie es nun ist?

komm einfach nach dem 10ten wieder wenn du Zeit hast.
Dann auch mit einem vernünftigen Schaltplan aus dem man die Pinzuordnngen erkennt.
In dem Spaghetti ist imho jede Mühe verloren.

Klingt jetzt nach "not invented here" ... kann auch so sein ... aber so wird meiner Meinung nichts langlebiges draus.

Ich habe ja auch geschrieben, dass das Auslagern in eine Funktion auch schonmal was bringen würde - da brauchts noch keine OOP.

Wir sind jetzt beim 60. Post, und Du hast immer noch nicht ordentlich beschrieben was da eigentlich ablaufen soll. Fragen beantwortest Du immer nur so, als ob wir das alles schon wüssten. Wir wissen nichts - ausser dem was Du schreibst.
Diese Fragen beziehen sich nicht auf deinen Code - das sind Fragen zum Projekt: Was soll da passieren. Es kann doch nicht so schwierig sein, das mal in einfachen Worten zu beschreiben.
Was soll da an Zügen wie herumfahren. Auch eine einfache Handskizze des Gleisplans mit den genauen Positionen der Reed-Kontakte wäre wichtig. Dann könnte man wesentlich zielgerichteter helfen.

Ich habe das nun schon ein paar mal beschrieben was es machen muss/soll. Der Code ist auch rel. gut dokumentiert, was was bedeutet. Es ist mir aber klar, dass man nicht eben schnell 2000 Zeilen Spagetthi verstehen kann. Kann aktuell/Momentan auch kein 25 seitiges Pflichtenheft in prosa schreiben. wenn Du verstehst was ich meine.

  • Es geht momentan nur darum wie ich z.B. auf Grund der von mir beschriebenen Bahnhofsfunktion das in einzelne millis() Funktionen auslagere. (Ich entkopple jeden Block mit IF mit einer millis() Funktion?)
  • Der Loop() Durchgang hat ohne IF's der Funktionen eine Durchlaufszeit von 1 bis 6 mS. (gemessen)
  • Wenn eine Funktion aktiv ist, benötigt er ca. 12 mS - 6 mS gibt dann auch 6 mS
  • Es werden alle Reed Kontakte erkannt und auch die Block Led angeleuchtet und auch gelöscht.
  • Nach dem Einschalten, hält der Zug die ersten 2 Male am Bahnhof an und fährt weiter wie es sein muss. Leider ab den 3. Durchlauf, hällt er nicht mehr an und fährt durch.
  • An anderen Stationen / Blöcke führt er keine Aktionen aus.
  • Sieht mir so aus wie eine Windows System ;-(

Werde mich nun nachmals mit dem Implementieren der millis() beschäftigen, da ist sicher was falsch.
Frustrierte Grüsse

Du hast noch gar nichts beschrieben. Wieviele Züge fahren? Wann fährt ein Zug wo? wechseln die sich ab? fahren alle in die gleiche Richtung? Wann und wo sollen sie anhalten?
Dazu braucht es kein 25-seitiges Pflichtenheft. Das kann man in ein paar Zeilen Prosa beschreiben. Aber Du lässt uns lieber im Dunkeln tappen.
Ich bin hier raus!