diff --git a/doc/script/simple_stream.py b/doc/script/simple_stream.py index 67c2a2c..bb957aa 100755 --- a/doc/script/simple_stream.py +++ b/doc/script/simple_stream.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +# coding=utf-8 +from __future__ import print_function + """\ Simple g-code streaming script for grbl @@ -39,28 +42,21 @@ THE SOFTWARE. import serial import time -# Open grbl serial port -s = serial.Serial('/dev/tty.usbmodem1811',115200) +# Open grbl serial port & Open g-code file +with serial.Serial('/dev/tty.usbmodem1811', 115200) as s, open('grbl.gcode', 'r') as f: -# Open g-code file -f = open('grbl.gcode','r'); + # Wake up grbl + s.write("\r\n\r\n") + time.sleep(2) # Wait for grbl to initialize + s.flushInput() # Flush startup text in serial input -# Wake up grbl -s.write("\r\n\r\n") -time.sleep(2) # Wait for grbl to initialize -s.flushInput() # Flush startup text in serial input + # Stream g-code to grbl + for line in f: + l = line.strip() # Strip all EOL characters for consistency + print('Sending: ' + l) + s.write(l + '\n') # Send g-code block to grbl + grbl_out = s.readline() # Wait for grbl response with carriage return + print(' : ' + grbl_out.strip()) -# Stream g-code to grbl -for line in f: - l = line.strip() # Strip all EOL characters for consistency - print 'Sending: ' + l, - s.write(l + '\n') # Send g-code block to grbl - grbl_out = s.readline() # Wait for grbl response with carriage return - print ' : ' + grbl_out.strip() - -# Wait here until grbl is finished to close serial port and file. -raw_input(" Press to exit and disable grbl.") - -# Close file and serial port -f.close() -s.close() \ No newline at end of file + # Wait here until grbl is finished to close serial port and file. + raw_input(" Press to exit and disable grbl.") diff --git a/doc/script/stream.py b/doc/script/stream.py index 4a637ab..52033d7 100755 --- a/doc/script/stream.py +++ b/doc/script/stream.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +# coding=utf-8 +from __future__ import print_function + """\ Stream g-code to grbl controller @@ -48,155 +51,169 @@ THE SOFTWARE. import serial import re import time -import sys import argparse import threading RX_BUFFER_SIZE = 128 BAUD_RATE = 115200 ENABLE_STATUS_REPORTS = True -REPORT_INTERVAL = 1.0 # seconds +REPORT_INTERVAL = 1.0 # seconds -is_run = True # Controls query timer +is_run = True # Controls query timer # Define command line argument interface parser = argparse.ArgumentParser(description='Stream g-code file to grbl. (pySerial and argparse libraries required)') parser.add_argument('gcode_file', type=argparse.FileType('r'), - help='g-code filename to be streamed') + 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') + 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() + # Periodic timer to query for status reports # TODO: Need to track down why this doesn't restart consistently before a release. def send_status_query(): s.write('?') - -def periodic_timer() : + + +def periodic_timer(): while is_run: - send_status_query() - time.sleep(REPORT_INTERVAL) - + send_status_query() + time.sleep(REPORT_INTERVAL) + # Initialize -s = serial.Serial(args.device_file,BAUD_RATE) f = args.gcode_file -verbose = True -if args.quiet : verbose = False -settings_mode = False -if args.settings : settings_mode = True -check_mode = False -if args.check : check_mode = True -# Wake up grbl -print "Initializing Grbl..." -s.write("\r\n\r\n") +with serial.Serial(args.device_file, BAUD_RATE) as s: -# Wait for grbl to initialize and flush startup text in serial input -time.sleep(2) -s.flushInput() + verbose = True + if args.quiet: + verbose = False + settings_mode = False + if args.settings: + settings_mode = True + check_mode = False + if args.check: + check_mode = True -if check_mode : - print "Enabling Grbl Check-Mode: SND: [$C]", - s.write("$C\n") - while 1: - grbl_out = s.readline().strip() # Wait for grbl response with carriage return - 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 verbose: print 'REC:',grbl_out - break + # Wake up grbl + print("Initializing Grbl...") + s.write("\r\n\r\n") -start_time = time.time(); + # Wait for grbl to initialize and flush startup text in serial input + time.sleep(2) + s.flushInput() -# Start status report periodic timer -if ENABLE_STATUS_REPORTS : - timerThread = threading.Thread(target=periodic_timer) - timerThread.daemon = True - timerThread.start() - -# Stream g-code to grbl -l_count = 0 -error_count = 0 -if settings_mode: - # Send settings file via simple call-response streaming method. Settings must be streamed - # in this manner since the EEPROM accessing cycles shut-off the serial interrupt. - print "SETTINGS MODE: Streaming", args.gcode_file.name, " to ", args.device_file - for line in f: - l_count += 1 # Iterate line counter - # l_block = re.sub('\s|\(.*?\)','',line).upper() # Strip comments/spaces/new line and capitalize - l_block = line.strip() # Strip all EOL characters for consistency - if verbose: print "SND>"+str(l_count)+": \"" + l_block + "\"" - s.write(l_block + '\n') # Send g-code block to grbl + if check_mode: + print("Enabling Grbl Check-Mode: SND: [$C]", end=' ') + s.write("$C\n") while 1: - grbl_out = s.readline().strip() # Wait for grbl response with carriage return - if grbl_out.find('ok') >= 0 : - if verbose: print " REC<"+str(l_count)+": \""+grbl_out+"\"" - break - elif grbl_out.find('error') >= 0 : - if verbose: print " REC<"+str(l_count)+": \""+grbl_out+"\"" - error_count += 1 + grbl_out = s.readline().strip() # Wait for grbl response with carriage return + 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 verbose: + print('REC:', grbl_out) break + + start_time = time.time() + + # Start status report periodic timer + if ENABLE_STATUS_REPORTS: + timerThread = threading.Thread(target=periodic_timer) + timerThread.daemon = True + timerThread.start() + + # Stream g-code to grbl + l_count = 0 + error_count = 0 + if settings_mode: + # Send settings file via simple call-response streaming method. Settings must be streamed + # in this manner since the EEPROM accessing cycles shut-off the serial interrupt. + print("SETTINGS MODE: Streaming", args.gcode_file.name, " to ", args.device_file) + for line in f: + l_count += 1 # Iterate line counter + # l_block = re.sub('\s|\(.*?\)','',line).upper() # Strip comments/spaces/new line and capitalize + l_block = line.strip() # Strip all EOL characters for consistency + if verbose: + print("SND>" + str(l_count) + ": \"" + l_block + "\"") + s.write(l_block + '\n') # Send g-code block to grbl + while 1: + grbl_out = s.readline().strip() # Wait for grbl response with carriage return + if grbl_out.find('ok') >= 0: + if verbose: + print(" REC<" + str(l_count) + ": \"" + grbl_out + "\"") + break + elif grbl_out.find('error') >= 0: + if verbose: + print(" REC<" + str(l_count) + ": \"" + grbl_out + "\"") + error_count += 1 + break + else: + print(" MSG: \"" + grbl_out + "\"") + else: + # Send g-code program via a more agressive streaming protocol that forces characters into + # Grbl's serial read buffer to ensure Grbl has immediate access to the next g-code command + # rather than wait for the call-response serial protocol to finish. This is done by careful + # counting of the number of characters sent by the streamer to Grbl and tracking Grbl's + # responses, such that we never overflow Grbl's serial read buffer. + g_count = 0 + c_line = [] + for line in f: + l_count += 1 # Iterate line counter + l_block = re.sub('\s|\(.*?\)', '', line).upper() # Strip comments/spaces/new line and capitalize + # l_block = line.strip() + c_line.append(len(l_block) + 1) # Track number of characters in grbl serial read buffer + grbl_out = '' + while sum(c_line) >= RX_BUFFER_SIZE - 1 | s.inWaiting(): + out_temp = s.readline().strip() # Wait for grbl response + if out_temp.find('ok') < 0 and out_temp.find('error') < 0: + print(" MSG: \"" + out_temp + "\"") # Debug response + else: + if out_temp.find('error') >= 0: + error_count += 1 + g_count += 1 # Iterate g-code counter + if verbose: + print(" REC<" + str(g_count) + ": \"" + out_temp + "\"") + del c_line[0] # Delete the block character count corresponding to the last 'ok' + s.write(l_block + '\n') # Send g-code block to grbl + if verbose: + print("SND>" + str(l_count) + ": \"" + l_block + "\"") + # Wait until all responses have been received. + while l_count > g_count: + out_temp = s.readline().strip() # Wait for grbl response + if out_temp.find('ok') < 0 and out_temp.find('error') < 0: + print(" MSG: \"" + out_temp + "\"") # Debug response else: - print " MSG: \""+grbl_out+"\"" -else: - # Send g-code program via a more agressive streaming protocol that forces characters into - # Grbl's serial read buffer to ensure Grbl has immediate access to the next g-code command - # rather than wait for the call-response serial protocol to finish. This is done by careful - # counting of the number of characters sent by the streamer to Grbl and tracking Grbl's - # responses, such that we never overflow Grbl's serial read buffer. - g_count = 0 - c_line = [] - for line in f: - l_count += 1 # Iterate line counter - l_block = re.sub('\s|\(.*?\)','',line).upper() # Strip comments/spaces/new line and capitalize - # l_block = line.strip() - c_line.append(len(l_block)+1) # Track number of characters in grbl serial read buffer - grbl_out = '' - while sum(c_line) >= RX_BUFFER_SIZE-1 | s.inWaiting() : - out_temp = s.readline().strip() # Wait for grbl response - if out_temp.find('ok') < 0 and out_temp.find('error') < 0 : - print " MSG: \""+out_temp+"\"" # Debug response - else : - if out_temp.find('error') >= 0 : error_count += 1 - g_count += 1 # Iterate g-code counter - if verbose: print " REC<"+str(g_count)+": \""+out_temp+"\"" - del c_line[0] # Delete the block character count corresponding to the last 'ok' - s.write(l_block + '\n') # Send g-code block to grbl - if verbose: print "SND>"+str(l_count)+": \"" + l_block + "\"" - # Wait until all responses have been received. - while l_count > g_count : - out_temp = s.readline().strip() # Wait for grbl response - if out_temp.find('ok') < 0 and out_temp.find('error') < 0 : - print " MSG: \""+out_temp+"\"" # Debug response - else : - if out_temp.find('error') >= 0 : error_count += 1 - g_count += 1 # Iterate g-code counter - del c_line[0] # Delete the block character count corresponding to the last 'ok' - if verbose: print " REC<"+str(g_count)+": \""+out_temp + "\"" + if out_temp.find('error') >= 0: + error_count += 1 + g_count += 1 # Iterate g-code counter + del c_line[0] # Delete the block character count corresponding to the last 'ok' + if verbose: + print(" REC<" + str(g_count) + ": \"" + out_temp + "\"") -# Wait for user input after streaming is completed -print "\nG-code streaming finished!" -end_time = time.time(); -is_run = False; -print " Time elapsed: ",end_time-start_time,"\n" -if check_mode : - if error_count > 0 : - print "CHECK FAILED:",error_count,"errors found! See output for details.\n" - 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." - raw_input(" Press to exit and disable Grbl.") + # Wait for user input after streaming is completed + print("\nG-code streaming finished!") + end_time = time.time() + is_run = False + print(" Time elapsed: ", end_time - start_time, "\n") + if check_mode: + if error_count > 0: + print("CHECK FAILED:", error_count, "errors found! See output for details.\n") + 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.") + raw_input(" Press to exit and disable Grbl.") -# Close file and serial port -f.close() -s.close() + # Close file and serial port + f.close()