GPG
-
Gesamte Inhalte
4 -
Benutzer seit
-
Letzter Besuch
Beiträge erstellt von GPG
-
-
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 importiertdef 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 hergestelltmyfenster = Tk() # Das Objekt eines Window-Fensters wird erstellt, d.h. ein reales Fenster wird erstellt
myfenster.title("Fahrpult") # Titel des Fenstersmybutton_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 Klammenmybutton_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
-
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
-
Hallo Modeller,
wo finde ich bitte die Einstellung, um Weichen freizuschalten bzw. die Freischaltung aufzuheben?
Vielen Dank
Steuerschnittstelle programmieren mit Python
in Anleitungen und Tutorials
Geschrieben · Bearbeitet von GPG
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