# model import serial import os 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 # Neuer Code fuer Mac OS X """ if os.uname()[0] == 'Darwin': try: s = serial.Serial('/dev/tty.usbserial') L.append(s.portstr) s.close() except serial.SerialException: pass for i in range(20): try: s = serial.Serial('/dev/tty.usbserial'+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 import time, platform def zeit(): if platform.system() == 'Windows': return time.clock() else: return time.time() import threading class Model(object): def __init__(self): self.s = serial.Serial(scan()[0]) self.s.setRTS(False) def setPort(self,port): self.s.setPort(port) self.s.setRTS(False) self.s.setDTR(False) def sendBits(self,bitmuster,bitzeit): def sende(bitmuster,bitzeit,s): t0 = zeit() n = 1 while len(bitmuster) > 0: bit = bitmuster[0] bitmuster = bitmuster[1:] if bit == '1': s.setRTS(True) else: s.setRTS(False) while n*bitzeit > zeit() - t0: time.sleep(0.001) n = n + 1 s.setRTS(False) # print(zeit() - t0) # DEBUG self.sendethread = threading.Thread(target = sende, args=(bitmuster,bitzeit,self.s)) self.sendethread.start() def __del__(self): # schliesst sicher die Schnittstelle self.s.close() # view import tkinter # zeiten = [] # DEBUG für Pollzeiten class View(tkinter.Tk): def __init__(self,cbEin,cbAus,cbCTS,cbSetPort,cbHalt,cbSend): tkinter.Tk.__init__(self) # Callbacks self.cbEin = cbEin self.cbAus = cbAus self.cbCTS = cbCTS self.cbSend = cbSend self.cbSetPort = cbSetPort self.protocol("WM_DELETE_WINDOW",cbHalt) # cbHalt wird aufgerufen, wenn das 'X' gedrueckt wird # Timersteuerung self.interval = 1 # Pollingintervall in ms # 'Elektronenstrahl' self.enabled = True self.y = 30 # Position der Linie fuer '0' self.y1 = 20 # 'Hoehe einer 1' in Pixel self.x = 0 # aktuelles x self.xa = 0 # altes x self.t0 = zeit() # Zeit am Anfang einer Zeile self.t = zeit() - self.t0 # Zeit seit Anfang einer Zeile self.ta = zeit() self.cts = self.cbCTS() self.pxs = 200 # Pixel/s, int self.pt = 0.1 # Pegelzeit, float self.pip = self.pxs*self.pt # Pegelintervalllaenge in Pixel self.t1 = zeit() # versuchsweise zur Pollingtime self.dnd = False # Drag&Drop-Flag self.mouse_x = None self.Mouse_y = None # Fenster self.title("Pegel-Transceiver") self.geometry('640x480') # Label self.lP = tkinter.Label(master=self, text='Port:') self.lP.place(x=20, y=20) self.lS = tkinter.Label(master=self, text='px/s:') self.lS.place(x=200, y=20) self.lCTS = tkinter.Label(master=self, text='CTS:') self.lCTS.place(x=507, y=20) self.lPegel = tkinter.Label(master=self, text='Pegel:') self.lPegel.place(x=20, y=55) self.lPegelzeit = tkinter.Label(master=self, text='Pegelzeit:') self.lPegelzeit.place(x=310, y=55) self.ls = tkinter.Label(master=self, text='s') self.ls.place(x=410, y=55) # 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=60,y=14, width=120) # Entry self.eA = tkinter.Entry(master=self) self.eA.insert(0, str(self.pxs)) self.eA.place(x=240, y=20, width=50) self.ePegel = tkinter.Entry(master=self) self.ePegel.insert(0, str('1010000010')) self.ePegel.place(x=60, y=55, width=230) self.ePegelzeit = tkinter.Entry(master=self) self.ePegelzeit.insert(0, str('0.1')) self.ePegelzeit.place(x=370, y=55, width=40) # Buttons self.bStart = tkinter.Button(master=self, text="Start", command=self.start) self.bStart.place(x=300,y=14,width=60) self.bStop = tkinter.Button(master=self, text="Stop", command=self.stop) self.bStop.place(x=370,y=14,width=60) self.bClear = tkinter.Button(master=self, text="Clear", command=self.clear) self.bClear.place(x=440,y=14,width=60) self.bSend = tkinter.Button(master=self, text="Send", command=self.send) self.bSend.place(x=440,y=50,width=60) self.bRTS = tkinter.Button(master=self, text="RTS") self.bRTS.bind('',self.cbEin) self.bRTS.bind('',self.cbAus) self.bRTS.place(x=570,y=14,width=60) # Canvases self.cLed = tkinter.Canvas(master=self,width=22,height=22) self.cLed.place(x=542,y=18) self.c = tkinter.Canvas(master=self,width=640,height=450) self.c.place(x=0,y=80) # Lineal self.Lineal() # LED self.item = self.cLed.create_oval(1,1,20,20,fill='#550000',tags=('LED')) # Timer starten self.after(0,self.poll) def Lineal(self): lx = 10 ly = 380 d = 3 self.c.delete('Lineal') # print(self.pip) # DEBUG self.c.create_line(lx,ly,lx+self.pip*20,ly,fill='#ff0000',tags=('Lineal')) for i in range(1,20): self.c.create_line(lx+i*self.pip,ly-d,lx+i*self.pip,ly+d,fill='#ff0000',tags=('Lineal')) self.c.tag_bind('Lineal','',self.mouse_enter) self.c.tag_bind('Lineal','',self.mouse_leave) self.c.tag_bind('Lineal','',self.mouse_button1) self.c.tag_bind('Lineal','',self.mouse_release1) self.c.tag_bind('Lineal','',self.mouse_move) def mouse_enter(self,e): self.cursor_alt = self['cursor'] self['cursor'] = 'hand1' def mouse_leave(self,e): self['cursor'] = self.cursor_alt def mouse_button1(self,e): self.dnd = True self.mouse_x = e.x self.mouse_y = e.y # print(self.mouse_x,self.mouse_y) # DEBUG def mouse_release1(self,e): self.dnd = False def mouse_move(self,e): if self.dnd: xoff = e.x - self.mouse_x yoff = e.y - self.mouse_y self.c.move('Lineal',xoff,yoff) self.mouse_x = e.x self.mouse_y = e.y def poll(self): # Anfang DEBUG für Pollzeiten """ t = zeit() tp = t-self.t1 self.t1 = t zeiten.append(tp) """ # Ende DEBUG für Pollzeiten if self.enabled: self.t = zeit() - self.t0 self.x = self.t*self.pxs if self.x > 640: # todo: width abfragen self.t = 0 self.t0 = zeit() self.x = 0 self.xa = 0 self.y = self.y + self.y1 + 10 # Bearbeiten von Led und Canvas aktCTS = self.cbCTS() if aktCTS and not self.cts: # Zustand 0 --> 1 self.cLed.itemconfig('LED',fill='#ff0000') if self.enabled: self.c.create_line(self.xa,self.y+1,self.xa,self.y - self.y1) # +1 ?? self.y = self.y - self.y1 self.cts = True elif not aktCTS and self.cts: # Zustand 1 --> 0 self.cLed.itemconfig('LED',fill='#550000') if self.enabled: self.c.create_line(self.xa,self.y,self.xa,self.y + self.y1) self.y = self.y + self.y1 self.cts = False else: # Zustand unveraendert if (self.x - self.xa > 0.5) and self.enabled: self.c.create_line(self.xa,self.y,self.x,self.y) self.xa = self.x # Bearbeiten der Eingabe zu px/s eingabe = self.eA.get() try: zahl = int(eingabe) # print(zahl) # DEBUG if (zahl > 0) and (zahl != self.pxs): self.pxs = zahl self.t0 = zeit() - self.x/self.pxs self.t = self.x/self.pxs # self.Lineal() elif zahl <= 0: self.eA.delete(0,tkinter.END) self.eA.insert(0,'0') except: self.eA.delete(0,tkinter.END) self.eA.insert(0,'0') # Bearbeiten der Eingabe zur Pegelzeit eingabe = self.ePegelzeit.get() try: zahl = float(eingabe) # print(zahl) # DEBUG if (zahl > 0) and (zahl != self.pt): self.pt = zahl # self.Lineal() except: pass # Pegelintervalllaenge in Pixel self.pip = round(self.pxs*self.pt) # rekursiver Aufruf self.after(self.interval,self.poll) def start(self): self.enabled = True self.t0 = zeit() - self.x/self.pxs self.t = self.x/self.pxs def stop(self): self.enabled = False def send(self): if self.cbSend != None: self.cbSend(self.ePegel.get(),float(self.ePegelzeit.get())) def clear(self): self.c = tkinter.Canvas(master=self,width=640,height=450) self.c.place(x=0,y=80) self.y = 30 # Position der Linie fuer '0' self.x = 0 # aktuelles x self.xa = 0 # altes x self.t0 = zeit() # Zeit am Anfang einer Zeile self.t = zeit() - self.t0 # Zeit seit Anfang einer Zeile self.ta = zeit() self.cts = self.cbCTS() self.Lineal() def cbOption(self, wert): # print(wert) # DEBUG self.cbSetPort(wert) # controller class Controller(object): def __init__(self): self.model = Model() self.view = View(self.schalteEin,self.schalteAus,self.model.s.getCTS, self.model.setPort,self.Halt, self.model.sendBits) self.view.mainloop() def schalteEin(self,event): self.model.s.setRTS(True) def schalteAus(self,event): self.model.s.setRTS(False) def setPort(self,port): self.model.s.setPort(port) def Halt(self): # Aufraeumarbeiten self.model.s.close() # Schnittstelle schliessen self.view.quit() # mainloop beenden self.view.destroy() # Fenster beseitigen # Hauptprogramm c = Controller()