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