Hallo zusammen,
bin jemand, der in der Coronazeit die Eisenbahn der Jugend (Märklin) wiederentdeckt hat und die digitale Welt eingestiegen ist.
Ich habe im Internet das Railuino-Projekt https://github.com/MBuratto/railuino gefunden, dass einen Arduino mit CAN-Bus Shield benutzt, um mittels der Gleisbox von Märklin die Modelleisenbahnanlage zu steuern.
Um eine Anbindung an ein tcp-Netz herzustellen habe ich den Arduino durch einen esp8266 (mit WLAN) und das Shield durch ein Can-Bus Module arduino mcp2515 ersetzt. Dazu habe ich den CAN Bus Treiber in der Railuino Library ausgetauscht. im esp8266 Sketch wird eine mqtt Schnittstelle eingebunden, auf denen der Arduino horcht (subscribe) und Messages legt (publish).
Das Datenformat der Messages ist JSON.
Soweit funktioniert es. Habe mir 2 Pendelzugteststrecken aufgebaut, eine mit Märklin Gleisen und MM2 Lok und eine mit 2-Leiter System (Peco Gleise mit DCC TRIX Lok). Als Rückmelder habe ich mir ein reed-Kontakt System gebaut, das mit einem weiteren esp8266 abgefragt wird und das bei überfahren dieses Event als JSON auf die MQTT Queue überträgt.
Als überliegende Steuerungssoftware habe ich ein python Skript geschrieben, das auf der MQTT horcht, Events entgegennimmt, entscheidet, was zu tun ist (Lok starten, Lok stoppen, Fahrtrichtung wechseln etc.). und dieses in wieder JSON verpackt und auf die MQTT Queue legt.
(Dieses wird s.o. vom Railuino-Arduino entgegengenommen, der JSON entpackt und in Railuino Libraryfunktionen umgesetzt und über den das CAN-BUS Modul auf die Gleisbox und dann damit auf die Schiene übertragen.)
Jetzt zu meiner Frage: Wäre es eine Idee und möglich, mein spezielles python Skript durch RailContral zu ersetzen? D.h. die Kommunikation würde gegen eine virtuelle MQTT-JSON Schnittstelle erfolgen, an der sich mein kleines Projekt mit Railuino oder jegliches andere andocken könnte.
Mit freundlichen Grüßen
Joachim
p.s.: Im Anhang ist noch eine Zeichnung
Fixed: Virtuelle MQTT-JSON Zentrale
Fixed: Virtuelle MQTT-JSON Zentrale
- Attachments
-
Modelleisenbahn-mqttjson.pdf
- (83.18 KiB) Downloaded 244 times
Re: Virtuelle MQTT-JSON Zentrale
Hallo Joachim
Ja natürlich ist das möglich. Müsstest es aber selbst in RailControl einbinden. Den Source Code hast du ja zur Verfügung. Neue Zentralen sind relativ einfach einzubinden.
Damit ich es auch mit aufnehme ins Git Repository müsste es unter Linux, Mac und Cygwin lauffähig sein.
Gruss
Teddy
Ja natürlich ist das möglich. Müsstest es aber selbst in RailControl einbinden. Den Source Code hast du ja zur Verfügung. Neue Zentralen sind relativ einfach einzubinden.
Damit ich es auch mit aufnehme ins Git Repository müsste es unter Linux, Mac und Cygwin lauffähig sein.
Gruss
Teddy
Re: Virtuelle MQTT-JSON Zentrale
Hallo Teddy,
ok, ich möchte es mal probieren.
Dazu habe ich mqttjson.cpp, mqttjson.h aus virtual erstellt und schon mal die Header Files der mosquitto lib und json-c lib eingebunden. Soweit kompiliert es.
Was muss ich tun, um die neue "Hardware" im Programmablauf anzumelden. Gibt es etwas, was mir hilft?
Gruß
Joachim
ok, ich möchte es mal probieren.
Dazu habe ich mqttjson.cpp, mqttjson.h aus virtual erstellt und schon mal die Header Files der mosquitto lib und json-c lib eingebunden. Soweit kompiliert es.
Was muss ich tun, um die neue "Hardware" im Programmablauf anzumelden. Gibt es etwas, was mir hilft?
Gruß
Joachim
Re: Virtuelle MQTT-JSON Zentrale
Hallo Joachim
So aus dem Bauch raus kommt mir in den Sinn:
enum HardwareType in DataTypes.h ergänzen.
HardwareHandler::ArgumentTypesOfHardwareTypeAndHint ergänzen.
HardwareHandler::Init ergänzen.
WebClientStatic::ListHardwareNames ergänzen.
Irgendwie sollte man das etwas zentralisieren. Aber das ist ein anderes Thema.
Gruss
Teddy
So aus dem Bauch raus kommt mir in den Sinn:
enum HardwareType in DataTypes.h ergänzen.
HardwareHandler::ArgumentTypesOfHardwareTypeAndHint ergänzen.
HardwareHandler::Init ergänzen.
WebClientStatic::ListHardwareNames ergänzen.
Irgendwie sollte man das etwas zentralisieren. Aber das ist ein anderes Thema.
Gruss
Teddy
Re: Virtuelle MQTT-JSON Zentrale
Hallo Teddy,
was bis dato funktioniert, ist, railcontrol Befehle umzusetzen und nach mqtt zu publishen und damit meinen Testaufbau zu steuern. D.h. Fahrstrom an/aus. Lok fahren/stoppen, Richtung ändern und Licht.
Bei subscribe kann ich die Rückmelder Messages aus der mqtt Queue lesen und habe die Daten in meiner "Rueckmeldefunktion" zur Verfügung. Was mir fehlt, ist der Feedback an den railcontrol Manager. Habe so etwas gefunden wie "manager->FeedbackState(controlID, pin, state);". Ist das der richtige Weg? Wie binde ich die Funktion ein?
Hilfe wäre willkommen ...
Gruß
Joachim
was bis dato funktioniert, ist, railcontrol Befehle umzusetzen und nach mqtt zu publishen und damit meinen Testaufbau zu steuern. D.h. Fahrstrom an/aus. Lok fahren/stoppen, Richtung ändern und Licht.
Bei subscribe kann ich die Rückmelder Messages aus der mqtt Queue lesen und habe die Daten in meiner "Rueckmeldefunktion" zur Verfügung. Was mir fehlt, ist der Feedback an den railcontrol Manager. Habe so etwas gefunden wie "manager->FeedbackState(controlID, pin, state);". Ist das der richtige Weg? Wie binde ich die Funktion ein?
Hilfe wäre willkommen ...
Gruß
Joachim
Re: Virtuelle MQTT-JSON Zentrale
Hallo Joachim
Du bist auf guten Weg. Kannst in Hsi88.cpp:181 spicken.
Gruss
Teddy
Du bist auf guten Weg. Kannst in Hsi88.cpp:181 spicken.
Gruss
Teddy
Re: Virtuelle MQTT-JSON Zentrale
Hallo Teddy,
Danke für den Hinweis.
Bin leider in eine C, C++ Sackgasse gelaufen. Die mosquitto library arbeitet mit C Callbackfunctions. Leider kann ich C++ class member functions dafür nicht verwenden, es sei denn, ich deklariere sie static. Dann kann ich aber nicht mehr in ihr auf die Klasseninhalte zugreifen (manager, controlD).
Mmhh, brauche erst mal etwas Abstand.
Gruß
Joachim
Danke für den Hinweis.
Bin leider in eine C, C++ Sackgasse gelaufen. Die mosquitto library arbeitet mit C Callbackfunctions. Leider kann ich C++ class member functions dafür nicht verwenden, es sei denn, ich deklariere sie static. Dann kann ich aber nicht mehr in ihr auf die Klasseninhalte zugreifen (manager, controlD).
Mmhh, brauche erst mal etwas Abstand.
Gruß
Joachim
Re: Virtuelle MQTT-JSON Zentrale
Hallo Joachim
Das ist richtig.
Du musst dir eine statische Methode bauen. Dieser übergibst du dann den Pointer auf eine Klasseninstanz (und allfällige weitere Parameter). Darin kannst du dann die eigentlich gewünschte Member-Methode aufrufen. Kommt halt stark darauf an, was die C-Library für eine Signatur erwartet.
Allenfalls kannst du dir in Storage/Sqlite.h/cpp die Methoden Callback* anschauen, da ist auch eine C-Library mit (statischen) Callbacks drin.
Gruss
Teddy
Das ist richtig.
Du musst dir eine statische Methode bauen. Dieser übergibst du dann den Pointer auf eine Klasseninstanz (und allfällige weitere Parameter). Darin kannst du dann die eigentlich gewünschte Member-Methode aufrufen. Kommt halt stark darauf an, was die C-Library für eine Signatur erwartet.
Allenfalls kannst du dir in Storage/Sqlite.h/cpp die Methoden Callback* anschauen, da ist auch eine C-Library mit (statischen) Callbacks drin.
Gruss
Teddy
Re: Virtuelle MQTT-JSON Zentrale
Hallo Teddy,
es kann weitergehen. Es lohnt, sich in die Library einzulesen. (Bin eigentlich kein Programmierer, lerne hier jeden Tag dazu.)
Mit mosq = mosquitto_new(NULL, clean_session, this) kann ich im letzten Argument "userdata lt. Doku" übergeben, wobei das bei mir mit this meine MqttJson Klasseninstanz selber ist.
Die bekomme ich beim Aufruf meiner Callbackfunktion mqtt_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) in obj mitgegeben. Dann noch einmal von void auf meine Klasse casten und ich kann alles nutzen. Top!
Gruß
Joachim
es kann weitergehen. Es lohnt, sich in die Library einzulesen. (Bin eigentlich kein Programmierer, lerne hier jeden Tag dazu.)
Mit mosq = mosquitto_new(NULL, clean_session, this) kann ich im letzten Argument "userdata lt. Doku" übergeben, wobei das bei mir mit this meine MqttJson Klasseninstanz selber ist.
Die bekomme ich beim Aufruf meiner Callbackfunktion mqtt_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) in obj mitgegeben. Dann noch einmal von void auf meine Klasse casten und ich kann alles nutzen. Top!
Gruß
Joachim