mirror of
				https://github.com/BKLronin/touchCNC.git
				synced 2025-10-30 13:59:41 +01:00 
			
		
		
		
	Initial implementation of gerbil
This commit is contained in:
		
							
								
								
									
										144
									
								
								cnc.py
									
									
									
									
									
								
							
							
						
						
									
										144
									
								
								cnc.py
									
									
									
									
									
								
							| @@ -5,10 +5,14 @@ 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 = [] | ||||
| @@ -41,6 +45,7 @@ feed = '#283B67' | ||||
|  | ||||
| def grblConnect2(): | ||||
|     global grbl | ||||
|     global port | ||||
|  | ||||
|     #Serial Connection | ||||
|     locations=['/dev/ttyACM0','/dev/ttyUSB0','/dev/ttyUSB1','/dev/ttyACM1','/dev/ttyACM2','/dev/ttyACM3', | ||||
| @@ -51,6 +56,7 @@ def grblConnect2(): | ||||
|                 #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")) | ||||
| @@ -75,11 +81,7 @@ def jogWrite(AXIS, CMD, scale): #Schreiben von manuellen Positionierungsbefehlen | ||||
|     MOVE = int(CMD) * DECIMAL[scale -1]      | ||||
|     grbl_command = ('$J=G91' + 'G21' + AXIS + str(MOVE)+ 'F1000')     | ||||
|     #print(grbl_command) $J=G91G21X10F185 | ||||
|     if freetosend == 1:  | ||||
|         byPass(grbl_command+'\n')         | ||||
|     else: | ||||
|         for button in blkbuttons: | ||||
|             switchButtonState(button) | ||||
|     grbl_gcode_send.send_gcode(grbl, grbl_command) | ||||
|  | ||||
| def switchButtonState(button): #Umschalter für Knopfstatus | ||||
|     if button["state"] == DISABLED: | ||||
| @@ -91,10 +93,9 @@ def directWrite(CMD): #Direktes schreiben eines Befehls | ||||
|     global freetosend | ||||
|     #print(freetosend) | ||||
|     grbl_command = CMD  | ||||
|     if freetosend == 0:            | ||||
|         now_bufferGRBL(grbl_command + '\n') | ||||
|     else: | ||||
|         byPass(grbl_command + '\n') | ||||
|  | ||||
|     grbl_gcode_send.send_gcode(grbl, grbl_command) | ||||
|  | ||||
|  | ||||
| def latchWrite(CMD): | ||||
|     global states  | ||||
| @@ -141,19 +142,16 @@ def latchWrite(CMD): | ||||
|     #print(grbl_command) | ||||
|     #print(states) | ||||
|      | ||||
|     if freetosend == 0: | ||||
|         now_bufferGRBL(grbl_command + '\n') | ||||
|     else: | ||||
|         byPass(grbl_command + '\n') | ||||
|     print(grbl_command) | ||||
|  | ||||
|     grbl_gcode_send.send_gcode(grbl, grbl_command) | ||||
|  | ||||
|  | ||||
| def terminalWrite(): #Holt Zeichenstring von Editfeld und sendet es | ||||
|     grbl_command = terminal.get() | ||||
|     #print(grbl_command) | ||||
|     if freetosend == 0:            | ||||
|         now_bufferGRBL(grbl_command + '\n') | ||||
|     else: | ||||
|         byPass(grbl_command+'\n') | ||||
|  | ||||
|     grbl_gcode_send.send_gcode(grbl, grbl_command) | ||||
|  | ||||
|  | ||||
| def infoScreen(data): #Anzeigecanvas für GRBL Rückmeldungen | ||||
|     global i | ||||
| @@ -166,14 +164,16 @@ def infoScreen(data): #Anzeigecanvas für GRBL Rückmeldungen | ||||
|         terminal_recv.delete("all") | ||||
|  | ||||
| def openGCODE(): #Dialog zur Gcode Auswahl und öffnen der Datei als GCODE Objekt | ||||
|     global GCODE | ||||
|  | ||||
|     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) | ||||
|         draw_GCODE(extract_GCODE()) | ||||
|         extracted = extract_GCODE(GCODE) | ||||
|         draw_GCODE(extracted) | ||||
|         gcode_to_stream = GCODE | ||||
|  | ||||
|     else: | ||||
|         fopen.config(bg = 'grey') | ||||
|       | ||||
| @@ -181,10 +181,10 @@ def openGCODE(): #Dialog zur Gcode Auswahl und öffnen der Datei als GCODE Objek | ||||
|     #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(): #Aufschlüsseln der enthaltenen Koordinaten in ein per Schlüssel zugängiges Dictionary | ||||
|     global dict_GCODE | ||||
| 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: | ||||
|     for line in gcode: | ||||
|         l = line.split() #Elemente trennen und in Liste konvertieren | ||||
|         for i in range(0,len(l)): | ||||
|             #print (l) | ||||
| @@ -218,86 +218,6 @@ def draw_GCODE(glist): #Zeichnen des GCodes zur Beurteilung des Bauraums | ||||
|         | ||||
|         mill_table.create_line(x_y_current, x_y_next) | ||||
|  | ||||
| def grblWrite():    | ||||
|     #print("write1") | ||||
|     global writebuffer | ||||
|      | ||||
|     GCODE.seek(0) | ||||
|                  | ||||
|     for line in GCODE:         | ||||
|         #print("write") | ||||
|         l = line.strip() # Strip all EOL characters for streaming         | ||||
|         grbl_command = l | ||||
|         #print("GCODE",grbl_command) | ||||
|         bufferGRBL(grbl_command + '\n')        | ||||
|     sendGRBL()        | ||||
|     GCODE.close() | ||||
|     for button in blkbuttons: #Ausgrauen blockierter Knöpfe während Fräsen. "Umschalter" | ||||
|             switchButtonState(button) | ||||
|     fopen.config(bg = 'grey') | ||||
|  | ||||
| def timedPositionRequest():# >Im Falle das kein GCODE gestreamed wird abfragen der momentanen Position nach 1000ms sendet über den "byPass" channel der den GCode Stream nicht beeinflusst | ||||
|     if grbl != 0 and freetosend == 1: | ||||
|         grbl_command = '?' | ||||
|         byPass(grbl_command) | ||||
|     root.after(1000, timedPositionRequest) | ||||
|  | ||||
| def bufferGRBL(grbl_command): | ||||
|     global writebuffer | ||||
|     writebuffer.append(grbl_command) | ||||
|     #print (len(writebuffer)) | ||||
|  | ||||
| def now_bufferGRBL(grbl_command): | ||||
|     global writebuffer | ||||
|     writebuffer.insert(1,grbl_command) | ||||
|     #print (len(writebuffer)) | ||||
|  | ||||
| def byPass(grbl_command): | ||||
|     global writebuffer_byPass | ||||
|     #print (grbl_command)  | ||||
|     if grbl_command == '?': | ||||
|         grbl.write(str.encode(grbl_command)) # Send g-code block to grbl | ||||
|         grbl_out = grbl.readline().strip() | ||||
|     else: | ||||
|         #print(grbl_command) | ||||
|         writebuffer_byPass.append(grbl_command) | ||||
|         grbl.write(str.encode(writebuffer_byPass[0])) # Send g-code block to grbl | ||||
|         grbl_out = grbl.readline().strip() | ||||
|         #print(writebuffer_byPass) | ||||
|         del writebuffer_byPass[0] | ||||
|     displayPosition_request(grbl_out) | ||||
|     infoScreen(grbl_out) | ||||
|     #print(grbl_out) | ||||
|  | ||||
| def debugWrite(grbl_command): | ||||
|     | ||||
|     grbl.write(str.encode(grbl_command)) # Send g-code block to grbl | ||||
|     grbl_out = grbl.readline().strip() | ||||
|     displayPosition_request(grbl_out) | ||||
|     infoScreen(grbl_out) | ||||
|     print(grbl_out) | ||||
|  | ||||
| def sendGRBL(): #Komplette Gcodes streamen senden | ||||
|     global writebuffer | ||||
|     global freetosend | ||||
|      | ||||
|     while len(writebuffer) >0: | ||||
|         freetosend = 0 | ||||
|         #print ("current",writebuffer[0]) | ||||
|         #print (writebuffer) | ||||
|         grbl.write(str.encode(writebuffer[0])) # Send g-code block to grbl | ||||
|         #writeToFileLog(writebuffer[0]) | ||||
|         #grbl.timeout = None     | ||||
|         readbuffer.append(grbl.readline().strip()) # Wait for grbl response with carriage return | ||||
|         del writebuffer[0] | ||||
|  | ||||
|         if len(readbuffer) == 5: | ||||
|             writebuffer.insert(2,'?' + '\n') #newline need? | ||||
|             displayPosition() | ||||
|             infoScreen(readbuffer[0]) | ||||
|             readbuffer.clear() | ||||
|     freetosend = 1 | ||||
|  | ||||
| def writeToFileLog(log): #Log für Debugzwecke | ||||
|     with open("log.txt", 'a') as out: | ||||
|         out.write(log) | ||||
| @@ -366,12 +286,20 @@ def displayPosition(): | ||||
|         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() | ||||
| @@ -385,8 +313,9 @@ def grblClose(): | ||||
| root = Tk() | ||||
| root.title('touchCNC') | ||||
| root.geometry('1024x600+0+0') | ||||
| root.geometry('1024x600+0+0') | ||||
| root.resizable(False,False)#17203b | ||||
| root.attributes('-fullscreen', True) | ||||
| root.attributes('-fullscreen', False) | ||||
| root.tk_setPalette(background='#11192C', foreground='white',activeBackground='#283867', activeForeground='white' ) | ||||
|  | ||||
| increments = IntVar() | ||||
| @@ -538,7 +467,8 @@ mill_table.grid(row=0, column=4,padx=10, pady=10,columnspan = 4, rowspan = 7) | ||||
| #BlockedButtons | ||||
| blkbuttons = (up,down,left,right,z_up,z_down, zero_x, zero_y, zero_z, zero_all, setzero, gozero, spindle) | ||||
|  | ||||
| timedPositionRequest() | ||||
|  | ||||
| #timedPositionRequest() | ||||
|    | ||||
| root.mainloop() | ||||
|  | ||||
|   | ||||
							
								
								
									
										423
									
								
								cnc_gerbil.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										423
									
								
								cnc_gerbil.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,423 @@ | ||||
