mirror of
https://github.com/BKLronin/touchCNC.git
synced 2024-12-30 10:34:01 +01:00
Compare commits
6 Commits
ffcb93124c
...
9f798791c5
Author | SHA1 | Date | |
---|---|---|---|
|
9f798791c5 | ||
|
1f20d7c79e | ||
|
63af178adf | ||
|
05f3b1dc45 | ||
|
ce7b331b1e | ||
|
f1ee9b8419 |
41
README.md
41
README.md
@ -1,28 +1,41 @@
|
||||
# touchCNC
|
||||
GRBL 1.1 CNC Controller for ODROID C2 with VU PLus Touch Screen
|
||||
# touchCNC 1.0
|
||||
GRBL 1.1 CNC Controller for ODROID C2 with VU PLus Touch Screen or Linux Desktop
|
||||
|
||||
Should run on any System wit at least 1024x600 Screen Resolution.
|
||||
|
||||
- Jog
|
||||
- Zero positions
|
||||
- Job commands
|
||||
- Spindle Coolant, Tool
|
||||
- Gcode milling envelope preview (low cpu usage),
|
||||
- Spindle Coolant, Tool and Macro commands
|
||||
- Gcode milling envelope preview
|
||||
- G28 Position
|
||||
- Feed override (soon)
|
||||
- Feed override (Not yet working)
|
||||
- terminal
|
||||
- Laser status and switch
|
||||
|
||||
![Screenshot_20231222_205706](https://github.com/BKLronin/touchCNC/assets/6392076/b57899df-8c59-4353-a41a-548273e79a59)
|
||||
![Screen.png](Screen.png)
|
||||
-
|
||||
- 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`
|
||||
|
||||
Tested on latest Armbian stable https://www.armbian.com/odroid-c2/#kernels-archive-all
|
||||
## Install
|
||||
- (Create env)
|
||||
- In folder enter:
|
||||
`pip install requirements.txt`
|
||||
|
||||
Based on
|
||||
Python3
|
||||
tkinter
|
||||
pyserial
|
||||
gerbil
|
||||
gcodemachine
|
||||
## Run
|
||||
`python cnc_gerbil.py`
|
||||
or
|
||||
`cd dist`
|
||||
`./cnc_gerbil`
|
||||
|
||||
In some cases you have to manually install tkinter via apt and pyserial via pip.
|
||||
### 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()
|
||||
|
@ -21,7 +21,7 @@ class touchCNC:
|
||||
self.increments = 0
|
||||
self.BORDER = 2
|
||||
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',
|
||||
'X': '0',
|
||||
@ -43,6 +43,14 @@ class touchCNC:
|
||||
self.feed = self.secondary
|
||||
self.transport = '#FA7921'
|
||||
|
||||
# Classic Scheme
|
||||
attention = 'red'
|
||||
loaded = 'green'
|
||||
cooling = 'blue'
|
||||
toolchange = 'yellow'
|
||||
standard = '#17223B'
|
||||
feed = '#283B67'
|
||||
|
||||
self.increments = IntVar()
|
||||
self.movement = Frame(root, relief='ridge', bd=self.BORDER, padx=10, pady=10)
|
||||
|
||||
@ -343,6 +351,7 @@ class touchCNC:
|
||||
|
||||
def grblClose(self):
|
||||
grbl.softreset()
|
||||
print(grbl.connected)
|
||||
grbl.disconnect()
|
||||
self.connect_ser.config(bg=self.secondary)
|
||||
|
||||
|
BIN
dist/cnc_gerbil
vendored
Executable file
BIN
dist/cnc_gerbil
vendored
Executable file
Binary file not shown.
@ -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")
|
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@ -0,0 +1,3 @@
|
||||
altgraph==0.17.4
|
||||
numpy==1.26.2
|
||||
pyserial==3.5
|
Loading…
Reference in New Issue
Block a user