Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
stream.py
00001 #!/usr/bin/env python 00002 """\ 00003 00004 Stream g-code to grbl controller 00005 00006 This script differs from the simple_stream.py script by 00007 tracking the number of characters in grbl's serial read 00008 buffer. This allows grbl to fetch the next line directly 00009 from the serial buffer and does not have to wait for a 00010 response from the computer. This effectively adds another 00011 buffer layer to prevent buffer starvation. 00012 00013 CHANGELOG: 00014 - 20161212: Added push message feedback for simple streaming 00015 - 20140714: Updated baud rate to 115200. Added a settings 00016 write mode via simple streaming method. MIT-licensed. 00017 00018 TODO: 00019 - Add runtime command capabilities 00020 00021 --------------------- 00022 The MIT License (MIT) 00023 00024 Copyright (c) 2012-2016 Sungeun K. Jeon 00025 00026 Permission is hereby granted, free of charge, to any person obtaining a copy 00027 of this software and associated documentation files (the "Software"), to deal 00028 in the Software without restriction, including without limitation the rights 00029 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00030 copies of the Software, and to permit persons to whom the Software is 00031 furnished to do so, subject to the following conditions: 00032 00033 The above copyright notice and this permission notice shall be included in 00034 all copies or substantial portions of the Software. 00035 00036 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00037 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00038 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00039 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00040 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00041 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00042 THE SOFTWARE. 00043 --------------------- 00044 """ 00045 00046 import serial 00047 import re 00048 import time 00049 import sys 00050 import argparse 00051 # import threading 00052 00053 RX_BUFFER_SIZE = 128 00054 00055 # Define command line argument interface 00056 parser = argparse.ArgumentParser(description='Stream g-code file to grbl. (pySerial and argparse libraries required)') 00057 parser.add_argument('gcode_file', type=argparse.FileType('r'), 00058 help='g-code filename to be streamed') 00059 parser.add_argument('device_file', 00060 help='serial device path') 00061 parser.add_argument('-q','--quiet',action='store_true', default=False, 00062 help='suppress output text') 00063 parser.add_argument('-s','--settings',action='store_true', default=False, 00064 help='settings write mode') 00065 args = parser.parse_args() 00066 00067 # Periodic timer to query for status reports 00068 # TODO: Need to track down why this doesn't restart consistently before a release. 00069 # def periodic(): 00070 # s.write('?') 00071 # t = threading.Timer(0.1, periodic) # In seconds 00072 # t.start() 00073 00074 # Initialize 00075 s = serial.Serial(args.device_file,115200) 00076 f = args.gcode_file 00077 verbose = True 00078 if args.quiet : verbose = False 00079 settings_mode = False 00080 if args.settings : settings_mode = True 00081 00082 # Wake up grbl 00083 print "Initializing grbl..." 00084 s.write("\r\n\r\n") 00085 00086 # Wait for grbl to initialize and flush startup text in serial input 00087 time.sleep(2) 00088 s.flushInput() 00089 00090 # Stream g-code to grbl 00091 l_count = 0 00092 if settings_mode: 00093 # Send settings file via simple call-response streaming method. Settings must be streamed 00094 # in this manner since the EEPROM accessing cycles shut-off the serial interrupt. 00095 print "SETTINGS MODE: Streaming", args.gcode_file.name, " to ", args.device_file 00096 for line in f: 00097 l_count += 1 # Iterate line counter 00098 # l_block = re.sub('\s|\(.*?\)','',line).upper() # Strip comments/spaces/new line and capitalize 00099 l_block = line.strip() # Strip all EOL characters for consistency 00100 if verbose: print 'SND: ' + str(l_count) + ':' + l_block, 00101 s.write(l_block + '\n') # Send g-code block to grbl 00102 while 1: 00103 grbl_out = s.readline().strip() # Wait for grbl response with carriage return 00104 if grbl_out.find('ok') < 0 and grbl_out.find('error') < 0 : 00105 print "\n Debug: ",grbl_out, 00106 else : 00107 if verbose: print 'REC:',grbl_out 00108 break 00109 else: 00110 # Send g-code program via a more agressive streaming protocol that forces characters into 00111 # Grbl's serial read buffer to ensure Grbl has immediate access to the next g-code command 00112 # rather than wait for the call-response serial protocol to finish. This is done by careful 00113 # counting of the number of characters sent by the streamer to Grbl and tracking Grbl's 00114 # responses, such that we never overflow Grbl's serial read buffer. 00115 g_count = 0 00116 c_line = [] 00117 # periodic() # Start status report periodic timer 00118 for line in f: 00119 l_count += 1 # Iterate line counter 00120 # l_block = re.sub('\s|\(.*?\)','',line).upper() # Strip comments/spaces/new line and capitalize 00121 l_block = line.strip() 00122 c_line.append(len(l_block)+1) # Track number of characters in grbl serial read buffer 00123 grbl_out = '' 00124 while sum(c_line) >= RX_BUFFER_SIZE-1 | s.inWaiting() : 00125 out_temp = s.readline().strip() # Wait for grbl response 00126 if out_temp.find('ok') < 0 and out_temp.find('error') < 0 : 00127 print " Debug: ",out_temp # Debug response 00128 else : 00129 grbl_out += out_temp; 00130 g_count += 1 # Iterate g-code counter 00131 grbl_out += str(g_count); # Add line finished indicator 00132 del c_line[0] # Delete the block character count corresponding to the last 'ok' 00133 if verbose: print "SND: " + str(l_count) + " : " + l_block, 00134 s.write(l_block + '\n') # Send g-code block to grbl 00135 if verbose : print "BUF:",str(sum(c_line)),"REC:",grbl_out 00136 00137 # Wait for user input after streaming is completed 00138 print "G-code streaming finished!\n" 00139 print "WARNING: Wait until grbl completes buffered g-code blocks before exiting." 00140 raw_input(" Press <Enter> to exit and disable grbl.") 00141 00142 # Close file and serial port 00143 f.close() 00144 s.close()
Generated on Tue Jul 12 2022 20:45:32 by
1.7.2