diff --git a/arduinosender/CommunicationMain.py b/arduinosender/CommunicationMain.py index d7b9db0..bc4622d 100644 --- a/arduinosender/CommunicationMain.py +++ b/arduinosender/CommunicationMain.py @@ -1,65 +1,198 @@ -import serial -import argparse -from time import sleep - +from serial import Serial from serial import SerialException -if __name__ == "__main__": - parser = argparse.ArgumentParser(prog = 'main.py') - parser.add_argument('-g', required = True, help = 'GCode file path') - parser.add_argument('-c', required = True, help = 'Arduino com port') - parser.add_argument('-t', required = False, type = int, help = 'Communication timout') - parser.add_argument('-b', required = False, type = int, help = 'Communication baudrate') - parser.add_argument('-waittime', required = False, type = int, help = 'Sleep time before sending (s)') - args = parser.parse_args() +from time import sleep +from tkinter import * +from tkinter.ttk import Notebook + +global serial + +class LabelWithEntry: + def __init__(self, parent, labelText, padXLeft = (0, 0), padYLeft = (0, 0), padXRight = (0, 0), padYRight = (0, 0)): + frame = Frame(parent) + frame.pack(side = TOP, fill = BOTH, expand = 1) + self.label = Label(frame, text = labelText) + self.label.pack(side = LEFT, padx = padXLeft, pady = padYLeft) + self.entry = Entry(frame) + self.entry.pack(side = RIGHT, padx = padXRight, pady = padYRight) - timeoutCom = 2 - baudRate = 9600 - commandTimeout = 0 - waitTime = 1 + def get(self): + return self.entry.get() + + def setText(self, text): + self.entry.insert(END, text) + +def openSerial(com, baudRate, communicationTimeout, waitTime): + global serial - if args.t: - timeoutCom = int(args.t) - if args.b: - baudRate = int(args.b) - if args.waittime: - waitTime = int(args.waittime) - - ser = None try: - ser = serial.Serial(args.c, baudRate, timeout = timeoutCom) - sleep(waitTime) + serial = Serial(com, int(baudRate), timeout = int(communicationTimeout)) + sleep(int(waitTime)) + except SerialException as errSE: + raise errSE + +def closeSerial(): + global serial - file = open(args.g, 'r') - lines = file.readlines() - file.close() - - for line in lines: - if not line == '\n': - ser.write(line.encode('UTF-8')) + try: + serial.close() + except SerialException as errSE: + raise errSE - if not ser.readline().decode('UTF-8').startswith('2'): - raise RuntimeError('Communication lost') +def readFile(filePath): + file = open(filePath, 'r') + lines = file.readlines() + file.close() + + return lines - while True: - received = ser.readline().decode('UTF-8') - if not received.startswith('1') or received.startswith('-1'): - commandTimeout += 1 - if commandTimeout > timeoutCom * 10: - raise RuntimeError('Command not executed') - if received.startswith('-1'): - raise RuntimeError('Command error') - else: - break +def sendAllLines(lines, timeoutCom): + global serial + + for line in lines: + if not line == '\n': + sendWithAck(line, timeoutCom) - print('Done') - - ser.close() - +def sendWithAck(gcodeCommand, timeoutCom): + global serial + commandTimeout = 0 + + serial.write(gcodeCommand.encode('UTF-8')) + if not serial.readline().decode('UTF-8').startswith('2'): + raise RuntimeError('Communication lost') + while True: + received = serial.readline().decode('UTF-8') + if not received.startswith('1') or received.startswith('-1'): + commandTimeout += 1 + if commandTimeout > timeoutCom * 10: + raise RuntimeError('Command not executed') + if received.startswith('-1'): + raise RuntimeError('Command error') + else: + break + + +def sendFileToPort(comPort, baudRate, communicationTimeout, waitTime, gcodePath): + global serial + + try: + openSerial(comPort, baudRate, communicationTimeout, waitTime) + lines = readFile(gcodePath) + sendAllLines(lines, communicationTimeout) + closeSerial() except SerialException as errSE: print('Serial Exception' + str(errSE)) except RuntimeError as errRE: print(str(errRE)) finally: - if ser is not None: - ser.close() \ No newline at end of file + if serial is not None: + closeSerial() + +def callWithParameters(comPortET, communicationTimeoutET, communicationBaudrateET, waitTimeET, gcodePathET): + timeoutCom = 2 + baudRate = 9600 + waitTime = 1 + + if communicationTimeoutET.get() != '': + timeoutCom = int(communicationTimeoutET.get()) + if communicationBaudrateET.get() != '': + baudRate = int(communicationBaudrateET.get()) + if waitTimeET.get() != '': + waitTime = int(waitTimeET.get()) + + sendFileToPort(comPortET.get(), baudRate, timeoutCom, waitTime, gcodePathET.get()) + +def sendX(mov, timeoutCom): + sendWithAck('G0 X' + str(mov), timeoutCom) + +def sendY(mov, timeoutCom): + sendWithAck('G0 Y' + str(mov), timeoutCom) + +def sendZ(mov, timeoutCom): + sendWithAck('G0 Z' + str(mov), timeoutCom) + +def sendHome(timeoutCom): + sendWithAck('G28', timeoutCom) + +def sendAbsPosition(timeoutCom): + sendWithAck('G90', timeoutCom) + +def sendRelativePosition(timeoutCom): + sendWithAck('G91', timeoutCom) + + +if __name__ == "__main__": + mainWindow = Tk() + mainWindow.title('Hello World!') + tabControl = Notebook(mainWindow) + tabAuto = Frame(tabControl) + tabManual = Frame(tabControl) + + # Frames + autoMainFrame = Frame(tabAuto, width = 300, height = 100) + autoMainFrame.pack(fill = None, expand = False) + manualMainFrame = Frame(tabManual, width = 300, height = 100) + manualMainFrame.pack(fill = None, expand = False) + + # Auto mode + padding = 20 + gcodeEntry = LabelWithEntry(autoMainFrame, 'GCode file', padXLeft = (0, padding)) + comEntry = LabelWithEntry(autoMainFrame, 'COM port', padXLeft = (0, padding)) + baudrateEntry = LabelWithEntry(autoMainFrame, 'Baudrate', padXLeft = (0, padding)) + baudrateEntry.setText('9600') + + comTimoutEntry = LabelWithEntry(autoMainFrame, 'Com timout (s)', padXLeft = (0, padding)) + comTimoutEntry.setText('1') + + sleepEntry = LabelWithEntry(autoMainFrame, 'Sleep init (s)', padXLeft = (0, padding)) + sleepEntry.setText('1') + + Button(autoMainFrame, text = 'Start', + command = lambda: callWithParameters(comEntry, baudrateEntry, comTimoutEntry, sleepEntry, gcodeEntry)) \ + .pack(side = BOTTOM, fill = BOTH, expand = 1, pady = (15, 0)) + + # Manual mode + buttonsFrame = Frame(manualMainFrame) + buttonsFrame.pack(side = TOP) + + openButton = Button(buttonsFrame, text = 'Open', command = lambda: openSerial(comEntry.get(), int(baudrateEntry.get()), int(comTimoutEntry.get()), int(sleepEntry.get()))) + openButton.grid(row = 0, column = 0) + closeButton = Button(buttonsFrame, text = 'Close', command = lambda: closeSerial()) + closeButton.grid(row = 0, column = 2) + + sendXP5Button = Button(buttonsFrame, text = '+5X', command = lambda: sendX(5, int(comTimoutEntry.get()))) + sendXP5Button.grid(row = 2, column = 2, padx = 5) + sendXM5Button = Button(buttonsFrame, text = '-5X', command = lambda: sendX(-5, int(comTimoutEntry.get()))) + sendXM5Button.grid(row = 2, column = 0, padx = 5) + + sendYP5Button = Button(buttonsFrame, text = '+5Y', command = lambda: sendY(5, int(comTimoutEntry.get()))) + sendYP5Button.grid(row = 1, column = 1, pady = 5) + sendYM5Button = Button(buttonsFrame, text = '-5Y', command = lambda: sendY(-5, int(comTimoutEntry.get()))) + sendYM5Button.grid(row = 3, column = 1, pady = 5) + + sendHomeButton = Button(buttonsFrame, text = 'Home', command = lambda: sendHome(int(comTimoutEntry.get()))) + sendHomeButton.grid(row = 2, column = 1) + + sendZP5Button = Button(buttonsFrame, text = '+5Z', command = lambda: sendZ(5, int(comTimoutEntry.get()))) + sendZP5Button.grid(row = 3, column = 2) + sendZM5Button = Button(buttonsFrame, text = '-5Z', command = lambda: sendZ(-5, int(comTimoutEntry.get()))) + sendZM5Button.grid(row = 1, column = 2) + + sendZP5Button = Button(buttonsFrame, text = 'G90', command = lambda: sendAbsPosition(int(comTimoutEntry.get()))) + sendZP5Button.grid(row = 1, column = 0) + sendZM5Button = Button(buttonsFrame, text = 'G91', command = lambda: sendRelativePosition(int(comTimoutEntry.get()))) + sendZM5Button.grid(row = 3, column = 0) + + customCommandFrame = Frame(manualMainFrame) + customCommandFrame.pack(side = BOTTOM, fill = BOTH, expand = 1) + + customCommand = Entry(customCommandFrame) + customCommand.pack(side = LEFT, fill = BOTH, expand = 1) + Button(customCommandFrame, text = 'Send', command = lambda: sendWithAck(customCommand.get(), int(comTimoutEntry.get()))).pack(side = RIGHT) + + tabControl.add(tabAuto, text = 'Auto') + tabControl.add(tabManual, text = 'Manual') + tabControl.pack(expand = 1, fill = BOTH) + mainWindow.mainloop() + + closeSerial() \ No newline at end of file