Anwort hat bisschen länger gedauert, aber bei dir muss ich mir etwas mehr Zeit für die Antwort nehmen.
Was ich bislang verstanden habe:
- Weichenbewegung über MQTT auslösen und per MQTT zurückmelden
- Je nach GPIO Änderung, sollen Weichenbefehle ausgelöst werden
Richtig?
Dann würde ich es in zwei Klassen aufteilen:
- Eine MQTT-Klasse, die das empfängen und senden der MQTT Befehle übernimmt.
- Eine Klasse, die nur auf die GPIO hört und dabei Weichenbefehle auslöst.
Lorenzo hat geschrieben: ↑28.06.2019, 08:45
Was mir jetzt noch fehlt:
- das 'saubere' Reagieren auf Zustände, die am MCP23017 anliegen. Ich habe das mal versucht, in der CmdTransceiverMQTT::loop() mit Pin* pin01 = new Pin("E0A0"); und GPIOobj.digitalRead(pin01);
Das geht zwar grundsätzlich, aber es gibt nach einer Weile immer einen Reset. Ist so also noch keine Lösung. Vielleicht darf man ja aber auch nicht in einer Schleife immer wieder new Pin aufrufen?!?
Durch new erzeugt du immer ein neues Objekt und irgendwann hast du keinen Speicher mehr.
Lösung: Variable in der Klasse deklarieren, einmal im Konstruktor erzeugen und dann immer nur GPIOobj.digitalRead(pin01); nutzen
Lorenzo hat geschrieben: ↑28.06.2019, 08:45
Hier könnte ich mir vorstellen, dass die Zustände am MCP global zur Verfügung stehen, so dass ich sie jederzeit von überall her abfragen kann, oder aber dass bestimmte Zustände bestimmte Action Routinen aufrufen, z.B. bei Vorliegen eines bestimmten gesetzten Bits, controller->notifyTurnout(Addr, dir, 5) aufgerufen wird. Das habe ich versucht, in void Controller::notifyGPIOChange(int pin, int newvalue) unterzubringen. Das mag bei mir aber der Compiler nicht. Dazu kenne ich mich mit den Klassen noch nicht gut genug aus.[/list]
Der saubere Weg wäre, dass deine Klasse von INotify erbt und du anschließend die Funktion virtual void GPIOChange(int pin, int newValue);implementierst, um über Änderungen an den GPIO imformiert zu werden.
In Config.cpp muss du dann deine Klasse noch als Notify-Klasse registieren: controller->registerNotify(a);
Lorenzo hat geschrieben: ↑28.06.2019, 08:45
- die nächste Herausforderung ist für mich, die Zustände der Weiche auch über MQTT publish zu veröffentlichen, damit dort die Weichenzustände (z.B. für ein Gleisstellbild) synchron verfügbar sind.
Analog zu oben: Dazu sollte deine MQTT Klasse von INotify erben und anschließend die Klasse TurnoutCmd(int id, int direction, int source) implementieren, um über Weichenänderungen informiert zu werden.
In Config.cpp muss du dann wieder deine Klasse noch als Notify-Klasse registieren: controller->registerNotify(a);
Lorenzo hat geschrieben: ↑28.06.2019, 08:45
Macht es hier Sinn, bzw. ist es möglich, MQTT->publish in einer ActionMQTT zu verwalten (analog ActionServo), die ich dann von überall her aufrufen kann? MQTT senden und empfangen wären dann in zwei unterschiedlichen Modulen, was ja auch einen gewissen Charme hat.[/list]
siehe oben. Lieber bei der Klassen teilen.
Im Prinzip ist das Konzept einfach:
- Wenn du auf irgendeine Änderung lauschen willst, implementiere die Klasse inotify und nutzt in Config.cpp controller->registerNotify(a);
- Wenn du eine Änderung auslösen willst, notifyturnout
Wobei ich bei dem letzten Punkt gerade mir unsicher bin. Wie willst du die Lösung betreiben.
An einer Z21 Zentrale?
Die Rückmeldung an eine z21 ist noch nicht ganz fertig. Auch für das Thema Traktion muss ich diese Funktion noch einbauen.