From d757bb5982989643fc0695c84e68b58a5aee976b Mon Sep 17 00:00:00 2001 From: Neil Gershenfeld <gersh@cba.mit.edu> Date: Sat, 28 Aug 2021 14:23:27 -0400 Subject: [PATCH] wip --- Urumbot/Urumbot.py | 704 +++++++++++++++++++++++---------------------- 1 file changed, 361 insertions(+), 343 deletions(-) diff --git a/Urumbot/Urumbot.py b/Urumbot/Urumbot.py index 44a7689..aec2966 100644 --- a/Urumbot/Urumbot.py +++ b/Urumbot/Urumbot.py @@ -16,6 +16,9 @@ import tkinter.filedialog from math import * import serial,os,time,multiprocessing,sys # +# Ubot class +# +# # global variables # forward = b'f' @@ -27,18 +30,16 @@ xmin = ymin = 0 port0 = port1 = portz = 0 tpwm = 20000 # us (50 Hz) workers = [] + +# # -# shared memory variables # -Servo = multiprocessing.Value('H',0,lock=False) # unsigned short -Count0 = multiprocessing.Value('i',0,lock=False) # signed int -Count1 = multiprocessing.Value('i',0,lock=False) # signed int -Step0 = multiprocessing.Value('f',0,lock=False) # float -Step1 = multiprocessing.Value('f',0,lock=False) # float +def StartProcess(): + print('hello') # # open ports and start event loop # -def Connect(): +def ConnectPort(): global port0,port1,portz # try: @@ -59,12 +60,6 @@ def Connect(): except: print('can not open '+PortZVar.get()) # - try: - EventProcess = multiprocessing.Process(target=EventLoop) - EventProcess.start() - workers.append(EventProcess) - except: - print('can not start event loop') # # event loop # @@ -104,341 +99,364 @@ def EventLoop(): port1.write(reverse) Count1.value += 1 # -# UI routines -# -# -def Quit(): - for w in workers: - w.terminate() - root.destroy() - sys.exit() -# -def Jog0CW(): - Step0.value = int(float(StepTimeVar.get())*1000000) - Step1.value = 0 - Count0.value = int(JogStepsVar.get()) - Count1.value = 0 -# -def Jog0CCW(): - Step0.value = int(float(StepTimeVar.get())*1000000) - Step1.value = 0 - Count0.value = -int(JogStepsVar.get()) - Count1.value = 0 -# -def Jog1CW(): - Step0.value = 0 - Step1.value = int(float(StepTimeVar.get())*1000000) - Count0.value = 0 - Count1.value = int(JogStepsVar.get()) -# -def Jog1CCW(): - Step0.value = 0 - Step1.value = int(float(StepTimeVar.get())*1000000) - Count0.value = 0 - Count1.value = -int(JogStepsVar.get()) -# -def PolarToCartesian(r0,r1): - x0 = float(X0Var.get()) - y0 = float(Y0Var.get()) - x1 = float(X1Var.get()) - y1 = float(Y1Var.get()) - d = sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0)) - x = (d*d+r0*r0-r1*r1)/(2*d) - y = sqrt(r0*r0-x*x) - return (x,y) +# main process # -def CartesianToPolar(x,y): - x0 = float(X0Var.get()) - y0 = float(Y0Var.get()) - x1 = float(X1Var.get()) - y1 = float(Y1Var.get()) - r0 = sqrt((x-x0)*(x-x0)+(y-y0)*(y-y0)) - r1 = sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1)) - return (r0,r1) -# -def JogAngle(): - r0 = float(R0Var.get()) - r1 = float(R1Var.get()) - x,y = PolarToCartesian(r0,r1) - theta = float(JogAngleVar.get())*pi/180 - r = int(JogStepsVar.get())*float(StepSizeVar.get()) - xnew = x+r*cos(theta) - ynew = y+r*sin(theta) - MoveTo(xnew,ynew) -# -def UpdatePWM(): - Servo.value = int(PWMVar.get()) -# -def PenUp(): - Servo.value = int(PWMaxVar.get()) - time.sleep(float(ServoDelayVar.get())) -# -def PenDown(): - Servo.value = int(PWMinVar.get()) - time.sleep(float(ServoDelayVar.get())) -# -def LoadFile(): - global points,xmin,ymin,plotscale - filename = tkinter.filedialog.askopenfile() - file = open(filename.name,'r') - xmin = ymin = 1e10 - xmax = ymax = -1e10 - digits = ['-','0','1','2','3','4','5','6','7','8','9'] - arg = '' - num = '' - cmd = '' - mode = '' - point = 0 - points = [] - x = y = 0 - Plot.create_rectangle(0,0,plotsize,plotsize,outline='',fill='white') - while 1: - chr = file.read(1) - if not chr: - break - if ((chr == 'n') or (chr == '\r') or (chr == '\n')): - continue - elif (chr == ';'): - if (num != ''): - if (mode == 'PR'): - if (point == 0): - x += float(num)/40.0 - points[-1].append(x) - else: - y += float(num)/40.0 - points[-1].append(y) - point = 1-point - else: - points[-1].append(float(num)/40.0) - num = '' - arg = '' - cmd = '' - elif (chr == ','): - if (num != ''): - if (mode == 'PR'): - if (point == 0): - x += float(num)/40.0 - points[-1].append(x) +if __name__ == '__main__': + # + # + # + class VarsClass: + # + # shared memory variables + # + Servo = multiprocessing.Value('H',0,lock=False) # unsigned short + Count0 = multiprocessing.Value('i',0,lock=False) # signed int + Count1 = multiprocessing.Value('i',0,lock=False) # signed int + Step0 = multiprocessing.Value('f',0,lock=False) # float + Step1 = multiprocessing.Value('f',0,lock=False) # float + vars = VarsClass() + # + # UI routines + # + def Quit(): + vars.process.terminate() + root.destroy() + sys.exit() + # + def Connect(): + try: + EventProcess = multiprocessing.Process(target=StartProcess) + EventProcess.start() + vars.process = EventProcess + except: + print('can not start event loop') + # + def Jog0CW(): + Step0.value = int(float(StepTimeVar.get())*1000000) + Step1.value = 0 + Count0.value = int(JogStepsVar.get()) + Count1.value = 0 + # + def Jog0CCW(): + Step0.value = int(float(StepTimeVar.get())*1000000) + Step1.value = 0 + Count0.value = -int(JogStepsVar.get()) + Count1.value = 0 + # + def Jog1CW(): + Step0.value = 0 + Step1.value = int(float(StepTimeVar.get())*1000000) + Count0.value = 0 + Count1.value = int(JogStepsVar.get()) + # + def Jog1CCW(): + Step0.value = 0 + Step1.value = int(float(StepTimeVar.get())*1000000) + Count0.value = 0 + Count1.value = -int(JogStepsVar.get()) + # + def PolarToCartesian(r0,r1): + x0 = float(X0Var.get()) + y0 = float(Y0Var.get()) + x1 = float(X1Var.get()) + y1 = float(Y1Var.get()) + d = sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0)) + x = (d*d+r0*r0-r1*r1)/(2*d) + y = sqrt(r0*r0-x*x) + return (x,y) + # + def CartesianToPolar(x,y): + x0 = float(X0Var.get()) + y0 = float(Y0Var.get()) + x1 = float(X1Var.get()) + y1 = float(Y1Var.get()) + r0 = sqrt((x-x0)*(x-x0)+(y-y0)*(y-y0)) + r1 = sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1)) + return (r0,r1) + # + def JogAngle(): + r0 = float(R0Var.get()) + r1 = float(R1Var.get()) + x,y = PolarToCartesian(r0,r1) + theta = float(JogAngleVar.get())*pi/180 + r = int(JogStepsVar.get())*float(StepSizeVar.get()) + xnew = x+r*cos(theta) + ynew = y+r*sin(theta) + MoveTo(xnew,ynew) + # + def UpdatePWM(): + vars.Servo.value = int(PWMVar.get()) + # + def PenUp(): + vars.Servo.value = int(PWMaxVar.get()) + time.sleep(float(ServoDelayVar.get())) + # + def PenDown(): + vars.Servo.value = int(PWMinVar.get()) + time.sleep(float(ServoDelayVar.get())) + # + def LoadFile(): + global points,xmin,ymin,plotscale + filename = tkinter.filedialog.askopenfile() + file = open(filename.name,'r') + xmin = ymin = 1e10 + xmax = ymax = -1e10 + digits = ['-','0','1','2','3','4','5','6','7','8','9'] + arg = '' + num = '' + cmd = '' + mode = '' + point = 0 + points = [] + x = y = 0 + Plot.create_rectangle(0,0,plotsize,plotsize,outline='',fill='white') + while 1: + chr = file.read(1) + if not chr: + break + if ((chr == 'n') or (chr == '\r') or (chr == '\n')): + continue + elif (chr == ';'): + if (num != ''): + if (mode == 'PR'): + if (point == 0): + x += float(num)/40.0 + points[-1].append(x) + else: + y += float(num)/40.0 + points[-1].append(y) + point = 1-point else: - y += float(num)/40.0 - points[-1].append(y) - point = 1-point - else: - points[-1].append(float(num)/40.0) - num = '' - else: - arg += chr - if (arg == 'PA'): - mode = 'PA' - arg = '' - elif (arg == 'PR'): - mode = 'PR' - arg = '' - elif (arg == 'PU'): - cmd = 'PU' + points[-1].append(float(num)/40.0) + num = '' arg = '' - points.append(['PU']) - elif (arg == 'PD'): - cmd = 'PD' - arg = '' - points.append(['PD']) - elif ((chr in digits) and ((cmd == 'PU') or (cmd == 'PD'))): - num += chr - file.close() - for segment in range(len(points)): - for point in range(1,len(points[segment]),2): - x = points[segment][point] - if (x > xmax): xmax = x - if (x < xmin): xmin = x - y = points[segment][point+1] - if (y > ymax): ymax = y - if (y < ymin): ymin = y - FileLimits.config(text=f"{xmax-xmin:.3f} x {ymax-ymin:.3f}") - if ((xmax-xmin) > (ymax-ymin)): - plotscale = (plotsize-2)/(xmax-xmin) - else: - plotscale = (plotsize-2)/(ymax-ymin) - xold = 0 - yold = plotsize-1 - for segment in range(len(points)): - type = points[segment][0] - for point in range(1,len(points[segment]),2): - xnew = 1+plotscale*(points[segment][point]-xmin) - ynew = (plotsize-1)-plotscale*(points[segment][point+1]-ymin) - if (type == 'PU'): - Plot.create_line(xold,yold,xnew,ynew,width=1,fill="#FF0000") + cmd = '' + elif (chr == ','): + if (num != ''): + if (mode == 'PR'): + if (point == 0): + x += float(num)/40.0 + points[-1].append(x) + else: + y += float(num)/40.0 + points[-1].append(y) + point = 1-point + else: + points[-1].append(float(num)/40.0) + num = '' else: - Plot.create_line(xold,yold,xnew,ynew,width=1,fill="#000000") - xold = xnew - yold = ynew -# -def DrawFile(): - global points,xmin,ymin - r0 = float(R0Var.get()) - r1 = float(R1Var.get()) - x0,y0 = PolarToCartesian(r0,r1) - xold = 0 - yold = plotsize-1 - Plot.create_rectangle(0,0,plotsize,plotsize,outline='',fill='white') - for segment in range(len(points)): - type = points[segment][0] - if (type == 'PU'): - PenUp() + arg += chr + if (arg == 'PA'): + mode = 'PA' + arg = '' + elif (arg == 'PR'): + mode = 'PR' + arg = '' + elif (arg == 'PU'): + cmd = 'PU' + arg = '' + points.append(['PU']) + elif (arg == 'PD'): + cmd = 'PD' + arg = '' + points.append(['PD']) + elif ((chr in digits) and ((cmd == 'PU') or (cmd == 'PD'))): + num += chr + file.close() + for segment in range(len(points)): + for point in range(1,len(points[segment]),2): + x = points[segment][point] + if (x > xmax): xmax = x + if (x < xmin): xmin = x + y = points[segment][point+1] + if (y > ymax): ymax = y + if (y < ymin): ymin = y + FileLimits.config(text=f"{xmax-xmin:.3f} x {ymax-ymin:.3f}") + if ((xmax-xmin) > (ymax-ymin)): + plotscale = (plotsize-2)/(xmax-xmin) else: - PenDown() - for point in range(1,len(points[segment]),2): - xnew = 1+plotscale*(points[segment][point]-xmin) - ynew = (plotsize-1)-plotscale*(points[segment][point+1]-ymin) + plotscale = (plotsize-2)/(ymax-ymin) + xold = 0 + yold = plotsize-1 + for segment in range(len(points)): + type = points[segment][0] + for point in range(1,len(points[segment]),2): + xnew = 1+plotscale*(points[segment][point]-xmin) + ynew = (plotsize-1)-plotscale*(points[segment][point+1]-ymin) + if (type == 'PU'): + Plot.create_line(xold,yold,xnew,ynew,width=1,fill="#FF0000") + else: + Plot.create_line(xold,yold,xnew,ynew,width=1,fill="#000000") + xold = xnew + yold = ynew + # + def DrawFile(): + global points,xmin,ymin + r0 = float(R0Var.get()) + r1 = float(R1Var.get()) + x0,y0 = PolarToCartesian(r0,r1) + xold = 0 + yold = plotsize-1 + Plot.create_rectangle(0,0,plotsize,plotsize,outline='',fill='white') + for segment in range(len(points)): + type = points[segment][0] if (type == 'PU'): - Plot.create_line(xold,yold,xnew,ynew,width=1,fill="#FF0000") + PenUp() else: - Plot.create_line(xold,yold,xnew,ynew,width=1,fill="#000000") - xold = xnew - yold = ynew - x = x0-points[segment][point]+xmin - y = y0-points[segment][point+1]+ymin - MoveTo(x,y) -# -def MoveTo(xnew,ynew): - r0 = float(R0Var.get()) - r1 = float(R1Var.get()) - x,y = PolarToCartesian(r0,r1) - r0new,r1new = CartesianToPolar(xnew,ynew) - count0 = int((r0new-r0)/float(StepSizeVar.get())) - count1 = int((r1new-r1)/float(StepSizeVar.get())) - r = sqrt(count0*count0+count1*count1) - if (r == 0): - return - t = r*float(StepTimeVar.get())*1000000 - if (count0 != 0): - Step0.value = fabs(t/count0) - if (count1 != 0): - Step1.value = fabs(t/count1) - Count0.value,Count1.value = count0,count1 - R0Var.set(f"{float(R0Var.get())+count0*float(StepSizeVar.get()):.3f}") - R1Var.set(f"{float(R1Var.get())+count1*float(StepSizeVar.get()):.3f}") - root.update() - while (True): - if ((Count0.value == 0) and (Count1.value == 0)): + PenDown() + for point in range(1,len(points[segment]),2): + xnew = 1+plotscale*(points[segment][point]-xmin) + ynew = (plotsize-1)-plotscale*(points[segment][point+1]-ymin) + if (type == 'PU'): + Plot.create_line(xold,yold,xnew,ynew,width=1,fill="#FF0000") + else: + Plot.create_line(xold,yold,xnew,ynew,width=1,fill="#000000") + xold = xnew + yold = ynew + x = x0-points[segment][point]+xmin + y = y0-points[segment][point+1]+ymin + MoveTo(x,y) + # + def MoveTo(xnew,ynew): + r0 = float(R0Var.get()) + r1 = float(R1Var.get()) + x,y = PolarToCartesian(r0,r1) + r0new,r1new = CartesianToPolar(xnew,ynew) + count0 = int((r0new-r0)/float(StepSizeVar.get())) + count1 = int((r1new-r1)/float(StepSizeVar.get())) + r = sqrt(count0*count0+count1*count1) + if (r == 0): return -# -# set up UI -# -root = Tk() -root.title('Urumbot-serial.py') -root.configure(bg='white') -pad = 2 -# -row = 0 -Button(root,text='Quit',command=Quit,bg='white').grid(column=1,row=row,padx=pad,pady=pad) -# -row += 1 -Label(root,text='Baud Rate: ',bg='white').grid(column=0,row=row,padx=pad,pady=pad) -BaudRateVar = StringVar(root,'921600') -Entry(root,textvariable=BaudRateVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) -# -row += 1 -Label(root,text='Jog steps:',bg='white').grid(column=0,row=row,padx=pad,pady=pad) -JogStepsVar = StringVar(root,'5000') -Entry(root,textvariable=JogStepsVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) -# -row += 1 -Label(root,text='Step size (mm):',bg='white').grid(column=0,row=row,padx=pad) -StepSizeVar = StringVar(root,'0.02') -Entry(root,textvariable=StepSizeVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) -# -row += 1 -Label(root,text='Step time (s): ',bg='white').grid(column=0,row=row,padx=pad,pady=pad) -StepTimeVar = StringVar(root,'0.0005') -Entry(root,textvariable=StepTimeVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) -# -row += 1 -ConnectButton = Button(root,text='Connect',command=Connect,bg='white') -ConnectButton.grid(column=1,row=row,padx=pad,pady=pad) -# -row += 1 -Label(root,text='Motor',bg='white').grid(column=0,row=row,padx=pad,pady=pad) -Label(root,text='Port',bg='white').grid(column=1,row=row,padx=pad,pady=pad) -Label(root,text='Jog',bg='white').grid(column=2,row=row,columnspan=2,padx=pad,pady=pad) -Label(root,text='x (mm)',bg='white').grid(column=4,row=row,padx=pad,pady=pad) -Label(root,text='y (mm)',bg='white').grid(column=5,row=row,padx=pad,pady=pad) -row += 1 -Label(root,text='0',bg='white').grid(column=0,row=row,padx=pad,pady=pad) -Port0Var = StringVar(root,'/dev/ttyACM0') -Entry(root,textvariable=Port0Var,width=15).grid(column=1,row=row,padx=pad,pady=pad) -Button(root,text='CW',command=Jog0CW,bg='white').grid(column=2,row=row,padx=pad,pady=pad) -Button(root,text='CCW',command=Jog0CCW,bg='white').grid(column=3,row=row,padx=pad,pady=pad) -X0Var = StringVar(root,'0') -Entry(root,textvariable=X0Var,width=10).grid(column=4,row=row,padx=pad,pady=pad) -Y0Var = StringVar(root,'0') -Entry(root,textvariable=Y0Var,width=10).grid(column=5,row=row,padx=pad,pady=pad) -# -row += 1 -Label(root,text='1',bg='white').grid(column=0,row=row,padx=pad,pady=pad) -Port1Var = StringVar(root,'/dev/ttyACM1') -Entry(root,textvariable=Port1Var,width=15).grid(column=1,row=row,padx=pad,pady=pad) -Button(root,text='CW',command=Jog1CW,bg='white').grid(column=2,row=row,padx=pad,pady=pad) -Button(root,text='CCW',command=Jog1CCW,bg='white').grid(column=3,row=row,padx=pad,pady=pad) -X1Var = StringVar(root,'500') -Entry(root,textvariable=X1Var,width=10).grid(column=4,row=row,padx=pad,pady=pad) -Y1Var = StringVar(root,'0') -Entry(root,textvariable=Y1Var,width=10).grid(column=5,row=row,padx=pad,pady=pad) -# -row += 1 -Label(root,text='Angle (degrees)',bg='white').grid(column=0,row=row,padx=pad,pady=pad) -JogAngleVar = StringVar(root,'0') -Entry(root,textvariable=JogAngleVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) -Button(root,text='Jog Angle',command=JogAngle,bg='white').grid(column=2,columnspan=2,row=row,padx=pad,pady=pad) -# -row += 1 -Label(root,text='Radius 0 (mm):',bg='white').grid(column=0,row=row,padx=pad) -R0Var = StringVar(root,'500') -Entry(root,textvariable=R0Var,width=15).grid(column=1,row=row,padx=pad,pady=pad) -# -row += 1 -Label(root,text='Radius 1 (mm):',bg='white').grid(column=0,row=row,padx=pad) -R1Var = StringVar(root,'500') -Entry(root,textvariable=R1Var,width=15).grid(column=1,row=row,padx=pad,pady=pad) -Label(root,text='min',bg='white').grid(column=4,row=row,padx=pad) -Label(root,text='max',bg='white').grid(column=5,row=row,padx=pad) -# -row += 1 -Label(root,text='Z servo:',bg='white').grid(column=0,row=row,padx=pad) -PortZVar = StringVar(root,'/dev/ttyACM2') -Entry(root,textvariable=PortZVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) -Label(root,text='PWM (us):',bg='white').grid(column=2,columnspan=2,row=row,padx=pad) -PWMinVar = StringVar(root,'1000') -Entry(root,textvariable=PWMinVar,width=10).grid(column=4,row=row,padx=pad,pady=pad) -PWMaxVar = StringVar(root,'2000') -Entry(root,textvariable=PWMaxVar,width=10).grid(column=5,row=row,padx=pad,pady=pad) -# -row += 1 -Label(root,text='PWM (us):',bg='white').grid(column=0,row=row,padx=pad) -PWMVar = StringVar(root,'1500') -Servo.value = int(PWMVar.get()) -Entry(root,textvariable=PWMVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) -Button(root,text='Update',command=UpdatePWM,bg='white').grid(column=2,columnspan=2,row=row,padx=pad,pady=pad) -# -row += 1 -Label(root,text='Servo Delay (s):',bg='white').grid(column=0,row=row,padx=pad) -ServoDelayVar = StringVar(root,'0.5') -Entry(root,textvariable=ServoDelayVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) -# -row += 1 -Button(root,text='Load HPGL File',command=LoadFile,bg='white').grid(column=0,row=row,padx=pad,pady=pad) -FileNameVar = StringVar(root,'') -Button(root,text='Draw',command=DrawFile,bg='white').grid(column=1,row=row,padx=pad,pady=pad) -# -row += 1 -Label(root,text='drawing size (mm):',bg='white').grid(column=0,row=row,padx=pad,pady=pad) -FileLimits = Label(root,text='',bg='white') -FileLimits.grid(column=1,row=row,padx=pad,pady=pad) -# -row += 1 -Label(root,text='origin',bg='white').grid(column=0,row=row,padx=pad,pady=pad,sticky='se') -Plot = Canvas(root,width=plotsize,height=plotsize,background='white') -Plot.grid(column=1,row=row,columnspan=4,padx=pad,pady=pad,sticky='sw') -# -# start mainloop -# -root.mainloop() + t = r*float(StepTimeVar.get())*1000000 + if (count0 != 0): + Step0.value = fabs(t/count0) + if (count1 != 0): + Step1.value = fabs(t/count1) + Count0.value,Count1.value = count0,count1 + R0Var.set(f"{float(R0Var.get())+count0*float(StepSizeVar.get()):.3f}") + R1Var.set(f"{float(R1Var.get())+count1*float(StepSizeVar.get()):.3f}") + root.update() + while (True): + if ((Count0.value == 0) and (Count1.value == 0)): + return + # + # set up UI + # + root = Tk() + root.title('Urumbot-serial.py') + root.configure(bg='white') + pad = 2 + # + row = 0 + Button(root,text='Quit',command=Quit,bg='white').grid(column=1,row=row,padx=pad,pady=pad) + # + row += 1 + Label(root,text='Baud Rate: ',bg='white').grid(column=0,row=row,padx=pad,pady=pad) + BaudRateVar = StringVar(root,'921600') + Entry(root,textvariable=BaudRateVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) + # + row += 1 + Label(root,text='Jog steps:',bg='white').grid(column=0,row=row,padx=pad,pady=pad) + JogStepsVar = StringVar(root,'5000') + Entry(root,textvariable=JogStepsVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) + # + row += 1 + Label(root,text='Step size (mm):',bg='white').grid(column=0,row=row,padx=pad) + StepSizeVar = StringVar(root,'0.02') + Entry(root,textvariable=StepSizeVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) + # + row += 1 + Label(root,text='Step time (s): ',bg='white').grid(column=0,row=row,padx=pad,pady=pad) + StepTimeVar = StringVar(root,'0.0005') + Entry(root,textvariable=StepTimeVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) + # + row += 1 + ConnectButton = Button(root,text='Connect',command=Connect,bg='white') + ConnectButton.grid(column=1,row=row,padx=pad,pady=pad) + # + row += 1 + Label(root,text='Motor',bg='white').grid(column=0,row=row,padx=pad,pady=pad) + Label(root,text='Port',bg='white').grid(column=1,row=row,padx=pad,pady=pad) + Label(root,text='Jog',bg='white').grid(column=2,row=row,columnspan=2,padx=pad,pady=pad) + Label(root,text='x (mm)',bg='white').grid(column=4,row=row,padx=pad,pady=pad) + Label(root,text='y (mm)',bg='white').grid(column=5,row=row,padx=pad,pady=pad) + row += 1 + Label(root,text='0',bg='white').grid(column=0,row=row,padx=pad,pady=pad) + Port0Var = StringVar(root,'/dev/ttyACM0') + Entry(root,textvariable=Port0Var,width=15).grid(column=1,row=row,padx=pad,pady=pad) + Button(root,text='CW',command=Jog0CW,bg='white').grid(column=2,row=row,padx=pad,pady=pad) + Button(root,text='CCW',command=Jog0CCW,bg='white').grid(column=3,row=row,padx=pad,pady=pad) + X0Var = StringVar(root,'0') + Entry(root,textvariable=X0Var,width=10).grid(column=4,row=row,padx=pad,pady=pad) + Y0Var = StringVar(root,'0') + Entry(root,textvariable=Y0Var,width=10).grid(column=5,row=row,padx=pad,pady=pad) + # + row += 1 + Label(root,text='1',bg='white').grid(column=0,row=row,padx=pad,pady=pad) + Port1Var = StringVar(root,'/dev/ttyACM1') + Entry(root,textvariable=Port1Var,width=15).grid(column=1,row=row,padx=pad,pady=pad) + Button(root,text='CW',command=Jog1CW,bg='white').grid(column=2,row=row,padx=pad,pady=pad) + Button(root,text='CCW',command=Jog1CCW,bg='white').grid(column=3,row=row,padx=pad,pady=pad) + X1Var = StringVar(root,'500') + Entry(root,textvariable=X1Var,width=10).grid(column=4,row=row,padx=pad,pady=pad) + Y1Var = StringVar(root,'0') + Entry(root,textvariable=Y1Var,width=10).grid(column=5,row=row,padx=pad,pady=pad) + # + row += 1 + Label(root,text='Angle (degrees)',bg='white').grid(column=0,row=row,padx=pad,pady=pad) + JogAngleVar = StringVar(root,'0') + Entry(root,textvariable=JogAngleVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) + Button(root,text='Jog Angle',command=JogAngle,bg='white').grid(column=2,columnspan=2,row=row,padx=pad,pady=pad) + # + row += 1 + Label(root,text='Radius 0 (mm):',bg='white').grid(column=0,row=row,padx=pad) + R0Var = StringVar(root,'500') + Entry(root,textvariable=R0Var,width=15).grid(column=1,row=row,padx=pad,pady=pad) + # + row += 1 + Label(root,text='Radius 1 (mm):',bg='white').grid(column=0,row=row,padx=pad) + R1Var = StringVar(root,'500') + Entry(root,textvariable=R1Var,width=15).grid(column=1,row=row,padx=pad,pady=pad) + Label(root,text='min',bg='white').grid(column=4,row=row,padx=pad) + Label(root,text='max',bg='white').grid(column=5,row=row,padx=pad) + # + row += 1 + Label(root,text='Z servo:',bg='white').grid(column=0,row=row,padx=pad) + PortZVar = StringVar(root,'/dev/ttyACM2') + Entry(root,textvariable=PortZVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) + Label(root,text='PWM (us):',bg='white').grid(column=2,columnspan=2,row=row,padx=pad) + PWMinVar = StringVar(root,'1000') + Entry(root,textvariable=PWMinVar,width=10).grid(column=4,row=row,padx=pad,pady=pad) + PWMaxVar = StringVar(root,'2000') + Entry(root,textvariable=PWMaxVar,width=10).grid(column=5,row=row,padx=pad,pady=pad) + # + row += 1 + Label(root,text='PWM (us):',bg='white').grid(column=0,row=row,padx=pad) + PWMVar = StringVar(root,'1500') + vars.Servo.value = int(PWMVar.get()) + Entry(root,textvariable=PWMVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) + Button(root,text='Update',command=UpdatePWM,bg='white').grid(column=2,columnspan=2,row=row,padx=pad,pady=pad) + # + row += 1 + Label(root,text='Servo Delay (s):',bg='white').grid(column=0,row=row,padx=pad) + ServoDelayVar = StringVar(root,'0.5') + Entry(root,textvariable=ServoDelayVar,width=15).grid(column=1,row=row,padx=pad,pady=pad) + # + row += 1 + Button(root,text='Load HPGL File',command=LoadFile,bg='white').grid(column=0,row=row,padx=pad,pady=pad) + FileNameVar = StringVar(root,'') + Button(root,text='Draw',command=DrawFile,bg='white').grid(column=1,row=row,padx=pad,pady=pad) + # + row += 1 + Label(root,text='drawing size (mm):',bg='white').grid(column=0,row=row,padx=pad,pady=pad) + FileLimits = Label(root,text='',bg='white') + FileLimits.grid(column=1,row=row,padx=pad,pady=pad) + # + row += 1 + Label(root,text='origin',bg='white').grid(column=0,row=row,padx=pad,pady=pad,sticky='se') + Plot = Canvas(root,width=plotsize,height=plotsize,background='white') + Plot.grid(column=1,row=row,columnspan=4,padx=pad,pady=pad,sticky='sw') + # + # start mainloop + # + root.mainloop() -- GitLab