mirror of
				https://github.com/BKLronin/touchCNC.git
				synced 2025-10-31 22:39:42 +01:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
			ffcb93124c
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 0308d47967 | ||
|  | c11e5e1ba4 | ||
|  | 9f798791c5 | ||
|  | 1f20d7c79e | ||
|  | 63af178adf | ||
|  | 05f3b1dc45 | ||
|  | ce7b331b1e | ||
|  | f1ee9b8419 | 
							
								
								
									
										73
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,28 +1,73 @@ | |||||||
| # touchCNC | # touchCNC 1.0 | ||||||
| GRBL 1.1 CNC Controller for ODROID C2 with VU PLus Touch Screen | 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.  | Should run on any System wit at least 1024x600 Screen Resolution.  | ||||||
|  |  | ||||||
| - Jog  | - Jog  | ||||||
| - Zero positions  | - Zero positions  | ||||||
| - Job commands  | - Job commands  | ||||||
| - Spindle Coolant, Tool | - Spindle Coolant, Tool and Macro commands  | ||||||
| - Gcode milling envelope preview (low cpu usage),  | - Gcode milling envelope preview  | ||||||
| - G28 Position | - G28 Position | ||||||
| - Feed override (soon) | - Feed override (Not yet working) | ||||||
| - terminal | - terminal | ||||||
|  | - Laser status and switch | ||||||
|  |  | ||||||
|  |  | ||||||
|  | -  | ||||||
|  | - Tested on latest Armbian stable https://www.armbian.com/odroid-c2/#kernels-archive-all | ||||||
|  | - Tested on Manjaro  | ||||||
|  | - Using cncpro v3 with grbl1.1f | ||||||
|  |  | ||||||
|  | ## Clone to your PC | ||||||
|  | `git clone https://github.com/BKLronin/touchCNC.git` | ||||||
|  |  | ||||||
|  | ## Install  | ||||||
|  | - (Create env)   | ||||||
|  | - In folder enter:   | ||||||
|  | `pip install requirements.txt`   | ||||||
|  |  | ||||||
|  | ## Run  | ||||||
|  | `python cnc_gerbil.py`     | ||||||
|  | or     | ||||||
|  | `cd dist`   | ||||||
|  | `./cnc_gerbil`  (Bundled pyinstaller executable) | ||||||
|  |  | ||||||
|  | ## Settings | ||||||
|  | `nano settings.py`   | ||||||
|  | or any other editor to setup to your specific usecase, the options are: | ||||||
|  |  | ||||||
|  | - The resolution of your SBC-screen   | ||||||
|  | `resolution = '1024x600+0+0'` | ||||||
|  |  | ||||||
|  |  | ||||||
| Tested on latest Armbian stable https://www.armbian.com/odroid-c2/#kernels-archive-all | - When running on SBC with touch set to: True   | ||||||
|  | `set_fullscreen = False` | ||||||
|  |  | ||||||
| Based on |  | ||||||
| Python3 |  | ||||||
| tkinter |  | ||||||
| pyserial |  | ||||||
| gerbil |  | ||||||
| gcodemachine |  | ||||||
|  |  | ||||||
| In some cases you have to manually install tkinter via apt and pyserial via pip. | - Platform dependent com ports   | ||||||
|  | `portlist = ['/dev/ttyUSB0', '/dev/ttyACM0', '/dev/ttyUSB1', '/dev/ttyACM1', '/dev/ttyACM2', '/dev/ttyACM3', | ||||||
|  |                      '/dev/ttyS0', '/dev/ttyS1', '/dev/ttyS2', '/dev/ttyS3']` | ||||||
|  |    | ||||||
|  |  | ||||||
|  | - Where the file dialog points to. Ideally some Nextcloud folder or Samba share etc.   | ||||||
|  | `basepath = '/home/'` | ||||||
|  |  | ||||||
|  |    | ||||||
|  | - Machine commands   | ||||||
|  | `spindle_on = 'M3S1000'  `   | ||||||
|  | `spindle_off = 'M5'`   | ||||||
|  | `cooling_on = 'M8' `    | ||||||
|  | `cooling_off = 'M9'  `   | ||||||
|  | `toolchange = 'G10 P0 L20 X0 Y0 Z0'  `  | ||||||
|  |    | ||||||
|  |  | ||||||
|  | - Table Info Text   | ||||||
|  | `table_text = 'Fräsbereich 300mm x 300mm'` | ||||||
|  |  | ||||||
|  | ### Based on: | ||||||
|  | Python3   | ||||||
|  | tkinter   | ||||||
|  | pyserial   | ||||||
|  | gerbil   | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								Screen.png
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Screen.png
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 67 KiB | 
							
								
								
									
										474
									
								
								cnc.py
									
									
									
									
									
								
							
							
						
						
									
										474
									
								
								cnc.py
									
									
									
									
									
								
							| @@ -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="<RESET",width = buttonsize_x, height = buttonsize_y,command = lambda:directWrite(''),bg= 'grey' ) |  | ||||||
