the python script so far consists of:
- setting up GRBL through serial communication
- setting up the GUI with tkinter
- the GUI so far consists of:
- buttons for xyz movement(to move the scanner to the start location)
- buttons for setting a predetermined path(for scanning)
however the method for inputting the path is different from the one used in
homeview(in the lab). the code doesn't involve adding steps in y axis after x axis
movement.
the whole path is to be inputted by the user, this can be modified to the method
used in homview if necessary.
the code also doesn't show any output that is generated yet, i will add it after
understanding how the output is measured and what format the output is needed in.
Here is the code:
(I have run only the GUI part and it works, to run the whole code i will need the
raspberry pi)
import serial
import time
import tkinter as tk
from functools import partial
# Configure the serial port
serial_port = '/dev/ttyUSB0' # Change to match your system
baud_rate = 115200
ser = serial.Serial(serial_port, baud_rate)
# Function to send G-code commands to GRBL
def send_gcode(gcode):
gcode_line = f"{gcode}\n"
ser.write(gcode_line.encode('utf-8'))
response = ser.readline().decode('utf-8').strip()
print(f"Sent: {gcode} | Received: {response}")
return response
# Define the move functions
def move_axis(axis, distance):
send_gcode(f"G0 {axis}{distance}")
# Function to follow a path
def follow_path(path):
for command in path:
send_gcode(command)
time.sleep(0.5) # Adjust delay as needed
# Function to add a movement command to the path
def add_to_path(axis, distance, path_listbox):
command = f"G0 {axis}{distance}"
path_listbox.insert(tk.END, command)
# Function to execute the path from the listbox
def execute_path(path_listbox):
path = path_listbox.get(0, tk.END)
follow_path(path)
# GUI setup with tkinter
def setup_gui():
root = tk.Tk()
root.title("XYZ Manipulator Control with GRBL")
directions = ['X', 'Y', 'Z']
moves = [10, -10]
for i, direction in enumerate(directions):
for j, move in enumerate(moves):
btn = tk.Button(root, text=f"{direction}{'+' if move > 0 else '-'}",
command=partial(move_axis, direction, move))
btn.grid(row=i, column=j)
# Path entry
path_label = tk.Label(root, text="Enter Path Movement:")
path_label.grid(row=len(directions), column=0, columnspan=3)
path_listbox = tk.Listbox(root, height=6)
path_listbox.grid(row=len(directions) + 1, column=0, columnspan=3)
axis_label = tk.Label(root, text="Axis:")
axis_label.grid(row=len(directions) + 2, column=0)
axis_entry = tk.Entry(root)
axis_entry.grid(row=len(directions) + 2, column=1)
distance_label = tk.Label(root, text="Distance:")
distance_label.grid(row=len(directions) + 2, column=2)
distance_entry = tk.Entry(root)
distance_entry.grid(row=len(directions) + 2, column=3)
add_button = tk.Button(root, text="Add to Path",
command=lambda: add_to_path(axis_entry.get().upper(),
distance_entry.get(), path_listbox))
add_button.grid(row=len(directions) + 2, column=4)
execute_button = tk.Button(root, text="Execute Path",
command=lambda: execute_path(path_listbox))
execute_button.grid(row=len(directions) + 3, column=0, columnspan=5)
return root
# Function to handle closing the GUI
def on_closing(root):
ser.close() # Ensure the serial port is closed
root.destroy() # Close the GUI window
# Main function
if __name__ == "__main__":
root = setup_gui() # Setup the GUI
# Set up the protocol handler to stop the listener when the window is closed
root.protocol("WM_DELETE_WINDOW", partial(on_closing, root))
# Run the GUI main loop
root.mainloop()