GPG Geschrieben 18. Januar 2019 Geschrieben 18. Januar 2019 (bearbeitet) Hallo Eisenbahner, nachdem ich so manch tolle Anleitung hier erhalten habe, möchte ich mich zum Dank revanchieren. Durch meine Beschäftigung mit dem Raspbery und elektronischen (Eisenbahn-)Basteleien lernte ich die Programmiersprache Python kennen und bin begeistert. Leider habe ich weder im InterNet noch hier im Forum irgendwelche direkten Tips für die Verbindung Python/3D-Studio gefunden. So dauerte das Einarbeiten entsprechend lang. Teil 1 Senden von Kommandos an das 3D-Studio am Beispiel Fahren einer Lok (kleinstmögliches Programm) 1. Aus dem InterNet wird Python heruntergeladen und installiert. Die Voreinstellungen können übernommen werden. 2. Zuerst muss das 3D-Studio mit einem Gleisplan und einer Lok gestartet werden. Die Lok erhält den Namen lok (klein geschrieben, willkürlich von mir gewählt). 3. Als Kommando-Port für Befehle an das 3D-Studio wird der voreingestellte Port 31385 beibehalten. Der Ereignis-Port kann ebenfalls beibehalten werden - er wird hier jedoch nicht benötigt. 4. Zur Erinnerung: Für jeden an das 3D-Studio gesendete Befehl gibt es je nach Befehl stets mindestens eine 1 (Kommunikation gelungen) oder eine 0 (Kommunikation misslungen) zurück. 5. Programm (Nummerierung am Zeilenanfang weglassen): import socket mySocket = socket.socket() host = "127.0.0.1" port = 31285 mySocket.connect((host,port)) mySocket.send(bytes("371;lok;1;8\n","utf-8")) datenbytes = mySocket.recv(24) print("Antwort als Bytes: ", datenbytes) Erklärung Das Paket socket (für die Datenverbindung) wird geladen.Es ist in der Sprache Python automatisch vorhanden, aber nicht automatisch in den eigenen Programmen eingebunden. Eine Instanz der Klasse socket wird erstellt. Die Benennung ist frei wählbar. Ich lass die Namen meiner Instanzen meist mit my beginnen ; so hier: mySocket. Adresse des eigenen Rechners (die heißen in der Regel immer so oder localhost). Der vom 3D-Studio voreingestellte Port. Verbindungsaufbau meines Programms mit dem 3D-Studio Der Befehl 371;lok;1;8 (die lok genannte Lokomotive soll vorwärts fahren mit Tempo 80. (kein Tippfehler! die hier eingegebene Zahl multipliziert das 3D-Studio automatisch mit 10). Da das 3D-Studio den Befehl in Byte-Form benötigt, muss der als String geschriebene Befehl umgewandelt werden. Das geschieht mit der Methode bytes(). Außerdem muss auch der notwendige Zeilenumbruch mit \n explizit dargestellt werden. Die bytes()-Methode verlangt überdies noch das Bestimmen einer Kodierart (hier: utf-8). Die Lok muss sich jetzt in Bewegung setzen. Die Antwort des 3D-Studios wird in die Variable datenbytes geschrieben. Die Zahl 24 gibt die geschätzte mögliche Größe der empfangenen Mitteilung an. Dort könnte auch eine größere oder kleinere Zahl stehen (probieren). Endlich wird die Antwort gedruckt (kann entfallen). Man kann die Antwort noch in einen String umwandeln und dann drucken: datenstring = str(datenbytes,"utf-8") print("Antword als String: ", datenstring) Anmerkung: Sollten 2 PC in einem Netzwerk miteinander verbunden sein, so sollte Python auf dem einen PC und das 3D-Studio auf dem anderen laufen. Dann muss lediglich die obige Adresse 127.0.0.1 ausgetauscht werden gegen die des PCs, auf dem das 3D-Studio läuft. Die Adresse erhält man unter anderem, wenn man in der Verwaltungssoftware einer Fritz.Box unter Heimnetzwerk nachschaut, im Internet nach "eigene IP-Adresse" sucht oder in die Systemsteuerung von WINDOWS guckt. Teil 2: Das Empfangen der Ereignismitteilungen vom 3D-Studio Lesen der Ereignisse Hier wieder das kleinstmögliche Programm (ohne Zeilennummern eingeben, Einrückungen beachten)) import socket host = "127.0.0.1" port2 = 31286 mySocket = socket.socket() mySocket.connect((host,port2)) while (True): antwort = mySocket.recv(1024) print(antwort) Erklärung: Importieren des Moduls socket für die Datenverbindung Adresse des eigenen Rechners. Alternativ: host="localhost" Vom 3D-Studio voreingestellter Port für die Ereignisübertragung Instanz der Klasse socket wird erstellt mit Voreinstellungen Verbindungsaufbau meines Programms mit dem 3D-Studio. Im Gegensatz zum Senden wird jetzt der voreingestellte Port für die Ereignisübertragung gewählt! Beginn einer Endlosschleife Die Mitteilungen des 3D-Studios in Form von Bytes werden in die Variable antwort geschrieben. Drucken der Variablen in Byte-Form Anmerkung: Sollen die beiden Programme zusammengefasst werden, so ist zu beachten, dass wegen der verschiedenen Ports ein zweites socket-Objekt erstellt werden muss. import socket mySocket = socket.socket() host = "127.0.0.1" port = 31285 mySocket.connect((host,port)) mySocket.send(bytes("371;lok;1;8\n","utf-8")) datenbytes = mySocket.recv(24) print("Antwort als Bytes: ", datenbytes) port2 = 31286 mySocket2 = socket.socket() mySocket2.connect((host,port2)) while (True): antwort = mySocket2.recv(1024) print(antwort) Grüße GPG Bearbeitet 18. März 2019 von GPG Überarbeitung des Artikels
GPG Geschrieben 26. Januar 2019 Autor Geschrieben 26. Januar 2019 (bearbeitet) Steuerschnittstelle programmieren mit Python3 und Tkinter Teil 3: Simples Fahrpult Beispiel für das Übertragen von Kommandos an das 3D-Studio in einem Fenster Zeilen ab dem #-Zeichen sind Kommentare und für den Programmablauf nicht relevant. Einrückungen sind in Python wichtig! ######################################### #### Programm: Fahrpult.pyw #### Einfaches Fahrpult #### 3 Geschwindigkeiten pro Richtung #### und Halt-Buttom ######################################### from tkinter import * # Modul tkinter (zuständig für die Fenstergestaltung) wird importiert import socket # Modul socket (zuständig für die Datenübertragung) wird importiert def fahren(v): # das Unterprogramm fahren mit einer Werteübergabe beim Aufruf wird definiert v_string = str(v) # der übergebene Wert wird in einen String verwandelt adress_string = "371;lok;1;" + v_string + "\n" # das Kommando für das Fahren der Lok wird zu einem String zusammengebaut adress_bytes = (bytes(adress_string ,"utf-8")) # Umwandlung des Strings in Bytes c.send(adress_bytes) # das Byte wird gesendet print(v) # die folgenden print-Anweisungen dienen nur der Kontrolle im Python-Shell print(v_string) print(adress_string) print(adress_bytes) host = "127.0.0.1" # Adresse des PCs, auf dem das 3D-Studio läuft port = 31285 # vom 3D-Studio voreingestellter Port für den Datenempfang c=socket.socket() # mein Objekt für die Datenübertragung wird erstellt (in den Programmen oben mySocket genannt) c.connect((host,port)) # Verbindung wird hergestellt myfenster = Tk() # Das Objekt eines Window-Fensters wird erstellt, d.h. ein reales Fenster wird erstellt myfenster.title("Fahrpult") # Titel des Fensters mybutton_fahren1 = Button (master=myfenster, text=" <<< ", command=lambda:fahren(-20)) # Die Buttons fürs Fahren werden erstellt, zuerst deren Namen mybutton_fahren2 = Button (master=myfenster, text=" << ", command=lambda:fahren(-10)) # dann werden deren Platzierungen im Fenster festgelegt mybutton_fahren3 = Button (master=myfenster, text=" < ", command=lambda:fahren( -2)) # mit Text wird die Aufschrift festgelegt mybutton_halten4 = Button (master=myfenster, text="HALT", command=lambda:fahren( 0)) # command legt fest, welches Unterprogramm beim mybutton_fahren5 = Button (master=myfenster, text=" > ", command=lambda:fahren( 2)) # Anklicken gestartet wird mybutton_fahren6 = Button (master=myfenster, text=" >> ", command=lambda:fahren( 10)) # lambda ermöglicht die Mitgabe eines Wertes mybutton_fahren7 = Button (master=myfenster, text=" >>> ", command=lambda:fahren( 20)) # der Wert steht in Klammen mybutton_fahren1.pack(side ='left', padx='5',pady='5') # die Methode pack() ordnet die Platzierung der Buttons im Fenster mybutton_fahren2.pack(side ='left', padx='5') # side= 'left bedeutet: Buttons nebeneinander anordnen mybutton_fahren3.pack(side ='left', padx='5') # padx und pady legt den Abstand der Buttons vom Rand und von einander in x- und y-Richtung fest mybutton_halten4.pack(side ='left', padx='5') mybutton_fahren5.pack(side ='left', padx='5') mybutton_fahren6.pack(side ='left', padx='5') mybutton_fahren7.pack(side ='left', padx='5') myfenster.mainloop() # mainloop organisiert das Funktionieren des Fensters Bearbeitet 18. März 2019 von GPG Überarbeitung des Artikels
Andy Geschrieben 26. Januar 2019 Geschrieben 26. Januar 2019 Hallo GPG, hochinteressant, dass das mit so wenig Befehlen möglich ist. Was muß jetzt noch getan werden, dass das in zwei parallelen Threads läuft? Gruß Andy
GPG Geschrieben 3. Februar 2019 Autor Geschrieben 3. Februar 2019 (bearbeitet) Programme (z.B. Fahrpult) im Vordergrund Das einfache, problemlose und kostenlos im InterNet erhältliche Utility AOT-Setter https://www.entwickler-ecke.de/topic_AOTSetter++Invertiert+Eigenschaft+AlwaysOnTop_68302,0.html eignet sich hervorragend, um kleine Windows-Fenster über Programme wie z.B. dem 3D-Studio in den Vordergrund zu legen. Gruß GPG Bearbeitet 18. März 2019 von GPG
Empfohlene Beiträge
Erstelle ein Benutzerkonto oder melde dich an, um zu kommentieren
Du musst ein Benutzerkonto besitzen, um einen Kommentar verfassen zu können
Benutzerkonto erstellen
Neues Benutzerkonto für unsere Community erstellen.
Neues Benutzerkonto erstellenAnmelden
Du hast bereits ein Benutzerkonto? Melde dich hier an.
Jetzt anmelden