| import serial | ||||
| import time | ||||
| from tkinter import * | ||||
| import serial.tools.list_ports | ||||
| from tkinter import filedialog as fd | ||||
| import os | ||||
| import threading | ||||
| from gerbil.gerbil import Gerbil | ||||
|  | ||||
|  | ||||
|  | ||||
| class touchCNC: | ||||
|     def __init__(self, root): | ||||
|         self.root = root | ||||
|  | ||||
|         # GUI Main | ||||
|         self.buttonsize_x = 5 | ||||
|         self.buttonsize_y = 3 | ||||
|         self.increments = 0 | ||||
|         self.BORDER = 2 | ||||
|         self.states = {'M3': '0', 'M8': '0', 'M6': '0', 'G10': '0'}  # self.spindle, Coolant, Toolchange | ||||
|  | ||||
|         self.dict_GCODE = {'G': '0', | ||||
|                       'X': '0', | ||||
|                       'Y': '0', | ||||
|                       'Z': '0', | ||||
|                       'I': '0', | ||||
|                       'J': '0', | ||||
|                       'F': '0' | ||||
|                       } | ||||
|  | ||||
|         # GUI Color Scheme | ||||
|         self.attention = 'red' | ||||
|         self.loaded = 'green' | ||||
|         self.cooling = 'blue' | ||||
|         self.toolchange = 'yellow' | ||||
|         self.standard = '#17223B' | ||||
|         self.feed = '#283B67' | ||||
|  | ||||
|         self.increments = IntVar() | ||||
|         self.movement = Frame(root, relief='ridge', bd=self.BORDER) | ||||
|         self.left = Button(root, text="-X", width=self.buttonsize_x, height=self.buttonsize_y, | ||||
|                       command=lambda: self.jogWrite('X', '-1', self.increments), bd=self.BORDER, bg=self.standard) | ||||
|         self.right = Button(root, text="+X", width=self.buttonsize_x, height=self.buttonsize_y, | ||||
|                        command=lambda: self.jogWrite('X', '1', self.increments), bd=self.BORDER, bg=self.standard) | ||||
|         self.up = Button(root, text="+Y", width=self.buttonsize_x, height=self.buttonsize_y, | ||||
|                     command=lambda: self.jogWrite('Y', '1', self.increments), bd=self.BORDER, bg=self.standard) | ||||
|         self.down = Button(root, text="-Y", width=self.buttonsize_x, height=self.buttonsize_y, | ||||
|                       command=lambda: self.jogWrite('Y', '-1', self.increments), bd=self.BORDER, bg=self.standard) | ||||
|         self.z_up = Button(root, text="+Z", width=self.buttonsize_x, height=self.buttonsize_y, | ||||
|                       command=lambda: self.jogWrite('Z', '1', self.increments), bd=self.BORDER, bg=self.standard) | ||||
|         self.z_down = Button(root, text="-Z", width=self.buttonsize_x, height=self.buttonsize_y, | ||||
|                         command=lambda: self.jogWrite('Z', '-1', self.increments), bd=self.BORDER, bg=self.standard) | ||||
|  | ||||
|         self.zero_x = Button(root, text="zero X", width=self.buttonsize_x, height=1, command=lambda: self.directWrite('G10 P0 L20 X0'), | ||||
|                         bd=self.BORDER) | ||||
|         self.zero_y = Button(root, text="zero Y", width=self.buttonsize_x, height=1, command=lambda: self.directWrite('G10 P0 L20 Y0'), | ||||
|                         bd=self.BORDER) | ||||
|         self.zero_z = Button(root, text="zero Z", width=self.buttonsize_x, height=1, command=lambda: self.directWrite('G10 P0 L20 Z0'), | ||||
|                         bd=self.BORDER) | ||||
|         self.zero_all = Button(root, text="zeroAll", width=self.buttonsize_x, height=3, command=lambda: self.latchWrite('G10'), | ||||
|                           bd=self.BORDER, bg='magenta') | ||||
|  | ||||
|         self.setzero = Button(root, text="SetPOS", width=self.buttonsize_x, height=self.buttonsize_y, | ||||
|                          command=lambda: self.directWrite('G28.1'), bd=self.BORDER) | ||||
|         self.gozero = Button(root, text="GoPOS", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.directWrite('G28'), | ||||
|                         bd=self.BORDER) | ||||
|  | ||||
|         self.connect_ser = Button(root, text="Cnnct", width=self.buttonsize_x, height=self.buttonsize_y, | ||||
|                                   command=self.grblConnect2, bg='grey', bd=self.BORDER) | ||||
|         self.discon_ser = Button(root, text="Dsconct", width=self.buttonsize_x, height=self.buttonsize_y, command= self.grblClose, | ||||
|                             bd=self.BORDER) | ||||
|         self.unlock = Button(root, text="Unlock", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.directWrite('$X'), | ||||
|                         bd=self.BORDER) | ||||
|         self.start = Button(root, text="START", width=self.buttonsize_x, height=self.buttonsize_y, bg=self.attention, | ||||
|                        command=self.grblWrite, bd=self.BORDER) | ||||
|         self.stop = Button(root, text="STOP", width=self.buttonsize_x, height=self.buttonsize_y, bd=self.BORDER, | ||||
|                       command=self.grblStop) | ||||
|         self.pause = Button(root, text="PAUSE", width=self.buttonsize_x, height=self.buttonsize_y, bg=self.cooling, bd=self.BORDER, | ||||
|                        command=self.grblPause) | ||||
|         self.resume = Button(root, text="RESUME", width=self.buttonsize_x, height=self.buttonsize_y, bd=self.BORDER, | ||||
|                         command=lambda: self.directWrite('~')) | ||||
|  | ||||
|         self.fopen = Button(root, text="GCODE", width=self.buttonsize_x, height=self.buttonsize_y, bg='grey', fg='black', | ||||
|                        command=self.openGCODE, bd=self.BORDER) | ||||
|  | ||||
|         self.spindle = Button(root, text="Spindle", width=self.buttonsize_x, height=self.buttonsize_y, | ||||
|                          command=lambda: self.latchWrite('M3')) | ||||
|         self.coolant = Button(root, text="Coolant", width=self.buttonsize_x, height=self.buttonsize_y, | ||||
|                          command=lambda: self.latchWrite('M8')) | ||||
|         self.tool = Button(root, text="Tool", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.latchWrite('M6')) | ||||
|         self.macro = Button(root, text="Macro1", width=self.buttonsize_x, height=self.buttonsize_y, | ||||
|                        command=lambda: self.directWrite(' G91 G0 X10 Y10 Z50 F1000')) | ||||
|  | ||||
|         self.inc1 = Button(root, text="Inc 1%", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.directWrite('‘'), | ||||
|                       bg=self.feed) | ||||
|         self.inc10 = Button(root, text="Inc 10%", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.directWrite('“'), | ||||
|                        bg=self.feed) | ||||
|         self.dec1 = Button(root, text="Dec 1%", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.directWrite('”'), | ||||
|                       bg=self.feed) | ||||
|         self.dec10 = Button(root, text="Dec 10%", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.directWrite('’'), | ||||
|                        bg=self.feed) | ||||
|         self.reset = Button(root, text="<RESET", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.directWrite(''), | ||||
|                        bg='grey') | ||||
|  | ||||
|         self.reboot = Button(root, text="REBOOT", width=self.buttonsize_x, height=self.buttonsize_y, | ||||
|                         command=lambda: os.system('reboot'), bg='grey') | ||||
|  | ||||
|         self.step_incr1 = Radiobutton(root, text='0,1', value=1, variable=self.increments, width=self.buttonsize_x, | ||||
|                                  height=self.buttonsize_y, indicatoron=0) | ||||
|         self.step_incr2 = Radiobutton(root, text='1', value=2, variable=self.increments, width=self.buttonsize_x, height=self.buttonsize_y, | ||||
|                                  indicatoron=0) | ||||
|         self.step_incr3 = Radiobutton(root, text='10', value=3, variable=self.increments, width=self.buttonsize_x, height=self.buttonsize_y, | ||||
|                                  indicatoron=0) | ||||
|         self.step_incr4 = Radiobutton(root, text='100', value=4, variable=self.increments, width=self.buttonsize_x, | ||||
|                                  height=self.buttonsize_y, indicatoron=0) | ||||
|         self.step_incr2.select() | ||||
|  | ||||
|         self.terminal = Entry(root, width=8, text="GCODE") | ||||
|         self.terminal_send = Button(root, text="SEND", width=self.buttonsize_x, height=self.buttonsize_y, bd=3, | ||||
|                                command=lambda: terminalWrite()) | ||||
|         self.terminal_recv = Canvas(root, width=200, height=400, bg='white') | ||||
|  | ||||
|         self.show_ctrl_x_label = Label(root, text="X") | ||||
|         self.show_ctrl_y_label = Label(root, text="Y") | ||||
|         self.show_ctrl_z_label = Label(root, text="Z") | ||||
|         self.show_ctrl_x = Label(root, text="X_POS", width=8, height=2, bg='white', relief=SUNKEN, fg='black') | ||||
|         self.show_ctrl_y = Label(root, text="Y_POS", width=8, height=2, bg='white', relief=SUNKEN, fg='black') | ||||
|         self.show_ctrl_z = Label(root, text="Z_POS", width=8, height=2, bg='white', relief=SUNKEN, fg='black') | ||||
|  | ||||
|         self.show_ctrl_x_w = Label(root, text="X_POS_W", width=8, height=2, bg='white', relief=SUNKEN, fg='black') | ||||
|         self.show_ctrl_y_w = Label(root, text="Y_POS_W", width=8, height=2, bg='white', relief=SUNKEN, fg='black') | ||||
|         self.show_ctrl_z_w = Label(root, text="Z_POS_W", width=8, height=2, bg='white', relief=SUNKEN, fg='black') | ||||
|  | ||||
|         # self.feed_control = Scale(root, orient = HORIZONTAL, length = 400, label = "self.feedrate",tickinterval = 20) | ||||
|  | ||||
|         # Milling Area and Gcode preview with grid generation | ||||
|  | ||||
|         self.mill_table = Canvas(root, width=400, height=400, bg='grey') | ||||
|  | ||||
|         self.mill_table.create_rectangle(50, 50, 350, 350, fill='white') | ||||
|         self.mill_table.create_text(200, 25, text='Fräsbereich 300mm x 300mm') | ||||
|  | ||||
|         for x in range(50, 350, 50): | ||||
|             self.mill_table.create_text(x, 400 - x, text=x - 50) | ||||
|  | ||||
|         for x in range(0, 400, 50): | ||||
|             for y in range(0, 400, 50): | ||||
|                 gitter_x = self.mill_table.create_line(x, 0, x, 400) | ||||
|                 gitter_y = self.mill_table.create_line(0, y, 400, y) | ||||
|  | ||||
|         self.movement.grid(row=0, column=0, columnspan=3, rowspan=1) | ||||
|         self.left.grid(row=1, column=0, padx=3, pady=2) | ||||
|         self.right.grid(row=1, column=2, padx=3, pady=2) | ||||
|         self.up.grid(row=0, column=1, padx=3, pady=10) | ||||
|         self.down.grid(row=1, column=1, padx=3, pady=2) | ||||
|         self.z_up.grid(row=0, column=3, padx=10, pady=10) | ||||
|         self.z_down.grid(row=1, column=3, padx=10, pady=2) | ||||
|  | ||||
|         self.step_incr2.select() | ||||
|  | ||||
|         self.step_incr1.grid(row=2, column=0, padx=3, pady=10) | ||||
|         self.step_incr2.grid(row=2, column=1, padx=3, pady=10) | ||||
|         self.step_incr3.grid(row=2, column=2, padx=3, pady=10) | ||||
|         self.step_incr4.grid(row=2, column=3, padx=3, pady=10) | ||||
|  | ||||
|         self.show_ctrl_x_label.grid(row=3, column=0, padx=3, pady=10) | ||||
|         self.show_ctrl_y_label.grid(row=4, column=0, padx=3, pady=10) | ||||
|         self.show_ctrl_z_label.grid(row=5, column=0, padx=3, pady=10) | ||||
|  | ||||
|         self.show_ctrl_x.grid(row=3, column=1, padx=0, pady=0, columnspan=1) | ||||
|         self.show_ctrl_y.grid(row=4, column=1, padx=0, pady=0, columnspan=1) | ||||
|         self.show_ctrl_z.grid(row=5, column=1, padx=0, pady=0, columnspan=1) | ||||
|  | ||||
|         self.show_ctrl_x_w.grid(row=3, column=2, padx=0, pady=0, columnspan=1) | ||||
|         self.show_ctrl_y_w.grid(row=4, column=2, padx=0, pady=0, columnspan=1) | ||||
|         self.show_ctrl_z_w.grid(row=5, column=2, padx=0, pady=0, columnspan=1) | ||||
|  | ||||
|         self.zero_x.grid(row=3, column=3) | ||||
|         self.zero_y.grid(row=4, column=3) | ||||
|         self.zero_z.grid(row=5, column=3) | ||||
|         self.zero_all.grid(row=6, column=3, padx=10, pady=10) | ||||
|  | ||||
|         self.setzero.grid(row=6, column=0, padx=10, pady=10) | ||||
|         self.gozero.grid(row=6, column=1, padx=10, pady=10) | ||||
|  | ||||
|         self.connect_ser.grid(row=7, column=0, padx=10, pady=10) | ||||
|         self.discon_ser.grid(row=7, column=1, padx=10, pady=10) | ||||
|         self.unlock.grid(row=8, column=1, padx=10, pady=10) | ||||
|         self.start.grid(row=7, column=2, padx=10, pady=10) | ||||
|         self.stop.grid(row=7, column=3, padx=10, pady=10) | ||||
|         self.pause.grid(row=8, column=2, padx=10, pady=10) | ||||
|         self.resume.grid(row=8, column=3, padx=10, pady=10) | ||||
|         self.fopen.grid(row=8, column=0, padx=10, pady=10) | ||||
|  | ||||
|         self.spindle.grid(row=7, column=4, padx=1, pady=10) | ||||
|         self.coolant.grid(row=7, column=5, padx=1, pady=10) | ||||
|         self.tool.grid(row=7, column=6, padx=1, pady=10) | ||||
|         self.macro.grid(row=7, column=7, padx=1, pady=10) | ||||
|  | ||||
|         self.dec10.grid(row=8, column=4, padx=1, pady=10) | ||||
|         self.dec1.grid(row=8, column=5, padx=1, pady=10) | ||||
|         self.inc1.grid(row=8, column=6, padx=1, pady=10) | ||||
|         self.inc10.grid(row=8, column=7, padx=1, pady=10) | ||||
|  | ||||
|         self.reset.grid(row=8, column=8, padx=1, pady=10) | ||||
|         self.reboot.grid(row=8, column=9, padx=1, pady=10) | ||||
|  | ||||
|         self.terminal.grid(row=7, column=8, padx=2, pady=10) | ||||
|         self.terminal_send.grid(row=7, column=9, padx=2, pady=10) | ||||
|         self.terminal_recv.grid(row=0, column=8, padx=10, pady=10, rowspan=7, columnspan=2) | ||||
|  | ||||
|         # self.feed_control.grid(row = 8, column = 4, columnspan =4) | ||||
|  | ||||
|         self.mill_table.grid(row=0, column=4, padx=10, pady=10, columnspan=4, rowspan=7) | ||||
|  | ||||
|         # sendGRBL() | ||||
|  | ||||
|         # BlockedButtons | ||||
|         self.blkbuttons = (self.up, self.down, self.left, self.right, self.z_up, self.z_down, self.zero_x, self.zero_y, | ||||
|                            self.zero_z, self.zero_all, self.setzero, self.gozero, self.spindle) | ||||
|         # Initialize the counter | ||||
|  | ||||
|  | ||||
|     def on_zero_position(self, label, pos): | ||||
|         print("Updated", pos) | ||||
|         label.config(text=pos) | ||||
|  | ||||
|     def gui_callback(self, eventstring, *data): | ||||
|         args = [] | ||||
|         print(data) | ||||
|         for d in data: | ||||
|             args.append(str(d)) | ||||
|         print("GUI CALLBACK: event={} data={}".format(eventstring.ljust(30), ", ".join(args))) | ||||
|  | ||||
|         if eventstring == "on_stateupdate": | ||||
|             print("stateupdate") | ||||
|             self.on_zero_position(self.show_ctrl_x, data[0]) | ||||
|         if eventstring == "on_hash_stateupdate": | ||||
|             print("args", type(data[0])) | ||||
|  | ||||
|             self.displayWorkPosition(data[0]["G28"]) | ||||
|  | ||||
|     def grblConnect2(self): | ||||
|         grbl.cnect("/dev/ttyUSB0", 115200)  # or /dev/ttyACM0 | ||||
|         if grbl.connected: | ||||
|             grbl.poll_start() | ||||
|         else: | ||||
|             print("wtf") | ||||
|  | ||||
|     def displayToolPosition(self): | ||||
|         print("update") | ||||
|         self.show_ctrl_x.config(text=grbl.cmpos[0]) | ||||
|         self.show_ctrl_y.config(text=grbl.cmpos[1]) | ||||
|         self.show_ctrl_z.config(text=grbl.cmpos[2]) | ||||
|         #self.root.after(1000, self.getPosition) | ||||
|  | ||||
|     def displayWorkPosition(self, pos: list): | ||||
|         print("update", pos) | ||||
|         self.show_ctrl_x_w.config(text = pos[0]) | ||||
|         self.show_ctrl_y_w.config(text = pos[1]) | ||||
|         self.show_ctrl_z_w.config(text = pos[2]) | ||||
|         #self.root.after(1000, self.getPosition) | ||||
|  | ||||
|     def jogWrite(self, axis, cmd, scale): | ||||
|         DECIMAL = [0.1, 1, 10, 100] | ||||
|         scale = self.increments.get() | ||||
|         MOVE = int(cmd) * DECIMAL[scale - 1] | ||||
|         grbl_command = ('$J=G91' + 'G21' + axis + str(MOVE) + 'F1000') | ||||
|         # print(grbl_command) $J=G91G21X10F185 | ||||
|  | ||||
|         grbl.send_immediately(grbl_command) | ||||
|  | ||||
|     def directWrite(self,cmd): | ||||
|         grbl.send_immediately(cmd) | ||||
|  | ||||
|     def latchWrite(self, CMD):         | ||||
|          | ||||
|         if self.states[CMD] == '0': | ||||
|             self.states[CMD] = '1' | ||||
|             if CMD == 'M3': | ||||
|                 self.spindle.config(bg=self.attention)  # A31621 | ||||
|             if CMD == 'M6': | ||||
|                 self.tool.config(bg=self.toolchange)  # E0CA3C | ||||
|             if CMD == 'G10': | ||||
|                 self.zero_all.config(bg=self.loaded) | ||||
|  | ||||
|         else: | ||||
|             self.states[CMD] = '0' | ||||
|             if CMD == 'M3': | ||||
|                 self.spindle.config(bg=self.loaded)  # A2D729 | ||||
|             if CMD == 'M6': | ||||
|                 self.tool.config(bg='grey') | ||||
|             # if CMD == 'G10': | ||||
|             #    zero_all.config(bg= attention) | ||||
|  | ||||
|         if CMD == 'M3': | ||||
|             if self.states['M3'] == '1': | ||||
|                 grbl_command = 'M3 S1000' | ||||
|             else: | ||||
|                 grbl_command = 'M3 S0' | ||||
|  | ||||
|         elif CMD == 'M8': | ||||
|             if self.states['M8'] == '1': | ||||
|                 grbl_command = (CMD) | ||||
|                 self.coolant.config(bg=self.cooling)  # 1F7A8C | ||||
|             else: | ||||
|                 grbl_command = 'M9' | ||||
|                 self.coolant.config(bg='grey') | ||||
|  | ||||
|         elif CMD == 'G10': | ||||
|             grbl_command = 'G10 P0 L20 X0 Y0 Z0' | ||||
|  | ||||
|         else: | ||||
|             grbl_command = (CMD) | ||||
|  | ||||
|             # grbl_command = (CMD * int(self.[CMD]) )    | ||||
|         # print(grbl_command) | ||||
|         # print(self.) | ||||
|  | ||||
|         grbl.send_immediately(grbl_command) | ||||
|  | ||||
|     def overrideCMD(self,cmd): | ||||
|         pass | ||||
|         #grbl. | ||||
|  | ||||
|     def openGCODE(self): | ||||
|         filetypes = (('GCODE', '*.nc'), ('All files', '*.*')) | ||||
|         GCODE = fd.askopenfilename(title='Open a file', initialdir='/home/thomas/Nextcloud/CAM/', filetypes=filetypes) | ||||
|  | ||||
|         if GCODE != 0: | ||||
|             self.fopen.config(bg=self.loaded) | ||||
|             extracted = self.extract_GCODE(GCODE) | ||||
|             self.draw_GCODE(extracted) | ||||
|             grbl.load_file(GCODE) | ||||
|  | ||||
|         else: | ||||
|             self.fopen.config(bg='grey') | ||||
|  | ||||
|     def grblWrite(self): | ||||
|         grbl.job_run() | ||||
|     def grblStop(self): | ||||
|         grbl.abort() | ||||
|  | ||||
|     def grblPause(self): | ||||
|         grbl.hold() | ||||
|  | ||||
|     def extract_GCODE(self, gcode_path: str):  # Aufschlüsseln der enthaltenen Koordinaten in ein per Schlüssel zugängiges Dictionary | ||||
|         with open(gcode_path, 'r') as gcode: | ||||
|             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]: | ||||
|                         self.dict_GCODE['G'] = l[i].replace('G', | ||||
|                                                        '')  # Wert einfügen und gleichzeitig G CODE befehl entfernen | ||||
|                     if 'X' in l[i]: | ||||
|                         self.dict_GCODE['X'] = l[i].replace('X', '') | ||||
|                     if 'Y' in l[i]: | ||||
|                         self.dict_GCODE['Y'] = l[i].replace('Y', '') | ||||
|                     if 'Z' in l[i]: | ||||
|                         self.dict_GCODE['Z'] = l[i].replace('Z', '') | ||||
|                     if 'I' in l[i] and not 'ZMIN': | ||||
|                         self.dict_GCODE['I'] = l[i].replace('I', '') | ||||
|                     if 'J' in l[i]: | ||||
|                         self.dict_GCODE['J'] = l[i].replace('J', '') | ||||
|                     if 'F' in l[i] and not 'Fusion': | ||||
|                         self.dict_GCODE['F'] = l[i].replace('F', '') | ||||
|  | ||||
|                         # print(dict_GCODE) | ||||
|                 list_dict_GCODE.append( | ||||
|                     self.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 drawgridTable(self): | ||||
|  | ||||
|         self.mill_table.create_rectangle(50, 50, 350, 350, fill='white') | ||||
|         self.mill_table.create_text(200, 25, text='Fräsbereich 300mm x 300mm') | ||||
|  | ||||
|         for x in range(50, 350, 50): | ||||
|             self.mill_table.create_text(x, 400 - x, text=x - 50) | ||||
|  | ||||
|         for x in range(0, 400, 50): | ||||
|             for y in range(0, 400, 50): | ||||
|                 gitter_x = self.mill_table.create_line(x, 0, x, 400) | ||||
|                 gitter_y = self.mill_table.create_line(0, y, 400, y) | ||||
|  | ||||
|     def draw_GCODE(self, glist):  # Zeichnen des GCodes zur Beurteilung des Bauraums | ||||
|         self.mill_table.delete('all') | ||||
|         self.drawgridTable() | ||||
|  | ||||
|         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']) | ||||
|  | ||||
|             self.mill_table.create_line(x_y_current, x_y_next) | ||||
|  | ||||
|     def grblClose(self): | ||||
|         grbl.disconnect() | ||||
|  | ||||
|  | ||||
|     print("test") | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     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') | ||||
|  | ||||
|     app = touchCNC(root) | ||||
|     grbl = Gerbil(app.gui_callback) | ||||
|     grbl.setup_logging() | ||||
|     grbl.hash_state_requested = True | ||||
|     grbl.gcode_parser_state_requested = True | ||||
|  | ||||
|     root.mainloop() | ||||
							
								
								
									
										55
									
								
								grbl_gcode_send.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								grbl_gcode_send.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| import serial | ||||
| import time | ||||
|  | ||||
| # Define the serial port and baud rate for communication | ||||
| ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1) | ||||
|  | ||||
| # Function to send G-code commands | ||||
| def send_gcode(ser, command): | ||||
|     # Split the command into chunks of 120 characters or less | ||||
|     chunks = [command[i:i + 120] for i in range(0, len(command), 120)] | ||||
|  | ||||
|     for chunk in chunks: | ||||
|         ser.write((chunk + '\n').encode()) | ||||
|         response = ser.readline().decode().strip() | ||||
|         if response != 'ok': | ||||
|             # Handle errors or unexpected responses here | ||||
|             print(f"GRBL response: {response}") | ||||
|  | ||||
| # Function to wait until the buffer is empty | ||||
| def wait_for_buffer_empty(): | ||||
|     while True: | ||||
|         status = send_gcode('?') | ||||
|         if status.startswith('<Idle'): | ||||
|             break | ||||
|         time.sleep(0.1) | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|  | ||||
|     # Your G-code commands | ||||
|     gcode_commands = [ | ||||
|         'G21',          # Set units to millimeters | ||||
|         'G90',          # Set to absolute positioning | ||||
|         'G1 X10 Y10 F100',  # Move to X10 Y10 at a feed rate of 100 mm/min | ||||
|         'G1 X20 Y20 F100', | ||||
|     ] | ||||
|  | ||||
|     try: | ||||
|         # Initialize communication | ||||
|  | ||||
|         #ser.open() | ||||
|         ser.flushInput() | ||||
|         ser.flushOutput() | ||||
|  | ||||
|         # Send G-code commands | ||||
|         for command in gcode_commands: | ||||
|             send_gcode(command) | ||||
|  | ||||
|         # Wait for the buffer to empty | ||||
|         wait_for_buffer_empty() | ||||
|  | ||||
|     except Exception as e: | ||||
|         print(f"An error occurred: {str(e)}") | ||||
|  | ||||
|     finally: | ||||
|         ser.close() | ||||
							
								
								
									
										150
									
								
								grbl_stream.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								grbl_stream.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,150 @@ | ||||