|  |  | ||||||
| reboot= Button(root,text="REBOOT",width = buttonsize_x, height = buttonsize_y,command = lambda: os.system('reboot'),bg= 'grey' ) |  | ||||||
|  |  | ||||||
| step_incr1 = Radiobutton(root, text= '0,1', value = 1 , variable = increments,width = buttonsize_x, height = buttonsize_y, indicatoron = 0 ) |  | ||||||
| step_incr2 = Radiobutton(root, text= '1', value = 2 , variable = increments,width = buttonsize_x, height = buttonsize_y, indicatoron = 0 ) |  | ||||||
| step_incr3 = Radiobutton(root, text= '10', value = 3 , variable = increments,width = buttonsize_x, height = buttonsize_y, indicatoron = 0 ) |  | ||||||
| step_incr4 = Radiobutton(root, text= '100', value = 4 , variable = increments,width = buttonsize_x, height = buttonsize_y, indicatoron = 0 ) |  | ||||||
| step_incr2.select() |  | ||||||
|  |  | ||||||
| terminal = Entry(root, width =8, text="GCODE") |  | ||||||
| terminal_send = Button(root, text="SEND",width = buttonsize_x, height = buttonsize_y, bd= 3, command = lambda: terminalWrite()) |  | ||||||
| terminal_recv = Canvas(root, width = 200, height =400, bg = 'white') |  | ||||||
|  |  | ||||||
| show_ctrl_x_label = Label(root,text = "X") |  | ||||||
| show_ctrl_y_label = Label(root,text = "Y") |  | ||||||
| show_ctrl_z_label = Label(root,text = "Z") |  | ||||||
| show_ctrl_x =Label(root, text = "X_POS", width = 8, height = 2, bg ='white', relief = SUNKEN, fg= 'black') |  | ||||||
| show_ctrl_y =Label(root, text = "Y_POS", width = 8, height = 2, bg ='white', relief = SUNKEN, fg= 'black') |  | ||||||
| show_ctrl_z =Label(root, text = "Z_POS", width = 8, height = 2, bg ='white', relief = SUNKEN, fg= 'black') |  | ||||||
|  |  | ||||||
| show_ctrl_x_w =Label(root, text = "X_POS_W", width = 8, height = 2, bg ='white', relief = SUNKEN, fg= 'black') |  | ||||||
| show_ctrl_y_w =Label(root, text = "Y_POS_W", width = 8, height = 2, bg ='white', relief = SUNKEN, fg= 'black') |  | ||||||
| show_ctrl_z_w =Label(root, text = "Z_POS_W", width = 8, height = 2, bg ='white', relief = SUNKEN, fg= 'black') |  | ||||||
|  |  | ||||||
| #feed_control = Scale(root, orient = HORIZONTAL, length = 400, label = "Feedrate",tickinterval = 20) |  | ||||||
|  |  | ||||||
| #Milling Area and Gcode preview with grid generation |  | ||||||
|  |  | ||||||
| mill_table= Canvas(root, width= 400, height = 400, bg = 'grey') |  | ||||||
|  |  | ||||||
| mill_table.create_rectangle(50,50,350,350, fill ='white') |  | ||||||
| mill_table.create_text(200,25,text = 'Fräsbereich 300mm x 300mm') |  | ||||||
|  |  | ||||||
| for x in range(50,350,50): |  | ||||||
|     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 = mill_table.create_line(x,0,x,400) |  | ||||||
|         gitter_y = mill_table.create_line(0,y,400,y) |  | ||||||
|  |  | ||||||
| movement.grid(row = 0, column = 0, columnspan = 3, rowspan = 1) |  | ||||||
| left.grid(row=1, column=0, padx=3, pady=2) |  | ||||||
| right.grid(row=1, column=2,padx=3, pady=2) |  | ||||||
| up.grid(row=0, column=1, padx=3, pady=10) |  | ||||||
| down.grid(row=1, column=1,padx=3, pady=2) |  | ||||||
| z_up.grid(row=0, column=3,padx=10, pady=10) |  | ||||||
| z_down.grid(row=1, column=3,padx=10, pady=2) |  | ||||||
|  |  | ||||||
| step_incr2.select() |  | ||||||
|  |  | ||||||
| step_incr1.grid(row=2, column=0,padx=3, pady=10) |  | ||||||
| step_incr2.grid(row=2, column=1,padx=3, pady=10) |  | ||||||
| step_incr3.grid(row=2, column=2,padx=3, pady=10) |  | ||||||
| step_incr4.grid(row=2, column=3,padx=3, pady=10) |  | ||||||
|  |  | ||||||
| show_ctrl_x_label.grid(row=3, column=0,padx=3, pady=10) |  | ||||||
| show_ctrl_y_label.grid(row=4, column=0,padx=3, pady=10) |  | ||||||
| show_ctrl_z_label.grid(row=5, column=0,padx=3, pady=10) |  | ||||||
|  |  | ||||||
| show_ctrl_x.grid(row=3, column=1,padx=0, pady=0, columnspan =1) |  | ||||||
| show_ctrl_y.grid(row=4, column=1,padx=0, pady=0, columnspan =1) |  | ||||||
| show_ctrl_z.grid(row=5, column=1,padx=0, pady=0, columnspan =1) |  | ||||||
|  |  | ||||||
| show_ctrl_x_w.grid(row=3, column=2,padx=0, pady=0, columnspan =1) |  | ||||||
| show_ctrl_y_w.grid(row=4, column=2,padx=0, pady=0, columnspan =1) |  | ||||||
| show_ctrl_z_w.grid(row=5, column=2,padx=0, pady=0, columnspan =1) |  | ||||||
|  |  | ||||||
| zero_x.grid(row=3, column=3) |  | ||||||
| zero_y.grid(row=4, column=3) |  | ||||||
| zero_z.grid(row=5, column=3) |  | ||||||
| zero_all.grid(row=6, column=3,padx=10, pady=10) |  | ||||||
|  |  | ||||||
| setzero.grid(row=6, column=0,padx=10, pady=10) |  | ||||||
| gozero.grid(row=6, column=1,padx=10, pady=10) |  | ||||||
|  |  | ||||||
| connect_ser.grid(row=7, column=0,padx=10, pady=10) |  | ||||||
| discon_ser.grid(row=7, column=1,padx=10, pady=10) |  | ||||||
| unlock.grid(row=8, column=1,padx=10, pady=10) |  | ||||||
| start.grid(row=7, column=2,padx=10, pady=10) |  | ||||||
| stop.grid(row=7, column=3,padx=10, pady=10) |  | ||||||
| pause.grid(row=8, column=2,padx=10, pady=10) |  | ||||||
| resume.grid(row=8, column=3,padx=10, pady=10) |  | ||||||
| fopen.grid(row=8, column=0,padx=10, pady=10) |  | ||||||
|  |  | ||||||
| spindle.grid(row=7, column=4,padx=1, pady=10) |  | ||||||
| coolant.grid(row=7, column=5,padx=1, pady=10) |  | ||||||
| tool.grid(row=7, column=6,padx=1, pady=10) |  | ||||||
| macro.grid(row=7, column=7,padx=1, pady=10) |  | ||||||
|  |  | ||||||
| dec10.grid(row=8, column=4,padx=1, pady=10) |  | ||||||
| dec1.grid(row=8, column=5,padx=1, pady=10) |  | ||||||
| inc1.grid(row=8, column=6,padx=1, pady=10) |  | ||||||
| inc10.grid(row=8, column=7,padx=1, pady=10) |  | ||||||
|  |  | ||||||
| reset.grid(row=8, column=8,padx=1, pady=10) |  | ||||||
| reboot.grid(row=8, column=9,padx=1, pady=10) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| terminal.grid(row = 7, column = 8, padx =2, pady =10) |  | ||||||
| terminal_send.grid(row = 7, column = 9, padx =2, pady =10) |  | ||||||
| terminal_recv.grid(row = 0, column = 8, padx =10, pady =10,rowspan = 7, columnspan =2) |  | ||||||
|  |  | ||||||
| #feed_control.grid(row = 8, column = 4, columnspan =4) |  | ||||||
|  |  | ||||||
| mill_table.grid(row=0, column=4,padx=10, pady=10,columnspan = 4, rowspan = 7) |  | ||||||
|  |  | ||||||
| #sendGRBL() |  | ||||||
|  |  | ||||||
| #BlockedButtons |  | ||||||
| blkbuttons = (up,down,left,right,z_up,z_down, zero_x, zero_y, zero_z, zero_all, setzero, gozero, spindle) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #timedPositionRequest() |  | ||||||
|    |  | ||||||
| root.mainloop() |  | ||||||
|  |  | ||||||
| @@ -3,7 +3,8 @@ import time | |||||||
| from tkinter import Button, Label, Variable, IntVar, Canvas, Frame, Listbox, Entry, Radiobutton, Tk, constants, LEFT | from tkinter import Button, Label, Variable, IntVar, Canvas, Frame, Listbox, Entry, Radiobutton, Tk, constants, LEFT | ||||||
| from tkinter import filedialog as fd | from tkinter import filedialog as fd | ||||||
| import os | import os | ||||||
| from gerbil.gerbil import Gerbil | from grbl_streamer import GrblStreamer | ||||||
|  | import settings | ||||||
|  |  | ||||||
| class touchCNC: | class touchCNC: | ||||||
|     def __init__(self, root): |     def __init__(self, root): | ||||||
| @@ -21,7 +22,7 @@ class touchCNC: | |||||||
|         self.increments = 0 |         self.increments = 0 | ||||||
|         self.BORDER = 2 |         self.BORDER = 2 | ||||||
|         self.feedspeed = None |         self.feedspeed = None | ||||||
|         self.states = {'M3': '0', 'M8': '0', 'M6': '0', 'G10': '0', '32' :0}  # self.spindle, Coolant, Toolchange |         self.states = {'M3': '0', 'M8': '0', 'M6': '0', 'G10': '0', '32' :'0'}  # self.spindle, Coolant, Toolchange | ||||||
|  |  | ||||||
|         self.dict_GCODE = {'G': '0', |         self.dict_GCODE = {'G': '0', | ||||||
|                       'X': '0', |                       'X': '0', | ||||||
| @@ -43,6 +44,14 @@ class touchCNC: | |||||||
|         self.feed = self.secondary |         self.feed = self.secondary | ||||||
|         self.transport = '#FA7921' |         self.transport = '#FA7921' | ||||||
|  |  | ||||||
|  |         # Classic Scheme | ||||||
|  |         attention = 'red' | ||||||
|  |         loaded = 'green' | ||||||
|  |         cooling = 'blue' | ||||||
|  |         toolchange = 'yellow' | ||||||
|  |         standard = '#17223B' | ||||||
|  |         feed = '#283B67' | ||||||
|  |  | ||||||
|         self.increments = IntVar() |         self.increments = IntVar() | ||||||
|         self.movement = Frame(root, relief='ridge', bd=self.BORDER, padx=10, pady=10) |         self.movement = Frame(root, relief='ridge', bd=self.BORDER, padx=10, pady=10) | ||||||
|  |  | ||||||
| @@ -305,8 +314,7 @@ class touchCNC: | |||||||
|  |  | ||||||
|     def grblConnect2(self, baudrate=115200, max_retries=5, retry_interval=3): |     def grblConnect2(self, baudrate=115200, max_retries=5, retry_interval=3): | ||||||
|         retry_count = 0 |         retry_count = 0 | ||||||
|         locations = ['/dev/ttyUSB0', '/dev/ttyACM0', '/dev/ttyUSB1', '/dev/ttyACM1', '/dev/ttyACM2', '/dev/ttyACM3', |         locations = settings.portlist | ||||||
|                      '/dev/ttyS0', '/dev/ttyS1', '/dev/ttyS2', '/dev/ttyS3'] |  | ||||||
|  |  | ||||||
|         # Configure logging |         # Configure logging | ||||||
|         logging.basicConfig(level=logging.DEBUG) |         logging.basicConfig(level=logging.DEBUG) | ||||||
| @@ -343,6 +351,7 @@ class touchCNC: | |||||||
|  |  | ||||||
|     def grblClose(self): |     def grblClose(self): | ||||||
|         grbl.softreset() |         grbl.softreset() | ||||||
|  |         print(grbl.connected) | ||||||
|         grbl.disconnect() |         grbl.disconnect() | ||||||
|         self.connect_ser.config(bg=self.secondary) |         self.connect_ser.config(bg=self.secondary) | ||||||
|  |  | ||||||
| @@ -400,13 +409,13 @@ class touchCNC: | |||||||
|  |  | ||||||
|     def get_grbl_command(self, CMD): |     def get_grbl_command(self, CMD): | ||||||
|         if CMD == 'M3': |         if CMD == 'M3': | ||||||
|             return 'M3 S1000' if self.states['M3'] == '1' else 'M5' |             return settings.spindle_on if self.states['M3'] == '1' else settings.spindle_off | ||||||
|  |  | ||||||
|         elif CMD == 'M8': |         elif CMD == 'M8': | ||||||
|             return CMD if self.states[CMD] == '1' else 'M9' |             return settings.cooling_on if self.states[CMD] == '1' else settings.cooling_off | ||||||
|  |  | ||||||
|         elif CMD == 'G10': |         elif CMD == 'G10': | ||||||
|             return 'G10 P0 L20 X0 Y0 Z0' |             return settings.toolchange | ||||||
|  |  | ||||||
|         elif CMD == '32': |         elif CMD == '32': | ||||||
|             return '$32=0' if self.states['32'] == '1' else '$32=1' |             return '$32=0' if self.states['32'] == '1' else '$32=1' | ||||||
| @@ -419,7 +428,7 @@ class touchCNC: | |||||||
|     def openGCODE(self): |     def openGCODE(self): | ||||||
|         filetypes = (('GCODE', '*.nc'), ('All files', '*.*')) |         filetypes = (('GCODE', '*.nc'), ('All files', '*.*')) | ||||||
|         if not self.file_list: |         if not self.file_list: | ||||||
|             GCODE = fd.askopenfilename(title='Open a file', initialdir='/home/', filetypes=filetypes) |             GCODE = fd.askopenfilename(title='Open a file', initialdir=settings.basepath, filetypes=filetypes) | ||||||
|         else: |         else: | ||||||
|             GCODE = self.load_gcode_from_listbox() |             GCODE = self.load_gcode_from_listbox() | ||||||
|  |  | ||||||
| @@ -462,7 +471,7 @@ class touchCNC: | |||||||
|     def openDir(self): |     def openDir(self): | ||||||
|         self.file_list = [] |         self.file_list = [] | ||||||
|         self.path_list = [] |         self.path_list = [] | ||||||
|         directory = fd.askdirectory(title='Open a Folder', initialdir='/home/') |         directory = fd.askdirectory(title='Open a Folder', initialdir=settings.basepath) | ||||||
|         allowed_extensions = {'nc', 'GCODE'}  # Use a set for efficient membership testing |         allowed_extensions = {'nc', 'GCODE'}  # Use a set for efficient membership testing | ||||||
|  |  | ||||||
|         if directory: |         if directory: | ||||||
| @@ -593,7 +602,7 @@ class DrawonTable: | |||||||
|         self.mill_table.delete('all') |         self.mill_table.delete('all') | ||||||
|  |  | ||||||
|         self.mill_table.create_rectangle(50, 50, 350, 350, fill='white') |         self.mill_table.create_rectangle(50, 50, 350, 350, fill='white') | ||||||
|         self.mill_table.create_text(200, 25, text='Fräsbereich 300mm x 300mm') |         self.mill_table.create_text(200, 25, text=settings.table_text) | ||||||
|  |  | ||||||
|         for x in range(50, 350, 50): |         for x in range(50, 350, 50): | ||||||
|             self.mill_table.create_text(x, 400 - x, text=x - 50) |             self.mill_table.create_text(x, 400 - x, text=x - 50) | ||||||
| @@ -607,16 +616,15 @@ class DrawonTable: | |||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|     root = Tk() |     root = Tk() | ||||||
|     root.title('touchCNC') |     root.title('touchCNC') | ||||||
|     root.geometry('1024x600+0+0') |     root.geometry(settings.resolution) | ||||||
|     root.grid_propagate(True) |     root.grid_propagate(True) | ||||||
|     root.resizable(False, False)  # 17203b |     root.resizable(False, False)  # 17203b | ||||||
|     root.attributes('-fullscreen', False) |     root.attributes('-fullscreen', settings.set_fullscreen) | ||||||
|     root.tk_setPalette(background='#4B4A67', foreground='black', activeBackground='#F99417', |     root.tk_setPalette(background='#4B4A67', foreground='black', activeBackground='#F99417', | ||||||
|                        activeForeground='lightgrey') |                        activeForeground='lightgrey') | ||||||
|  |  | ||||||
|  |  | ||||||
|     app = touchCNC(root) |     app = touchCNC(root) | ||||||
|     grbl = Gerbil(app.gui_callback) |     grbl = GrblStreamer(app.gui_callback) | ||||||
|     grbl.hash_state_requested = True |     grbl.hash_state_requested = True | ||||||
|     grbl.gcode_parser_state_requested = True |     grbl.gcode_parser_state_requested = True | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								dist/cnc_gerbil
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								dist/cnc_gerbil
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										22
									
								
								dist/settings.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								dist/settings.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  |  | ||||||
|  | # The resolution of your SBC-screen | ||||||
|  | resolution = '1024x600+0+0' | ||||||
|  |  | ||||||
|  | # When running on SBC with touch set to: True | ||||||
|  | set_fullscreen = False | ||||||
|  |  | ||||||
|  | # Platform dependent | ||||||
|  | portlist = ['/dev/ttyUSB0', '/dev/ttyACM0', '/dev/ttyUSB1', '/dev/ttyACM1', '/dev/ttyACM2', '/dev/ttyACM3', | ||||||
|  |                      '/dev/ttyS0', '/dev/ttyS1', '/dev/ttyS2', '/dev/ttyS3'] | ||||||
|  | # Where the file dialog points to. Ideally some Nextcloud folder or Samba share etc. | ||||||
|  | basepath = '/home/' | ||||||
|  |  | ||||||
|  | # Machine commands | ||||||
|  | spindle_on = 'M3S1000' | ||||||
|  | spindle_off = 'M5' | ||||||
|  | cooling_on = 'M8' | ||||||
|  | cooling_off = 'M9' | ||||||
|  | toolchange = 'G10 P0 L20 X0 Y0 Z0' | ||||||
|  |  | ||||||
|  | # Table Info Text | ||||||
|  | table_text = 'Fräsbereich 300mm x 300mm' | ||||||
 Submodule gcode_machine deleted from 624f71ae15
									
								
							
							
								
								
									
										1
									
								
								gerbil
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								gerbil
									
									
									
									
									
								
							 Submodule gerbil deleted from 78aa148f0a
									
								
							| @@ -1,55 +0,0 @@ | |||||||
| 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
									
									
									
									
									
								
							
							
						
						
									
										150
									
								
								grbl_stream.py
									
									
									
									
									
								
							| @@ -1,150 +0,0 @@ | |||||||
| 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
									
									
									
									
									
								
							
							
						
						
									
										315
									
								
								modules.py
									
									
									
									
									
								
							| @@ -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") |  | ||||||
							
								
								
									
										5
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | altgraph==0.17.4 | ||||||
|  | gcode-machine==1.0.3 | ||||||
|  | grbl-streamer==1.0.3 | ||||||
|  | numpy==1.26.2 | ||||||
|  | pyserial==3.5 | ||||||
							
								
								
									
										22
									
								
								settings.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								settings.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  |  | ||||||
|  | # The resolution of your SBC-screen | ||||||
|  | resolution = '1024x600+0+0' | ||||||
|  |  | ||||||
|  | # When running on SBC with touch set to: True | ||||||
|  | set_fullscreen = False | ||||||
|  |  | ||||||
|  | # Platform dependent | ||||||
|  | portlist = ['/dev/ttyUSB0', '/dev/ttyACM0', '/dev/ttyUSB1', '/dev/ttyACM1', '/dev/ttyACM2', '/dev/ttyACM3', | ||||||
|  |                      '/dev/ttyS0', '/dev/ttyS1', '/dev/ttyS2', '/dev/ttyS3'] | ||||||
|  | # Where the file dialog points to. Ideally some Nextcloud folder or Samba share etc. | ||||||
|  | basepath = '/home/' | ||||||
|  |  | ||||||
|  | # Machine commands | ||||||
|  | spindle_on = 'M3S1000' | ||||||
|  | spindle_off = 'M5' | ||||||
|  | cooling_on = 'M8' | ||||||
|  | cooling_off = 'M9' | ||||||
|  | toolchange = 'G10 P0 L20 X0 Y0 Z0' | ||||||
|  |  | ||||||
|  | # Table Info Text | ||||||
|  | table_text = 'Fräsbereich 300mm x 300mm' | ||||||
		Reference in New Issue
	
	Block a user