# model import serial def scan(): """ gibt eine Liste von Strings der Namen der verfuegbaren Ports zurueck """ L = [] for i in range(10): try: s = serial.Serial('/dev/ttyS'+str(i)) L.append(s.portstr) s.close() except serial.SerialException: pass for i in range(10): try: s = serial.Serial('/dev/ttyUSB'+str(i)) L.append(s.portstr) s.close() except serial.SerialException: pass for i in range(10): try: s = serial.Serial('COM'+str(i)) L.append(s.portstr) s.close() except serial.SerialException: pass for i in range(10): try: s = serial.Serial(i) L.append(i) s.close() except serial.SerialException: pass return L def ByteToBin(b): """ gibt einen String der Laenge 8 zurueck, der das Byte b darstellt, Beispiel: 65 --> '01000001' """ return bin(b)[2:].zfill(8) import time def sendbyte(b,bitzeit,setLeitung): """ ein Byte b wird im miniRS232-Protokoll mit der Bitzeit bitzeit in s gesendet, dabei wird zum Setzen der Leitung die Funktion SetLeitung verwendet, SetLeitung hat einen Parameter vom Typ bool """ # Bitmuster erzeugen bm = ByteToBin(b) # Leitung zunaechst auf Null setLeitung(0) time.sleep(0.005) # Startbit setLeitung(1) time.sleep(bitzeit) # Datenbits for i in range(8): setLeitung(int(bm[i])) time.sleep(bitzeit) # Stoppbit setLeitung(0) time.sleep(bitzeit) # DEBUG, Achtung: verlaengert Stoppbit print('gesendet:',chr(b),format(b,'3d'),bm) class Model(object): def __init__(self): self.s = serial.Serial(scan()[0]) self.s.setRTS(False) def send(self,nachricht,bitzeit): for b in nachricht: sendbyte(b,bitzeit,self.s.setRTS) def __del__(self): # schliesst sicher die Schnittstelle self.s.close() def codiert(s): """ wandelt einen Python-String in eine Byte-Folge um, dabei wird ein Python-Zeichen ch zu dem Byte ord(ch), falls ord(ch) > 255 ist, wird auf 255 zurueckgesetzt """ def ordx(ch): b = ord(ch) if b > 255: return 255 else: return b return bytes([ordx(ch) for ch in s]) # view import tkinter import time class View(tkinter.Tk): def __init__(self,cbSetPort,cbSend,cbHalt): tkinter.Tk.__init__(self) # Callbacks self.cbSetPort = cbSetPort self.cbSend = cbSend self.protocol("WM_DELETE_WINDOW",cbHalt) # cbHalt wird aufgerufen, wenn das 'X' gedrückt wird # Fenster self.title("Sender 1") self.geometry('325x200+600+200') # Label self.lP = tkinter.Label(master=self, text='Port:') self.lP.place(x=20, y=20) self.lB = tkinter.Label(master=self, text='Bitzeit:') self.lB.place(x=210, y=20) self.lS = tkinter.Label(master=self, text='s') self.lS.place(x=295, y=20) # Optionmenu self.vS = tkinter.StringVar(master=self) self.scan = scan() self.vS.set(self.scan[0]) self.oS = tkinter.OptionMenu(self,self.vS,*self.scan, command=self.cbOption) self.oS.place(x=55,y=14, width=100) # Entry self.eA = tkinter.Entry(master=self) self.eA.insert(0, '0.05') self.eA.place(x=255, y=20, width=40) self.eA.bind('',self.cbEntry) # Text self.tA = tkinter.Text(self,width=40,height=5) # width und height in Zeichen self.tA.delete('1.0',tkinter.END) self.tA.insert(tkinter.END,"Wie geht's denn so?") self.tA.place(x=20,y=60) # Buttons self.bSend = tkinter.Button(master=self, text="sende", command=self.cbSendintern) self.bSend.place(x=20,y=150) def cbOption(self, wert): # print(wert) # DEBUG self.cbSetPort(wert) def cbEntry(self,event): self.focus_force() print('Return im Entry-Widget, String:',self.eA.get()) def cbSendintern(self): # Bitzeit ermitteln bitzeit = float(self.eA.get()) # todo Fehlerabfangen # String zu nachricht codieren nachricht = codiert(self.tA.get('1.0',tkinter.END)[:-1]) print('zu senden:',nachricht) # DEBUG # Callback aufrufen self.cbSend(nachricht,bitzeit) # controller class Controller(object): def __init__(self): self.model = Model() self.view = View(self.setPort,self.Send,self.Halt) self.view.mainloop() def setPort(self,port): self.model.s.setPort(port) self.model.s.setRTS(0) def Send(self,nachricht,bitzeit): self.model.send(nachricht,bitzeit) def Halt(self): # Aufraeumarbeiten self.model.s.close() # Schnittstelle schliessen self.view.quit() # mainloop beenden self.view.destroy() # Fenster beseitigen # Hauptprogramm c = Controller()