import tkinter as tk from tkinter.constants import W, X import serial.tools.list_ports import functools import tkinter.ttk as ttk from configparser import ConfigParser import os import labrobot as lrb import threading # commands command = [] infoline = [] # serial ports ports = serial.tools.list_ports.comports() serialObj = serial.Serial() def serial_ports(): return serial.tools.list_ports.comports() def on_select(event=None): serialObj.port = cb.get().split(' ')[0] serialObj.baudrate = 115000 serialObj.open() root = tk.Tk() infobar = tk.StringVar() #configue root root.title("Jfs Labrobot") root.geometry('800x500+300+300') root.columnconfigure(0,weight=1) root.rowconfigure(0,weight=1) #root.config(bg='#b7f731') notebook = ttk.Notebook(root) notebook.grid(sticky='news',padx=5,pady=5) notebook.enable_traversalrightmainframe = ttk.Frame(notebook) mainframe = ttk.Frame(notebook) #mainframe.rowconfigure(0,weight=1) mainframe.columnconfigure(0,weight=1) notebook.add(mainframe,text='main',underline=0) leftframe = ttk.Frame(mainframe) leftframe.columnconfigure(0,weight=1) leftframe.rowconfigure(1,weight=1) leftframe.grid(column=0,row=0,sticky='news') rightframe = ttk.Frame(mainframe) rightframe.columnconfigure(0,weight=1) rightframe.rowconfigure(0,weight=1) rightframe.grid(column=1,row=0,sticky='new') uprightframe =ttk.LabelFrame(rightframe,text='Basic') uprightframe.grid(column=0,row=0,sticky='ns') downrightframe =ttk.LabelFrame(rightframe,text='More to select') downrightframe.grid(column=0,row=1,sticky='new',pady=5) cb =ttk.Combobox(leftframe,values=serial_ports()) cb.grid(row=0,column=0,stick="nwe") cb.bind('<>',on_select) info = ttk.Label(textvariable=infobar) info.grid(row=99,column=0,sticky='ew',padx=5) infobar.set('Info Bar') scb =tk.Scrollbar(leftframe) scb.grid(row=1,column=1,sticky='ns') #txt = tk.Text(leftframe,height=30,width=50) txt = tk.Text(leftframe) txt.grid(row=1,column=0,sticky='ewns') scb.config(command=txt.yview) txt.config(yscrollcommand=scb.set) txt.tag_configure('small',font=('Verdana',8),foreground='black') b1 = ttk.Button(uprightframe,text='Home All',width=12) b1.grid(row=0,column=0,sticky='nw') b2 = ttk.Button(uprightframe,text='Home X',width=12) b2.grid(row=0,column=1,sticky='ne') b3 = ttk.Button(uprightframe,text='Home Y',width=12) b3.grid(row=1,column=0,sticky='nw') b4 = ttk.Button(uprightframe,text='Home Z',width=12) b4.grid(row=1,column=1,sticky='ne') b6 = ttk.Button(uprightframe,text='Home P',width=12) b6.grid(row=2,column=0,sticky='nw') b7 = ttk.Button(uprightframe,text='Get Position',width=12) b7.grid(row=2,column=1,sticky='ne') l1 = ttk.Label(uprightframe,text="Enter G-Code").grid(row=3,column=0) e1 = ttk.Entry(uprightframe) e1.grid(row=3,column=1) b5 = ttk.Button(uprightframe,text='Send Code') b5.grid(row=4,column=1,sticky="ne") b8 = ttk.Button(downrightframe,text='Next Tip') b8.grid(row=0,column=0,sticky='ne') b9 = ttk.Button(downrightframe,text='Up') b9.grid(row=0,column=1,sticky='ne') b10 = ttk.Button(downrightframe,text='Down') b10.grid(row=0,column=2,sticky='ne') b11 = ttk.Button(downrightframe,text='Top') b11.grid(row=1,column=0,sticky='ne') b13 = ttk.Button(downrightframe,text='Load') b13.grid(row=1,column=1,sticky='ne') b12 = ttk.Button(downrightframe,text='Dispense') b12.grid(row=1,column=2,sticky='ne') b14 = ttk.Button(downrightframe,text='Take Chem') b14.grid(row=2,column=0,sticky='ne') b15 = ttk.Button(downrightframe,text='Next Vessel') b15.grid(row=2,column=1,sticky='ne') b16 = ttk.Button(downrightframe,text='Load Next') b16.grid(row=2,column=2,sticky='ne') ttk.Label(downrightframe,text='Start Vessel').grid(row=3,column=0,sticky='e') e2 =ttk.Entry(downrightframe,width=5) e2.grid(row=3,column=1,sticky='w') ttk.Label(downrightframe,text='Last Vessel').grid(row=4,column=0,sticky='e') e3 =ttk.Entry(downrightframe,width=5) e3.grid(row=4,column=1,sticky='w') b17 = ttk.Button(downrightframe,text='Load All') b17.grid(row=4,column=2,sticky='e') b18 = ttk.Button(downrightframe,text='Clear Tip') b18.grid(row=3,column=2,sticky='e') ###################### Parts ## init Labrobot startVessel = tk.IntVar() lastVessel = tk.IntVar() ## Top Block xoffset = tk.DoubleVar() yoffset = tk.DoubleVar() rows = tk.IntVar() cols = tk.IntVar() xspace = tk.DoubleVar() yspace = tk.DoubleVar() zlevel = tk.DoubleVar() akttip = tk.IntVar() ## Tip tipvol = tk.IntVar() tipup = tk.DoubleVar() tiphub = tk.DoubleVar() tipspeed = tk.IntVar() aktvol = tk.DoubleVar() ## Chemicals chemX = tk.DoubleVar() chemY = tk.DoubleVar() chemVol = tk.DoubleVar() chemZ = tk.DoubleVar() deltaz = tk.DoubleVar() tauch = tk.DoubleVar() reaPart = tk.DoubleVar() ## ReactionSpace rxoffset = tk.DoubleVar() ryoffset = tk.DoubleVar() rrows = tk.IntVar() rcols = tk.IntVar() rxspace = tk.DoubleVar() ryspace = tk.DoubleVar() rtipvol = tk.IntVar() rzlevel = tk.DoubleVar() rakt = tk.IntVar() def conf_read(): config = ConfigParser() config.read(os.path.join(os.path.dirname(__file__), "config.ini"),) xoffset.set(float(config.get('tipblock','xoffset',fallback=0))) yoffset.set(float(config.get('tipblock','yoffset',fallback=0))) rows.set(int(config.get('tipblock','rows',fallback=0))) cols.set(int(config.get('tipblock','cols',fallback=0))) xspace.set(float(config.get('tipblock','xspace',fallback=0))) yspace.set(float(config.get('tipblock','yspace',fallback=0))) tipvol.set(int(config.get('tipblock','tipvol',fallback=0))) zlevel.set(float(config.get('tipblock','zlevel',fallback=0))) tipup.set(float(config.get('tipblock','tipup',fallback=0))) tiphub.set(float(config.get('tipblock','tiphub',fallback=0))) tipspeed.set(int(config.get('tipblock','tipspeed',fallback=0))) chemX.set(float(config.get('chemblock','chemx',fallback=0))) chemY.set(float(config.get('chemblock','chemy',fallback=0))) chemVol.set(float(config.get('chemblock','chemvol',fallback=0))) chemZ.set(float(config.get('chemblock','chemz',fallback=0))) deltaz.set(float(config.get('chemblock','deltaz',fallback=0))) tauch.set(float(config.get('chemblock','tauch',fallback=0))) reaPart.set(float(config.get('chemblock','reapart',fallback=0))) rxoffset.set(float(config.get('reacblock','rxoffset',fallback=0))) ryoffset.set(float(config.get('reacblock','ryoffset',fallback=0))) rrows.set(int(config.get('reacblock','rrows',fallback=0))) rcols.set(int(config.get('reacblock','rcols',fallback=0))) rxspace.set(float(config.get('reacblock','rxspace',fallback=0))) ryspace.set(float(config.get('reacblock','ryspace',fallback=0))) rzlevel.set(float(config.get('reacblock','rzlevel',fallback=0))) def conf_write(): config = ConfigParser() config.read(os.path.join(os.path.dirname(__file__), "config.ini"),) config.set('tipblock','xoffset',str(xoffset.get())) config.set('tipblock','yoffset',str(yoffset.get())) config.set('tipblock','rows',str(rows.get())) config.set('tipblock','cols',str(cols.get())) config.set('tipblock','xspace',str(xspace.get())) config.set('tipblock','yspace',str(yspace.get())) config.set('tipblock','tipvol',str(tipvol.get())) config.set('tipblock','zlevel',str(zlevel.get())) config.set('tipblock','tipup',str(tipup.get())) config.set('tipblock','tiphub',str(tiphub.get())) config.set('tipblock','tipspeed',str(tipspeed.get())) config.set('chemblock','chemx',str(chemX.get())) config.set('chemblock','chemy',str(chemY.get())) config.set('chemblock','chemvol',str(chemVol.get())) config.set('chemblock','chemz',str(chemZ.get())) config.set('chemblock','deltaz',str(deltaz.get())) config.set('chemblock','tauch',str(tauch.get())) config.set('chemblock','reapart',str(reaPart.get())) config.set('reacblock','rxoffset',str(rxoffset.get())) config.set('reacblock','ryoffset',str(ryoffset.get())) config.set('reacblock','rrows',str(rrows.get())) config.set('reacblock','rcols',str(rcols.get())) config.set('reacblock','rxspace',str(rxspace.get())) config.set('reacblock','ryspace',str(ryspace.get())) config.set('reacblock','rzlevel',str(rzlevel.get())) with open(os.path.join(os.path.dirname(__file__), "config.ini"),'w') as f: config.write(f) conf_read() lpb = lrb.LabPipBlock(xoffset.get(),yoffset.get(),zlevel.get(),rows.get(),cols.get(),xspace.get(),yspace.get()) pip = lrb.LabPip(vol=tipvol.get(),top=tipup.get(),hub=tiphub.get(),fe=tipspeed.get()) chem = lrb.ChemLoc(chemX.get(),chemY.get(),chemZ.get(),chemVol.get(),deltaz.get(),tauch.get(),chemVol.get()) react = lrb.LabReactBlock(rxoffset.get(),ryoffset.get(),rzlevel.get(),rrows.get(),rcols.get(),rxspace.get(),ryspace.get()) partframe = ttk.Frame(notebook) #partframe.rowconfigure(0,weight=1) partframe.columnconfigure(0,weight=1) notebook.add(partframe,text='parts',underline=0) pipblockframe =ttk.LabelFrame(partframe,text='Tip Block') pipblockframe.grid(column=0,row=0,sticky='wns',padx=5,pady=5) pl1 = ttk.Label(pipblockframe,text='X offset').grid(column=0,row=0,padx=5) pe1 = ttk.Entry(pipblockframe,textvariable=xoffset) pe1.grid(column=1,row=0,sticky='e') pl2 = ttk.Label(pipblockframe,text='rows').grid(column=0,row=2,padx=5) pe2 = ttk.Entry(pipblockframe,textvariable=rows) pe2.grid(column=1,row=2,sticky='e') pl3 = ttk.Label(pipblockframe,text='columns').grid(column=0,row=3,padx=5) pe3 = ttk.Entry(pipblockframe,textvariable=cols) pe3.grid(column=1,row=3,sticky='e') pl4 = ttk.Label(pipblockframe,text='x space').grid(column=0,row=4,padx=5) pe4 = ttk.Entry(pipblockframe,textvariable=xspace) pe4.grid(column=1,row=4,sticky='e') pl5 = ttk.Label(pipblockframe,text='y space').grid(column=0,row=5,padx=5) pe5 = ttk.Entry(pipblockframe,textvariable=yspace) pe5.grid(column=1,row=5,sticky='e') pl6 = ttk.Label(pipblockframe,text='Y offset').grid(column=0,row=1,padx=5) pe6 = ttk.Entry(pipblockframe,textvariable=yoffset) pe6.grid(column=1,row=1,sticky='e') pl8 = ttk.Label(pipblockframe,text='Z uptake').grid(column=0,row=6,padx=5) pe8 = ttk.Entry(pipblockframe,textvariable=zlevel) pe8.grid(column=1,row=6,sticky='e') ttk.Separator(pipblockframe, orient=tk.HORIZONTAL).grid(row=7,sticky='ew') pl7 = ttk.Label(pipblockframe,text='Tip Volume').grid(column=0,row=8,padx=5) pe7 = ttk.Entry(pipblockframe,textvariable=tipvol) pe7.grid(column=1,row=8,sticky='e') pl9 = ttk.Label(pipblockframe,text='Tip Top').grid(column=0,row=9,padx=5) pe9 = ttk.Entry(pipblockframe,textvariable=tipup) pe9.grid(column=1,row=9,sticky='e') pl10 = ttk.Label(pipblockframe,text='Tip Hub').grid(column=0,row=10,padx=5) pe10 = ttk.Entry(pipblockframe,textvariable=tiphub) pe10.grid(column=1,row=10,sticky='e') pl11 = ttk.Label(pipblockframe,text='Tip Speed').grid(column=0,row=11,padx=5) pe11 = ttk.Entry(pipblockframe,textvariable=tipspeed) pe11.grid(column=1,row=11,sticky='e') ttk.Separator(pipblockframe, orient=tk.HORIZONTAL).grid(row=80,sticky='ew') pl12 = ttk.Label(pipblockframe,text='Akt Tip').grid(column=0,row=81,padx=5) pe12 = ttk.Entry(pipblockframe,textvariable=akttip) pe12.grid(column=1,row=81,sticky='e') pl13 = ttk.Label(pipblockframe,text='Akt Volumne').grid(column=0,row=82,padx=5) pe13 = ttk.Entry(pipblockframe,textvariable=aktvol) pe13.grid(column=1,row=82,sticky='e') ttk.Separator(pipblockframe, orient=tk.HORIZONTAL).grid(row=98,sticky='ew') pb1 = ttk.Button(pipblockframe,text='Set') pb1.grid(column=0,row=99,sticky='e') pb2 = ttk.Button(pipblockframe,text='Save') pb2.grid(column=1,row=99,sticky='w') chemframe =ttk.LabelFrame(partframe,text='Chemicals') chemframe.grid(column=1,row=0,sticky='wns',padx=5,pady=5) cl1 = ttk.Label(chemframe,text='X pos').grid(column=0,row=0,padx=5) ce1 = ttk.Entry(chemframe,textvariable=chemX) ce1.grid(column=1,row=0,sticky='e') cl2 = ttk.Label(chemframe,text='Y pos').grid(column=0,row=1,padx=5) ce2 = ttk.Entry(chemframe,textvariable=chemY) ce2.grid(column=1,row=1,sticky='e') cl3 = ttk.Label(chemframe,text='Z Surface').grid(column=0,row=2,padx=5) ce3 = ttk.Entry(chemframe,textvariable=chemZ) ce3.grid(column=1,row=2,sticky='e') cl4 = ttk.Label(chemframe,text='Volume').grid(column=0,row=3,padx=5) ce4 = ttk.Entry(chemframe,textvariable=chemVol) ce4.grid(column=1,row=3,sticky='e') cl5 = ttk.Label(chemframe,text='DeltaZ/ml').grid(column=0,row=4,padx=5) ce5 = ttk.Entry(chemframe,textvariable=deltaz) ce5.grid(column=1,row=4,sticky='e') cl6 = ttk.Label(chemframe,text='React Vol').grid(column=0,row=5,padx=5) ce6 = ttk.Entry(chemframe,textvariable=reaPart) ce6.grid(column=1,row=5,sticky='e') reactframe =ttk.LabelFrame(partframe,text='Reaction Vessels') reactframe.grid(column=2,row=0,sticky='wns',padx=5,pady=5) rl1 = ttk.Label(reactframe,text='X offset').grid(column=0,row=0,padx=5) re1 = ttk.Entry(reactframe,textvariable=rxoffset) re1.grid(column=1,row=0,sticky='e') rl2 = ttk.Label(reactframe,text='rows').grid(column=0,row=2,padx=5) re2 = ttk.Entry(reactframe,textvariable=rrows) re2.grid(column=1,row=2,sticky='e') rl3 = ttk.Label(reactframe,text='columns').grid(column=0,row=3,padx=5) re3 = ttk.Entry(reactframe,textvariable=rcols) re3.grid(column=1,row=3,sticky='e') rl4 = ttk.Label(reactframe,text='x space').grid(column=0,row=4,padx=5) re4 = ttk.Entry(reactframe,textvariable=rxspace) re4.grid(column=1,row=4,sticky='e') rl5 = ttk.Label(reactframe,text='y space').grid(column=0,row=5,padx=5) re5 = ttk.Entry(reactframe,textvariable=ryspace) re5.grid(column=1,row=5,sticky='e') rl6 = ttk.Label(reactframe,text='Y offset').grid(column=0,row=1,padx=5) re6 = ttk.Entry(reactframe,textvariable=ryoffset) re6.grid(column=1,row=1,sticky='e') rl7 = ttk.Label(reactframe,text='Z level').grid(column=0,row=6,padx=5) re7 = ttk.Entry(reactframe,textvariable=rzlevel) re7.grid(column=1,row=6,sticky='e') ttk.Separator(reactframe, orient=tk.HORIZONTAL).grid(row=80,sticky='ew') rl8 = ttk.Label(reactframe,text='Akt Vessel').grid(column=0,row=81,padx=5) re8 = ttk.Entry(reactframe,textvariable=rakt) re8.grid(column=1,row=81,sticky='e') ### commands and bindings pb2.config(command=conf_write) def set_tipblock(): global lpb lpb.xoffset = float(xoffset.get()) lpb.yoffset = float(yoffset.get()) lpb.rows = int(rows.get()) lpb.columns = int(cols.get()) lpb.deltax = float(xspace.get()) lpb.deltay = float(yspace.get()) lpb.z = float(zlevel.get()) lpb.akt = int(akttip.get()) global pip pip.vol = int(tipvol.get()) pip.hub = float(tiphub.get()) pip.fe = int(tipspeed.get()) pip.top = float(tipup.get()) global chem chem.xloc = float(chemX.get()) chem.yloc = float(chemY.get()) chem.vol = float(chemVol.get()) chem.zloc = float(chemZ.get()) chem.deltaz = float(deltaz.get()) chem.tauch = float(tauch.get()) chem.chemvol = float(chemVol.get()) global react react.xoffset = float(rxoffset.get()) react.yoffset = float(ryoffset.get()) react.rows = int(rrows.get()) react.columns = int(rcols.get()) react.deltax = float(rxspace.get()) react.deltay = float(ryspace.get()) react.z = float(rzlevel.get()) react.akt = int(rakt.get()) pb1.config(command=set_tipblock) def homeAll(): serialObj.write(b'\n') b1.configure(command=homeAll) def homeX(): serialObj.write(b'\n') b2.configure(command=homeX) def homeY(): serialObj.write(b'\n') b3.configure(command=homeY) def homeZ(): serialObj.write(b'\n') b4.configure(command=homeZ) def homeP(): serialObj.write(b'\n') b6.configure(command=homeP) def getPos(): serialObj.write(b'\n') b7.configure(command=getPos) def do_gcode(): s = e1.get() s = s + '\n' print(s) serialObj.write(s.encode('utf-8')) b5.configure(command=do_gcode) def upTip(): command.append(pip.up().encode('utf-8')) b9.configure(command=upTip) def downTip(): command.append(pip.down().encode('utf-8')) b10.configure(command=downTip) def nextTip(): upTip() serialObj.write(pip.get_tip(lpb.next()).encode('utf-8')) akttip.set(lpb.akt) downTip() b8.configure(command=nextTip) def load(): if pip.amIdown() == False: command.append(pip.go_top().encode('utf-8')) command.append(pip.go_down().encode('utf-8')) else: command.append(pip.go_top().encode('utf-8')) pip.setVolMax() aktvol.set(pip.getVol()) b13.config(command=load) def dispense(): v = reaPart.get() if pip.dispenseVol(v): command.append(pip.sendE().encode('utf-8')) else : takeChem() upTip() command.append(pip.get_tip(react.same()).encode('utf-8')) downTip() if pip.dispenseVol(v): command.append(pip.sendE().encode('utf-8')) else: print('Error') aktvol.set(pip.getVol()) print(pip.getVol()) b12.config(command=dispense) def top(): command.append(pip.go_top().encode('utf-8')) b11.config(command=top) def takeChem(): upTip() pip.setXY(chem.getXY()) command.append(pip.sendXY().encode('utf-8')) pip.setZ(chem.load(pip.vol/1000)) #load 1ml command.append(pip.down().encode('utf-8')) load() command.append(pip.up().encode('utf-8')) chemVol.set(chem.vol) b14.config(command=takeChem) def nextVessel(): upTip() command.append(pip.get_tip(react.next()).encode('utf-8')) rakt.set(react.akt) downTip() b15.config(command=nextVessel) def loadNext(): upTip() takeChem() nextVessel() dispense() upTip() b16.config(command=loadNext) def loadSerie(): takeChem() p = startVessel.get() q = lastVessel.get() + 1 for i in range(p,q): print(i) react.akt = i rakt.set(react.akt) upTip() command.append(pip.get_tip(react.same()).encode('utf-8')) downTip() dispense() upTip() b17.config(command=loadSerie) def clearTip(): upTip() pip.setXY(chem.getXY()) command.append(pip.sendXY().encode('utf-8')) pip.clearVol() command.append(pip.sendE().encode('utf-8')) b18.config(command=clearTip) ### Init Vars startVessel.set(1) e2.config(textvariable=startVessel) lastVessel.set(6) e3.config(textvariable=lastVessel) weiter = True def checkSerialPort(): global weiter if serialObj.isOpen() and serialObj.in_waiting: recentPacket = serialObj.readline() recentPacketString = recentPacket.decode('utf') txt.insert('0.1',recentPacketString,'small') weiter = True if (len(command) > 0) & (weiter==True) : x = command.pop(0) txt.insert('0.1',x,'small') serialObj.write(x) weiter=False while True: root.update() checkSerialPort()