From b4d2bcebabec2c5a7e8368a3215bb3232fff8a08 Mon Sep 17 00:00:00 2001 From: Thomas Herrmann Date: Fri, 22 Dec 2023 16:30:35 +0100 Subject: [PATCH] - Added laser state indicator - Added portscan - --- cnc_gerbil.py | 236 +++++++++++++++++++++++++++++++------------------- 1 file changed, 149 insertions(+), 87 deletions(-) diff --git a/cnc_gerbil.py b/cnc_gerbil.py index c6b3f3d..22c9d3e 100644 --- a/cnc_gerbil.py +++ b/cnc_gerbil.py @@ -1,3 +1,4 @@ +import logging import time from tkinter import Button, Label, Variable, IntVar, Canvas, Frame, Listbox, Entry, Radiobutton, Tk, constants, LEFT from tkinter import filedialog as fd @@ -11,14 +12,17 @@ class touchCNC: self.root = root # GUI Main + self.stick_var = None + self.stick_var_disp = 'NSWE' self.buttonsize_x = 5 self.buttonsize_y = 3 self.buttonsize_y_s = 1 - self.pady_var = 5 + self.pady_var = 3 self.file_list = [] self.list_items = Variable(value=self.file_list) 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.dict_GCODE = {'G': '0', @@ -98,19 +102,19 @@ class touchCNC: command=lambda: self.latchWrite('M3')) self.coolant = Button(root, text="Coolant", width=self.buttonsize_x, height=self.buttonsize_y, bg=self.standard, command=lambda: self.latchWrite('M8')) - self.tool = Button(root, text="Tool", width=self.buttonsize_x, height=self.buttonsize_y, bg=self.standard, command=lambda: self.latchWrite('M6')) + self.tool = Button(root, text="Tool", width=self.buttonsize_x, height=self.buttonsize_y, bg=self.standard, command=lambda: self.directWrite('G10')) self.macro = Button(root, text="Laser", width=self.buttonsize_x, height=self.buttonsize_y, bg=self.standard, command=lambda: self.latchWrite('32')) #self.directWrite(' G91 G0 X10 Y10 Z50 F1000')) - self.inc1 = Button(root, text="Inc 1%", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.directWrite('‘'), + self.inc1 = Button(root, text="Inc 1%", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.feed_over_write(1), bg=self.feed) - self.inc10 = Button(root, text="Inc 10%", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.directWrite('“'), + self.inc10 = Button(root, text="Inc 10%", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.feed_over_write(10), bg=self.feed) - self.dec1 = Button(root, text="Dec 1%", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.directWrite('”'), + self.dec1 = Button(root, text="Dec 1%", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.feed_over_write(-1), bg=self.feed) - self.dec10 = Button(root, text="Dec 10%", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.directWrite('’'), + self.dec10 = Button(root, text="Dec 10%", width=self.buttonsize_x, height=self.buttonsize_y, command=lambda: self.feed_over_write(-10), bg=self.feed) - self.reset = Button(root, text=" 9: + self.feedspeed = data[10] + + elif eventstring == "on_read": + if data[0] == '$32=1': + self.macro.config(background=self.attention) + + elif data[0] == '$32=0': + self.macro.config(background=self.loaded) + + #elif eventstring == "on_processed_command": + # pass elif eventstring == "on_line_sent": pass @@ -285,15 +302,51 @@ class touchCNC: self.terminal_recv.config(text=eventstring) self.terminal_recv_content.config(text=data) - def grblConnect2(self): - grbl.cnect("/dev/ttyUSB0", 115200) # or /dev/ttyACM0 - time.sleep(2) - if grbl.connected: - grbl.poll_start() - self.connect_ser.config(bg = self.loaded) + import time + import logging - else: - print("wtf -couldnt start thread") + def grblConnect2(self, baudrate=115200, max_retries=5, retry_interval=3): + retry_count = 0 + locations = ['/dev/ttyUSB0', '/dev/ttyACM0', '/dev/ttyUSB1', '/dev/ttyACM1', '/dev/ttyACM2', '/dev/ttyACM3', + '/dev/ttyS0', '/dev/ttyS1', '/dev/ttyS2', '/dev/ttyS3'] + + # Configure logging + logging.basicConfig(level=logging.DEBUG) + logger = logging.getLogger(__name__) + + if not grbl.connected: + for device in locations: + if retry_count < max_retries: + try: + logger.info(f"Attempting to connect to {device}") + grbl.cnect(path=device, baudrate=baudrate) + + break + + except Exception as e: + logger.error(f"Failed to connect to {device}: {e}") + self.terminal_recv_content.config(text=f"Failed to connect to {device}: {e}") + retry_count += 1 + time.sleep(retry_interval) + + logger.warning(f"Failed to connect after {max_retries} attempts.") + + finally: + time.sleep(3) + grbl.setup_logging() + self.connect_ser.config(bg=self.loaded) + #rbl.request_settings() + logger.info(f"Connection successful to {device}") + self.terminal_recv_content.config(text=f"Connection successful to {device}") + grbl.connected = True + grbl.poll_start() + self.terminal_recv_content.config(text=f"State: {grbl.connected}") + #grbl.set_feed_override(True) + + def grblClose(self): + grbl.softreset() + grbl.disconnect() + self.connect_ser.config(bg=self.secondary) def displayWorkPosition(self, pos: list): #print("update", pos) @@ -311,9 +364,14 @@ class touchCNC: grbl.send_immediately(grbl_command) - def directWrite(self,cmd): + def directWrite(self, cmd): grbl.send_immediately(cmd) + def feed_over_write(self, change: int): + new_feed = self.feedspeed / 100 * change + print(new_feed) + grbl.request_feed(new_feed) + def latchWrite(self, CMD): if self.states[CMD] == '0': self.states[CMD] = '1' @@ -343,7 +401,7 @@ class touchCNC: def get_grbl_command(self, CMD): if CMD == 'M3': - return 'M3 S1000' if self.states['M3'] == '1' else 'M3 S0' + return 'M3 S1000' if self.states['M3'] == '1' else 'M5' elif CMD == 'M8': return CMD if self.states[CMD] == '1' else 'M9' @@ -367,6 +425,8 @@ class touchCNC: GCODE = self.load_gcode_from_listbox() if GCODE: + grbl.abort() + grbl.job_new() self.fopen.config(bg=self.loaded) extracted = self.extract_GCODE(GCODE) draw = DrawonTable(self.mill_table) @@ -402,18 +462,23 @@ class touchCNC: def openDir(self): self.file_list = [] directory = fd.askdirectory(title='Open a Folder', initialdir='/home/thomas/Nextcloud/CAM/') - print(directory) + #print(directory) allowed_extensions = {'nc', 'GCODE'} # Use a set for efficient membership testing + print(directory) - filenames = self.get_filenames(directory) - self.files.delete(0, constants.END) - for file in filenames: - # Check if the file has an allowed extension - if any(file.lower().endswith(ext) for ext in allowed_extensions): - self.file_list.append(file) - self.files.insert("end", file) # Add the filename to the Listbox + if directory: + filenames = self.get_filenames(directory) + self.files.delete(0, constants.END) + for file in filenames: + # Check if the file has an allowed extension + if any(file.lower().endswith(ext) for ext in allowed_extensions): + self.file_list.append(file) + self.files.insert("end", file) # Add the filename to the Listbox + else: + print("Please select Folder") + self.terminal_recv_content.config(text="Please select Folder") - print(self.file_list) + #print(self.file_list) def load_gcode_from_listbox(self): selected_indices = self.files.curselection() if selected_indices: @@ -471,9 +536,7 @@ class touchCNC: return list_dict_GCODE - def grblClose(self): - grbl.disconnect() - self.connect_ser.config(bg=self.secondary) + class DrawonTable: def __init__(self, mill_table: object): @@ -493,7 +556,7 @@ class DrawonTable: self.mill_table.delete('all') def drawToolCursor(self): - id = self.mill_table.create_text(50 + float(self.cursor_pos[0]), 345 - float(self.cursor_pos[1]), text='V', fill = 'red') + id = self.mill_table.create_text(50 + float(self.cursor_pos[0]), 342 - float(self.cursor_pos[1]), text='V', fill = 'red', font=("Arial", 16)) return id @@ -549,7 +612,6 @@ if __name__ == "__main__": app = touchCNC(root) grbl = Gerbil(app.gui_callback) - grbl.setup_logging() grbl.hash_state_requested = True grbl.gcode_parser_state_requested = True