From 03371143cd476c978fbc5c87588c56e60678f65c Mon Sep 17 00:00:00 2001 From: jens Date: Mon, 29 Nov 2021 19:24:18 +0000 Subject: [PATCH] Replace labrobot.py --- gui/labrobot.py | 475 ++++++++++++++---------------------------------- 1 file changed, 132 insertions(+), 343 deletions(-) diff --git a/gui/labrobot.py b/gui/labrobot.py index 6b4b9dd..cc9991b 100644 --- a/gui/labrobot.py +++ b/gui/labrobot.py @@ -1,364 +1,153 @@ -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 - - -# 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 = 115200 - serialObj.open() - - -root = tk.Tk() -#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) - -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') -###################### Parts -## init Labrobot +from tkinter.constants import X -xoffset = tk.DoubleVar() -yoffset = tk.DoubleVar() -rows = tk.IntVar() -cols = tk.IntVar() -xspace = tk.DoubleVar() -yspace = tk.DoubleVar() -tipvol = tk.IntVar() -zlevel = tk.DoubleVar() -tipup = tk.DoubleVar() -tiphub = tk.DoubleVar() -tipspeed = tk.IntVar() -akttip = tk.IntVar() +class LabPis: + """ Point in Lab Space | e.g. Point of a pipette tip""" + default_x = 0 + default_y = 0 + default_z = 0 + default_e = 0 # e.g piston position + default_id = 0 -chemX = tk.DoubleVar() -chemY = tk.DoubleVar() -chemVol = tk.DoubleVar() -chemZ = tk.DoubleVar() -deltaz = tk.DoubleVar() -tauch = tk.DoubleVar() + def __init__(self, x=default_x,y=default_y,z=default_z,id=default_id,e=default_e): + self.x = x + self.y = y + self.z = z + self.e = e + self.id = id -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))) + def __str__(self) -> str: + return(f'') -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())) - with open(os.path.join(os.path.dirname(__file__), "config.ini"),'w') as f: - config.write(f) -conf_read() +class LabPip(LabPis): + default_vol = 1000 # pipette volume + default_top = 20 # piston top position + default_hub = 10 # piston max hub + default_fe = 2000 # speed piston -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()) - -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') -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') -### 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()) - -pb1.config(command=set_tipblock) + def __init__(self, x=LabPis.default_x, y=LabPis.default_y, z=LabPis.default_z, id=LabPis.default_id, e=LabPis.default_e, + vol=default_vol,hub=default_hub,fe=default_fe,top=default_top): + super().__init__(x=x, y=y, z=z, id=id, e=e) + self.vol = vol + self.fe = fe + self.hub = hub + self.top = top -def homeAll(): - serialObj.write(b'\n') -b1.configure(command=homeAll) + def __str__(self) -> str: + return super().__str__()[:-1]+f'|top={self.top}|hub={self.hub}|vol={self.vol}|fe={self.fe}>' -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(): - serialObj.write(pip.up().encode('utf-8')) -b9.configure(command=upTip) - -def downTip(): - serialObj.write(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() + def sendE(self): + return f'\n' -b8.configure(command=nextTip) + def sendXY(self): + return f'\n' -def load(): - serialObj.write(pip.go_top().encode('utf-8')) - serialObj.write(pip.go_down().encode('utf-8')) - serialObj.write(pip.go_top().encode('utf-8')) -b13.config(command=load) + def go_top(self): + self.e=self.top + return self.sendE() -def dispense(): - serialObj.write(pip.go_down().encode('utf-8')) -b12.config(command=dispense) + def get_tip(self,l): + self.up() + self.x = l[0] + self.y = l[1] + self.z = l[2] + return self.sendXY() -def top(): - serialObj.write(pip.go_top().encode('utf-8')) -b11.config(command=top) + def go_down(self): + self.e = self.top + self.hub + return self.sendE() -def takeChem(): - print(chem.getXY()) - pip.setXY(chem.getXY()) - serialObj.write(pip.sendXY().encode('utf-8')) - pip.setZ(chem.load(1)) - serialObj.write(pip.down().encode('utf-8')) - serialObj.write(pip.go_top().encode('utf-8')) - upTip() + def up(self): + return f'\n' + + def down(self): + return f'\n' + def setXY(self,l): + self.x=l[0] + self.y=l[1] + + def setZ(self,z): + self.z = z + + + +class LabPipBlock(): + """ Pipettenblock description + x_offset, y_offset of first tip, + z for take a tip, + number of rows and columns, + deltax,deltay space between two tips + """ + + def __init__(self,xoffset,yoffset,z,rows,cols,deltax,deltay): + self.xoffset = xoffset + self.yoffset = yoffset + self.rows = rows + self.columns = cols + self.anz = self.rows * self.columns + self.deltax = deltax + self.deltay = deltay + self.z = z + self.akt = 0 + + + def next(self): + if self.akt == self.anz: + print(f'akt ={self.akt} anz= {self.anz}') + return f'No more tips !!' + else : + r = self.anz / self.rows + m = self.akt % r # column + c = self.akt // r # row + self.akt += 1 + x = self.xoffset + (m * self.deltax) + y = self.yoffset + (c * self.deltay) + print(f'x={x} y= {y} akt= {self.akt}') + return x,y,self.z + + def say_ok(self): + print('ok') + +class ChemLoc(): + """ Chemikalien Lokation zloc location of surface + vol of chemical + change of surface per ml """ + + def __init__(self,xloc,yloc,zloc,vol,deltaz,tauch): + self.xloc = xloc + self.yloc = yloc + self.zloc = zloc + self.vol = vol + self.deltaz = deltaz + self.tauch = tauch + + def getXY(self): + return self.xloc,self.yloc + + def load(self,ml): + if self.vol > ml: + z = self.zloc + self.tauch; + self.zloc = self.zloc + self.deltaz*ml + self.vol = self.vol - ml + return z + else: + return 0 -b14.config(command=takeChem) -def checkSerialPort(): - if serialObj.isOpen() and serialObj.in_waiting: - recentPacket = serialObj.readline() - recentPacketString = recentPacket.decode('utf') - txt.insert('0.1',recentPacketString,'small') - -while True: - root.update() - checkSerialPort() - - + +#Job 100myl of A in Vial 1 +#v1 = LabPis(200,200,100,21) +#a1 = LabPis(100,100,100,1) +#p1 = LabPis() +if __name__ == '__main__': + lpb = LabPipBlock(16,1,78,20,5,108,86) + pip = LabPip(vol=500) + pip.fe =5000 + for i in range(20): + print(pip.get_tip(lpb.next()))