| import serial | ||||
| import re | ||||
| import time | ||||
| import threading | ||||
|  | ||||
| RX_BUFFER_SIZE = 128 | ||||
| BAUD_RATE = 115200 | ||||
| ENABLE_STATUS_REPORTS = True | ||||
| REPORT_INTERVAL = 1.0  # seconds | ||||
|  | ||||
| is_run = True  # Controls query timer | ||||
|  | ||||
| class GrblController: | ||||
|     def __init__(self, device_file, verbose=True, settings_mode=False, check_mode=False): | ||||
|         self.ser = serial.Serial(device_file, BAUD_RATE) | ||||
|         self.verbose = verbose | ||||
|         self.settings_mode = settings_mode | ||||
|         self.check_mode = check_mode | ||||
|         self.timerThread = None | ||||
|  | ||||
|     def open(self): | ||||
|         self.ser.open() | ||||
|         self.ser.flushInput() | ||||
|         self.ser.flushOutput() | ||||
|         time.sleep(2) | ||||
|         self.ser.flushInput() | ||||
|         if self.check_mode: | ||||
|             self.set_check_mode() | ||||
|  | ||||
|     def close(self): | ||||
|         self.ser.close() | ||||
|  | ||||
|     def set_check_mode(self): | ||||
|         self.send_command("$C\n") | ||||
|         while True: | ||||
|             grbl_out = self.ser.readline().strip() | ||||
|             if grbl_out.find('error') >= 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() | ||||
							
								
								
									
										315
									
								
								modules.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										315
									
								
								modules.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,315 @@ | ||||
| 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") | ||||
		Reference in New Issue
	
	Block a user