diff --git a/README.md b/README.md index 7dea06e..0d86e70 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# touchCNC -not ready for production - TESTING STAGE -GRBL 1.1 CNC Controller for ODROID C2 with VU PLus Touch Screen +# touchCNC 1.0 +GRBL 1.1 CNC Controller for ODROID C2 with VU PLus Touch Screen or Linux Desktop Should run on any System wit at least 1024x600 Screen Resolution. @@ -7,19 +7,35 @@ Should run on any System wit at least 1024x600 Screen Resolution. - Zero positions - Job commands - Spindle Coolant, Tool and Macro commands -- Gcode milling envelope preview (low cpu usage), +- Gcode milling envelope preview - G28 Position -- Feed override +- Feed override (Not yet working) - terminal +- Laser status and switch ![Screen](https://user-images.githubusercontent.com/6392076/133233601-8ef0e06f-e055-4677-8828-ed092aa37250.png) +- Tested on latest Armbian stable https://www.armbian.com/odroid-c2/#kernels-archive-all +- Tested on Manjaro +- Using cncpro v3 with grbl1.1f -Tested on latest Armbian stable https://www.armbian.com/odroid-c2/#kernels-archive-all +## Clone to your PC +`git clone https://github.com/BKLronin/touchCNC.git` -Based on +## Install +- (Create env) +- In folder enter: +`pip install requirements.txt` + +## Run +`python cnc_gerbil.py` +or +`cd dist` +`./cnc_gerbil` + +### Based on: Python3 tkinter pyserial +gerbil -In some cases you have to manually install tkinter via apt and pyserial via pip. diff --git a/cnc.py b/cnc.py deleted file mode 100644 index 30df109..0000000 --- a/cnc.py +++ /dev/null @@ -1,474 +0,0 @@ -import serial -import time -from tkinter import * -import serial.tools.list_ports -from tkinter import filedialog as fd -import os -import threading -import grbl_gcode_send -import grbl_stream - -grbl = 0 -port = None -i = 10 -GCODE = 0 -gcode_to_stream = [] -countbuf = 0 -writebuffer_byPass = [] -writebuffer = [] -readbuffer = [] -AXIS = 'X' -states = {'M3':'0', 'M8':'0', 'M6':'0', 'G10': '0'} #Spindle, Coolant, Toolchange -dict_GCODE = {'G':'0', - 'X':'0', - 'Y':'0', - 'Z':'0', - 'I':'0', - 'J':'0', - 'F':'0' - } - -#GUI Main -buttonsize_x = 5 -buttonsize_y = 3 -increments = 0 -BORDER = 2 -freetosend = 1 - -#GUI Color Scheme -attention = 'red' -loaded = 'green' -cooling = 'blue' -toolchange = 'yellow' -standard = '#17223B' -feed = '#283B67' - -def grblConnect2(): - global grbl - global port - - #Serial Connection - locations=['/dev/ttyACM0','/dev/ttyUSB0','/dev/ttyUSB1','/dev/ttyACM1','/dev/ttyACM2','/dev/ttyACM3', - '/dev/ttyS0','/dev/ttyS1','/dev/ttyS2','/dev/ttyS3'] - - for device in locations: - try: - #print([comport.device for comport in serial.tools.list_ports.comports()]) - print ("Trying...",device) - grbl = serial.Serial(port= device, baudrate= 115200, timeout =.5) #dsrdtr= True) - port = device - #grbl.open() - #print(grbl.readline()) - grbl.write(str.encode("\r\n\r\n")) - time.sleep(2) # Wait for grbl to initialize - grbl.flushInput() # Flush startup text in serial input - connect_ser.config(bg= loaded) - #print("connected") - - break - except: - #print ("Failed to connect on",device) - grbl = 0 - - # Stream g-code to grbl - #Stream GCODE from -https://onehossshay.wordpress.com/2011/08/26/grbl-a-simple-python-interface/- - -def jogWrite(AXIS, CMD, scale): #Schreiben von manuellen Positionierungsbefehlen - global freetosend - - DECIMAL = [0.1,1,10,100] - scale = increments.get() - MOVE = int(CMD) * DECIMAL[scale -1] - grbl_command = ('$J=G91' + 'G21' + AXIS + str(MOVE)+ 'F1000') - #print(grbl_command) $J=G91G21X10F185 - grbl_gcode_send.send_gcode(grbl, grbl_command) - -def switchButtonState(button): #Umschalter für Knopfstatus - if button["state"] == DISABLED: - button["state"] = NORMAL - else: - button["state"] = DISABLED - -def directWrite(CMD): #Direktes schreiben eines Befehls - global freetosend - #print(freetosend) - grbl_command = CMD - - grbl_gcode_send.send_gcode(grbl, grbl_command) - - -def latchWrite(CMD): - global states - global freetosend - if states[CMD] == '0': - states[CMD] = '1' - if CMD == 'M3': - spindle.config(bg= attention) #A31621 - if CMD == 'M6': - tool.config(bg = toolchange)#E0CA3C - if CMD == 'G10': - zero_all.config(bg = loaded) - - else: - states[CMD] ='0' - if CMD == 'M3': - spindle.config(bg=loaded)#A2D729 - if CMD == 'M6': - tool.config(bg='grey') - #if CMD == 'G10': - # zero_all.config(bg= attention) - - if CMD == 'M3': - if states['M3'] == '1': - grbl_command = 'M3 S1000' - else: - grbl_command = 'M3 S0' - - elif CMD == 'M8': - if states['M8'] == '1': - grbl_command = (CMD) - coolant.config(bg = cooling)#1F7A8C - else: - grbl_command = 'M9' - coolant.config(bg ='grey') - - elif CMD == 'G10': - grbl_command = 'G10 P0 L20 X0 Y0 Z0' - - else: - grbl_command = (CMD) - - #grbl_command = (CMD * int(states[CMD]) ) - #print(grbl_command) - #print(states) - - - grbl_gcode_send.send_gcode(grbl, grbl_command) - - -def terminalWrite(): #Holt Zeichenstring von Editfeld und sendet es - grbl_command = terminal.get() - #print(grbl_command) - - grbl_gcode_send.send_gcode(grbl, grbl_command) - - -def infoScreen(data): #Anzeigecanvas für GRBL Rückmeldungen - global i - terminalFrame = Frame(terminal_recv, bg = 'white') - terminal_recv.create_window(10,i, window = terminalFrame, anchor = 'nw') - Label(terminalFrame, text = data, font = ('Calibri',10), bg ='white', fg ='black').pack() - i += 22 - if i >=400: - i=10 - terminal_recv.delete("all") - -def openGCODE(): #Dialog zur Gcode Auswahl und öffnen der Datei als GCODE Objekt - global gcode_to_stream - filetypes = (('GCODE', '*.nc'),('All files', '*.*')) - GCODE = fd.askopenfile(title='Open a file', initialdir='/home/thomas/Nextcloud/CAM/', filetypes=filetypes) - - if GCODE != 0: - fopen.config(bg= loaded) - extracted = extract_GCODE(GCODE) - draw_GCODE(extracted) - gcode_to_stream = GCODE - - else: - fopen.config(bg = 'grey') - - - #build_xy = findEnvelope() #Aufruf PLatz im Bauraum - #mill_table.create_rectangle(build_xy[0],build_xy[1], fill = 'blue', stipple = 'gray75') # Zeichnen des Objekts im Bauraum - -def extract_GCODE(gcode: list): #Aufschlüsseln der enthaltenen Koordinaten in ein per Schlüssel zugängiges Dictionary - - list_dict_GCODE = [] - for line in gcode: - l = line.split() #Elemente trennen und in Liste konvertieren - for i in range(0,len(l)): - #print (l) - if 'G' in l[i]: - dict_GCODE['G'] = l[i].replace('G','') #Wert einfügen und gleichzeitig G CODE befehl entfernen - if 'X' in l[i]: - dict_GCODE['X'] = l[i].replace('X','') - if 'Y' in l[i]: - dict_GCODE['Y'] = l[i] .replace('Y','') - if 'Z' in l[i]: - dict_GCODE['Z'] = l[i].replace('Z','') - if 'I' in l[i] and not 'ZMIN': - dict_GCODE['I'] = l[i].replace('I','') - if 'J' in l[i]: - dict_GCODE['J'] = l[i].replace('J','') - if 'F' in l[i] and not 'Fusion': - dict_GCODE['F'] = l[i].replace('F','') - - #print(dict_GCODE) - list_dict_GCODE.append(dict_GCODE.copy()) #Copy notwendig da es sich nur um einen "Pointer" handelt der immer auf die zuletzt aktualisierte dict Zeile zeigt. - print(list_dict_GCODE) - - return list_dict_GCODE - -def draw_GCODE(glist): #Zeichnen des GCodes zur Beurteilung des Bauraums - - for i in range(0,len(glist)-1): - - x_y_current = 50 + float(glist[i]['X']), 350 - float(glist[i]['Y']) - x_y_next = 50 + float(glist[i+1]['X']), 350 - float(glist[i+1]['Y']) - - mill_table.create_line(x_y_current, x_y_next) - -def writeToFileLog(log): #Log für Debugzwecke - with open("log.txt", 'a') as out: - out.write(log) - -def displayPosition_request(grbl_pos): - if grbl != 0 : - try: - position = str(grbl_pos) - #print (readbuffer) - - position = position.replace('Idle|', ',') - position = position.replace('Run|', ',') - position = position.replace('WPos:', '') - position = position.replace('MPos:', '') - position = position.replace('>', ',') - position = position.replace('|', ',') - position.strip() - coordinates_list = position.split(',') - #print(coordinates_list) - show_ctrl_x.config(text = coordinates_list[1]) - show_ctrl_y.config(text = coordinates_list[2]) - show_ctrl_z.config(text = coordinates_list[3]) - - mill_table.create_line(coordinates_list[1],coordinates_list[2],coordinates_list[1],coordinates_list[2]+50, arrow = FIRST ) - - #show_ctrl_x_w.config(text = coordinates_list[4]) - #show_ctrl_y_w.config(text = coordinates_list[5]) - #show_ctrl_z_w.config(text = coordinates_list[6]) - - except: - pass - #print("Listerror") - - - else: - print("Serial Busy") - #root.after(1000,displayPosition) - -def displayPosition(): - global readbuffer - if grbl != 0 : - try: - position = str(readbuffer[2]) - #print (readbuffer) - - position = position.replace('Idle|', ',') - position = position.replace('Run|', ',') - position = position.replace('WPos:', '') - position = position.replace('MPos:', '') - position = position.replace('>', ',') - position = position.replace('|', ',') - position.strip() - coordinates_list = position.split(',') - #print(coordinates_list) - show_ctrl_x.config(text = coordinates_list[1]) - show_ctrl_y.config(text = coordinates_list[2]) - show_ctrl_z.config(text = coordinates_list[3]) - - mill_table.create_line(coordinates_list[1],coordinates_list[2],coordinates_list[1]+10,coordinates_list[2]+20 ) - mill_table.create_line(coordinates_list[1],coordinates_list[2],coordinates_list[1]-10,coordinates_list[2]+20 ) - mill_table.create_line(coordinates_list[1]-10,coordinates_list[2]+20,coordinates_list[1]+10,coordinates_list[2]+20 ) - #show_ctrl_x_w.config(text = coordinates_list[4]) - #show_ctrl_y_w.config(text = coordinates_list[5]) - #show_ctrl_z_w.config(text = coordinates_list[6]) - - except: - pass - #print("Listerror") - - else: - print("Serial Busy") - #root.after(1000,displayPosition) - -def grblWrite(): - if gcode_to_stream != None: - print("Stream", gcode_to_stream) - grbl_gcode_send.send_gcode(grbl, gcode_to_stream) - - #fdbk = grbl_gcode_send.send_gcode(grbl, line) - #print(fdbk) - grbl_gcode_send.wait_for_buffer_empty() - -def grblClose(): - # Close file and serial port - #f.close() - try: - grbl.close() - print("closed") - connect_ser.config(bg='grey') - except: - print("Connection still open") - -root = Tk() -root.title('touchCNC') -root.geometry('1024x600+0+0') -root.geometry('1024x600+0+0') -root.resizable(False,False)#17203b -root.attributes('-fullscreen', False) -root.tk_setPalette(background='#11192C', foreground='white',activeBackground='#283867', activeForeground='white' ) - -increments = IntVar() -movement = Frame(root, relief = 'ridge', bd = BORDER) -left = Button(root, text="-X", width = buttonsize_x, height = buttonsize_y, command = lambda:jogWrite('X', '-1', increments),bd = BORDER, bg = standard) -right = Button(root, text="+X",width = buttonsize_x, height = buttonsize_y,command = lambda:jogWrite('X', '1', increments),bd = BORDER, bg = standard) -up = Button(root, text="+Y", width = buttonsize_x, height = buttonsize_y,command = lambda:jogWrite('Y', '1', increments),bd = BORDER, bg = standard) -down = Button(root, text="-Y",width = buttonsize_x, height = buttonsize_y,command = lambda:jogWrite('Y', '-1', increments),bd = BORDER, bg = standard) -z_up = Button(root, text="+Z",width = buttonsize_x, height = buttonsize_y,command = lambda:jogWrite('Z', '1', increments) ,bd = BORDER, bg = standard) -z_down = Button(root, text="-Z",width = buttonsize_x, height = buttonsize_y,command = lambda:jogWrite('Z', '-1', increments),bd = BORDER, bg = standard) - -zero_x = Button(root, text="zero X",width = buttonsize_x, height = 1, command = lambda:directWrite('G10 P0 L20 X0'),bd = BORDER) -zero_y = Button(root, text="zero Y",width = buttonsize_x, height = 1, command = lambda:directWrite('G10 P0 L20 Y0'),bd = BORDER) -zero_z = Button(root, text="zero Z",width = buttonsize_x, height = 1, command = lambda:directWrite('G10 P0 L20 Z0'),bd = BORDER) -zero_all=Button(root, text="zeroAll",width = buttonsize_x, height = 3, command = lambda:latchWrite('G10'),bd = BORDER, bg= 'magenta') - -setzero =Button(root, text="SetPOS",width = buttonsize_x, height = buttonsize_y, command = lambda:directWrite('G28.1'),bd = BORDER) -gozero =Button(root, text="GoPOS",width = buttonsize_x, height = buttonsize_y, command = lambda:directWrite('G28'),bd = BORDER) - -connect_ser = Button(root, text="Cnnct",width = buttonsize_x, height = buttonsize_y, command = grblConnect2, bg = 'grey',bd = BORDER) -discon_ser = Button(root, text="Dsconct",width = buttonsize_x, height = buttonsize_y, command = lambda:grblClose(),bd = BORDER) -unlock = Button(root, text="Unlock",width = buttonsize_x, height = buttonsize_y, command = lambda:directWrite('$X'),bd = BORDER) -start = Button(root, text="START",width = buttonsize_x, height = buttonsize_y, bg = attention, command = lambda: threading.Thread(target = grblWrite).start(),bd = BORDER) -stop = Button(root, text="STOP",width = buttonsize_x, height = buttonsize_y,bd = BORDER, command = lambda: directWrite('') ) -pause = Button(root, text="PAUSE",width = buttonsize_x, height = buttonsize_y, bg = cooling,bd = BORDER,command = lambda: directWrite('!') ) -resume = Button(root, text="RESUME",width = buttonsize_x, height = buttonsize_y,bd = BORDER,command = lambda: directWrite('~')) - -fopen = Button(root, text="GCODE",width = buttonsize_x , height = buttonsize_y, bg = 'grey',fg = 'black', command = openGCODE,bd = BORDER) - -spindle = Button(root, text="Spindle",width = buttonsize_x, height = buttonsize_y,command = lambda:latchWrite('M3')) -coolant = Button(root, text="Coolant",width = buttonsize_x, height = buttonsize_y,command = lambda:latchWrite('M8') ) -tool = Button(root, text="Tool",width = buttonsize_x, height = buttonsize_y,command = lambda:latchWrite('M6') ) -macro = Button(root, text="Macro1",width = buttonsize_x, height = buttonsize_y,command = lambda:directWrite(' G91 G0 X10 Y10 Z50 F1000') ) - -inc1 = Button(root, text="Inc 1%",width = buttonsize_x, height = buttonsize_y,command = lambda:directWrite('‘'),bg= feed) -inc10 = Button(root,text="Inc 10%",width = buttonsize_x, height = buttonsize_y,command = lambda:directWrite('“'),bg= feed ) -dec1 = Button(root, text="Dec 1%",width = buttonsize_x, height = buttonsize_y,command = lambda:directWrite('”'),bg= feed ) -dec10 = Button(root,text="Dec 10%",width = buttonsize_x, height = buttonsize_y,command = lambda:directWrite('’'),bg= feed ) -reset = Button(root,text="= 0: - print("REC:", grbl_out) - print(" Failed to set Grbl check-mode. Aborting...") - quit() - elif grbl_out.find('ok') >= 0: - if self.verbose: - print('REC:', grbl_out) - break - - def send_command(self, command): - self.ser.write((command + '\n').encode()) - - def read_response(self): - return self.ser.readline().strip() - - def send_gcode(self, gcode_file): - l_count = 0 - error_count = 0 - start_time = time.time() - self.start_status_report_timer() - - for line in gcode_file: - l_count += 1 - l_block = line.strip() - if self.settings_mode: - self.send_command(l_block) - while True: - grbl_out = self.read_response() - if grbl_out.find('ok') >= 0: - if self.verbose: - print(" REC<{}: \"{}\"".format(l_count, grbl_out)) - break - elif grbl_out.find('error') >= 0: - if self.verbose: - print(" REC<{}: \"{}\"".format(l_count, grbl_out)) - error_count += 1 - break - else: - print(" MSG: \"{}\"".format(grbl_out)) - else: - c_line = [] - for char in l_block: - c_line.append(len(char) + 1) - grbl_out = '' - while sum(c_line) >= RX_BUFFER_SIZE - 1 or self.ser.inWaiting(): - out_temp = self.read_response() - if out_temp.find('ok') < 0 and out_temp.find('error') < 0: - print(" MSG: \"{}\"".format(out_temp)) - else: - if out_temp.find('error') >= 0: - error_count += 1 - del c_line[0] - if self.verbose: - print(" REC<{}: \"{}\"".format(l_count, out_temp)) - self.send_command(char) - if self.verbose: - print("SND>{}: \"{}\"".format(l_count, char)) - - while l_count > 0: - out_temp = self.read_response() - if out_temp.find('ok') < 0 and out_temp.find('error') < 0: - print(" MSG: \"{}\"".format(out_temp)) - else: - if out_temp.find('error') >= 0: - error_count += 1 - l_count -= 1 - del c_line[0] - if self.verbose: - print(" REC<{}: \"{}\"".format(l_count, out_temp)) - - self.stop_status_report_timer() - end_time = time.time() - is_run = False - - print("\nG-code streaming finished!") - print("Time elapsed: {}\n".format(end_time - start_time)) - - if self.check_mode: - if error_count > 0: - print("CHECK FAILED: {} errors found! See output for details.\n".format(error_count)) - else: - print("CHECK PASSED: No errors found in g-code program.\n") - else: - print("WARNING: Wait until Grbl completes buffered g-code blocks before exiting.") - - def start_status_report_timer(self): - if ENABLE_STATUS_REPORTS: - self.timerThread = threading.Thread(target=self.periodic_timer) - self.timerThread.daemon = True - self.timerThread.start() - - def stop_status_report_timer(self): - self.timerThread.join() - - def periodic_timer(self): - while is_run: - self.send_command('?') - time.sleep(REPORT_INTERVAL) - -if __name__ == '__main__': - import argparse - - parser = argparse.ArgumentParser(description='Stream g-code file to grbl.') - parser.add_argument('gcode_file', type=argparse.FileType('r'), help='g-code filename to be streamed') - parser.add_argument('device_file', help='serial device path') - parser.add_argument('-q', '--quiet', action='store_true', default=False, help='suppress output text') - parser.add_argument('-s', '--settings', action='store_true', default=False, help='settings write mode') - parser.add_argument('-c', '--check', action='store_true', default=False, help='stream in check mode') - args = parser.parse_args() - - grbl_controller = GrblController(args.device_file, not args.quiet, args.settings, args.check) - grbl_controller.open() - grbl_controller.send_gcode(args.gcode_file) - grbl_controller.close() diff --git a/modules.py b/modules.py deleted file mode 100644 index 443c3b1..0000000 --- a/modules.py +++ /dev/null @@ -1,315 +0,0 @@ -grbl = 0 -port = None -i = 10 -GCODE = 0 -gcode_to_stream = [] -countbuf = 0 -writebuffer_byPass = [] -writebuffer = [] -readbuffer = [] -AXIS = 'X' -states = {'M3': '0', 'M8': '0', 'M6': '0', 'G10': '0'} # Spindle, Coolant, Toolchange -dict_GCODE = {'G': '0', - 'X': '0', - 'Y': '0', - 'Z': '0', - 'I': '0', - 'J': '0', - 'F': '0' - } - -# GUI Main -buttonsize_x = 5 -buttonsize_y = 3 -increments = 0 -BORDER = 2 -freetosend = 1 - -# GUI Color Scheme -attention = 'red' -loaded = 'green' -cooling = 'blue' -toolchange = 'yellow' -standard = '#17223B' -feed = '#283B67' - - -def grblConnect2(): - global grbl - global port - - # Serial Connection - locations = ['/dev/ttyACM0', '/dev/ttyUSB0', '/dev/ttyUSB1', '/dev/ttyACM1', '/dev/ttyACM2', '/dev/ttyACM3', - '/dev/ttyS0', '/dev/ttyS1', '/dev/ttyS2', '/dev/ttyS3'] - - for device in locations: - try: - # print([comport.device for comport in serial.tools.list_ports.comports()]) - print("Trying...", device) - grbl = serial.Serial(port=device, baudrate=115200, timeout=.5) # dsrdtr= True) - port = device - # grbl.open() - # print(grbl.readline()) - grbl.write(str.encode("\r\n\r\n")) - time.sleep(2) # Wait for grbl to initialize - grbl.flushInput() # Flush startup text in serial input - connect_ser.config(bg=loaded) - # print("connected") - - break - except: - # print ("Failed to connect on",device) - grbl = 0 - - # Stream g-code to grbl - # Stream GCODE from -https://onehossshay.wordpress.com/2011/08/26/grbl-a-simple-python-interface/- - - -def jogWrite(AXIS, CMD, scale): # Schreiben von manuellen Positionierungsbefehlen - global freetosend - - DECIMAL = [0.1, 1, 10, 100] - scale = increments.get() - MOVE = int(CMD) * DECIMAL[scale - 1] - grbl_command = ('$J=G91' + 'G21' + AXIS + str(MOVE) + 'F1000') - # print(grbl_command) $J=G91G21X10F185 - grbl_gcode_send.send_gcode(grbl, grbl_command) - - -def switchButtonState(button): # Umschalter für Knopfstatus - if button["state"] == DISABLED: - button["state"] = NORMAL - else: - button["state"] = DISABLED - - -def directWrite(CMD): # Direktes schreiben eines Befehls - global freetosend - # print(freetosend) - grbl_command = CMD - - grbl_gcode_send.send_gcode(grbl, grbl_command) - - -def latchWrite(CMD): - global states - global freetosend - if states[CMD] == '0': - states[CMD] = '1' - if CMD == 'M3': - spindle.config(bg=attention) # A31621 - if CMD == 'M6': - tool.config(bg=toolchange) # E0CA3C - if CMD == 'G10': - zero_all.config(bg=loaded) - - else: - states[CMD] = '0' - if CMD == 'M3': - spindle.config(bg=loaded) # A2D729 - if CMD == 'M6': - tool.config(bg='grey') - # if CMD == 'G10': - # zero_all.config(bg= attention) - - if CMD == 'M3': - if states['M3'] == '1': - grbl_command = 'M3 S1000' - else: - grbl_command = 'M3 S0' - - elif CMD == 'M8': - if states['M8'] == '1': - grbl_command = (CMD) - coolant.config(bg=cooling) # 1F7A8C - else: - grbl_command = 'M9' - coolant.config(bg='grey') - - elif CMD == 'G10': - grbl_command = 'G10 P0 L20 X0 Y0 Z0' - - else: - grbl_command = (CMD) - - # grbl_command = (CMD * int(states[CMD]) ) - # print(grbl_command) - # print(states) - - grbl_gcode_send.send_gcode(grbl, grbl_command) - - -def terminalWrite(): # Holt Zeichenstring von Editfeld und sendet es - grbl_command = terminal.get() - # print(grbl_command) - - grbl_gcode_send.send_gcode(grbl, grbl_command) - - -def infoScreen(data): # Anzeigecanvas für GRBL Rückmeldungen - global i - terminalFrame = Frame(terminal_recv, bg='white') - terminal_recv.create_window(10, i, window=terminalFrame, anchor='nw') - Label(terminalFrame, text=data, font=('Calibri', 10), bg='white', fg='black').pack() - i += 22 - if i >= 400: - i = 10 - terminal_recv.delete("all") - - -def openGCODE(): # Dialog zur Gcode Auswahl und öffnen der Datei als GCODE Objekt - global gcode_to_stream - filetypes = (('GCODE', '*.nc'), ('All files', '*.*')) - GCODE = fd.askopenfile(title='Open a file', initialdir='/home/thomas/Nextcloud/CAM/', filetypes=filetypes) - - if GCODE != 0: - fopen.config(bg=loaded) - extracted = extract_GCODE(GCODE) - draw_GCODE(extracted) - gcode_to_stream = GCODE - - else: - fopen.config(bg='grey') - - # build_xy = findEnvelope() #Aufruf PLatz im Bauraum - # mill_table.create_rectangle(build_xy[0],build_xy[1], fill = 'blue', stipple = 'gray75') # Zeichnen des Objekts im Bauraum - - -def extract_GCODE(gcode: list): # Aufschlüsseln der enthaltenen Koordinaten in ein per Schlüssel zugängiges Dictionary - - list_dict_GCODE = [] - for line in gcode: - l = line.split() # Elemente trennen und in Liste konvertieren - for i in range(0, len(l)): - # print (l) - if 'G' in l[i]: - dict_GCODE['G'] = l[i].replace('G', '') # Wert einfügen und gleichzeitig G CODE befehl entfernen - if 'X' in l[i]: - dict_GCODE['X'] = l[i].replace('X', '') - if 'Y' in l[i]: - dict_GCODE['Y'] = l[i].replace('Y', '') - if 'Z' in l[i]: - dict_GCODE['Z'] = l[i].replace('Z', '') - if 'I' in l[i] and not 'ZMIN': - dict_GCODE['I'] = l[i].replace('I', '') - if 'J' in l[i]: - dict_GCODE['J'] = l[i].replace('J', '') - if 'F' in l[i] and not 'Fusion': - dict_GCODE['F'] = l[i].replace('F', '') - - # print(dict_GCODE) - list_dict_GCODE.append( - dict_GCODE.copy()) # Copy notwendig da es sich nur um einen "Pointer" handelt der immer auf die zuletzt aktualisierte dict Zeile zeigt. - print(list_dict_GCODE) - - return list_dict_GCODE - - -def draw_GCODE(glist): # Zeichnen des GCodes zur Beurteilung des Bauraums - - for i in range(0, len(glist) - 1): - x_y_current = 50 + float(glist[i]['X']), 350 - float(glist[i]['Y']) - x_y_next = 50 + float(glist[i + 1]['X']), 350 - float(glist[i + 1]['Y']) - - mill_table.create_line(x_y_current, x_y_next) - - -def writeToFileLog(log): # Log für Debugzwecke - with open("log.txt", 'a') as out: - out.write(log) - - -def displayPosition_request(grbl_pos): - if grbl != 0: - try: - position = str(grbl_pos) - # print (readbuffer) - - position = position.replace('Idle|', ',') - position = position.replace('Run|', ',') - position = position.replace('WPos:', '') - position = position.replace('MPos:', '') - position = position.replace('>', ',') - position = position.replace('|', ',') - position.strip() - coordinates_list = position.split(',') - # print(coordinates_list) - show_ctrl_x.config(text=coordinates_list[1]) - show_ctrl_y.config(text=coordinates_list[2]) - show_ctrl_z.config(text=coordinates_list[3]) - - mill_table.create_line(coordinates_list[1], coordinates_list[2], coordinates_list[1], - coordinates_list[2] + 50, arrow=FIRST) - - # show_ctrl_x_w.config(text = coordinates_list[4]) - # show_ctrl_y_w.config(text = coordinates_list[5]) - # show_ctrl_z_w.config(text = coordinates_list[6]) - - except: - pass - # print("Listerror") - - - else: - print("Serial Busy") - # root.after(1000,displayPosition) - - -def displayPosition(): - global readbuffer - if grbl != 0: - try: - position = str(readbuffer[2]) - # print (readbuffer) - - position = position.replace('Idle|', ',') - position = position.replace('Run|', ',') - position = position.replace('WPos:', '') - position = position.replace('MPos:', '') - position = position.replace('>', ',') - position = position.replace('|', ',') - position.strip() - coordinates_list = position.split(',') - # print(coordinates_list) - show_ctrl_x.config(text=coordinates_list[1]) - show_ctrl_y.config(text=coordinates_list[2]) - show_ctrl_z.config(text=coordinates_list[3]) - - mill_table.create_line(coordinates_list[1], coordinates_list[2], coordinates_list[1] + 10, - coordinates_list[2] + 20) - mill_table.create_line(coordinates_list[1], coordinates_list[2], coordinates_list[1] - 10, - coordinates_list[2] + 20) - mill_table.create_line(coordinates_list[1] - 10, coordinates_list[2] + 20, coordinates_list[1] + 10, - coordinates_list[2] + 20) - # show_ctrl_x_w.config(text = coordinates_list[4]) - # show_ctrl_y_w.config(text = coordinates_list[5]) - # show_ctrl_z_w.config(text = coordinates_list[6]) - - except: - pass - # print("Listerror") - - else: - print("Serial Busy") - # root.after(1000,displayPosition) - - -def grblWrite(): - if gcode_to_stream != None: - print("Stream", gcode_to_stream) - grbl_gcode_send.send_gcode(grbl, gcode_to_stream) - - # fdbk = grbl_gcode_send.send_gcode(grbl, line) - # print(fdbk) - grbl_gcode_send.wait_for_buffer_empty() - - -def grblClose(): - # Close file and serial port - # f.close() - try: - grbl.close() - print("closed") - connect_ser.config(bg='grey') - except: - print("Connection still open") \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..5702cc8 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +altgraph==0.17.4 +numpy==1.26.2 +pyserial==3.5