4Stream g-code to grbl controller
6This script differs from the simple_stream.py script by
7tracking the number of characters in grbl's serial read
8buffer. This allows grbl to fetch the next line directly
9from the serial buffer and does not have to wait for a
10response from the computer. This effectively adds another
11buffer layer to prevent buffer starvation.
14- 20170531: Status report feedback at 1.0 second intervals.
15 Configurable baudrate and report intervals. Bug fixes.
16- 20161212: Added push message feedback
for simple streaming
17- 20140714: Updated baud rate to 115200. Added a settings
18 write mode via simple streaming method. MIT-licensed.
21- Add realtime control commands during streaming.
26Copyright (c) 2012-2017 Sungeun K. Jeon
28Permission
is hereby granted, free of charge, to any person obtaining a copy
29of this software
and associated documentation files (the
"Software"), to deal
30in the Software without restriction, including without limitation the rights
31to use, copy, modify, merge, publish, distribute, sublicense,
and/
or sell
32copies of the Software,
and to permit persons to whom the Software
is
33furnished to do so, subject to the following conditions:
35The above copyright notice
and this permission notice shall be included
in
36all copies
or substantial portions of the Software.
38THE SOFTWARE IS PROVIDED
"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
57ENABLE_STATUS_REPORTS = True
58REPORT_INTERVAL = 1.0 # seconds
60is_run = True # Controls query timer
62# Define command line argument interface
63parser = argparse.ArgumentParser(description='Stream g-code file to grbl. (pySerial and argparse libraries required)')
64parser.add_argument('gcode_file', type=argparse.FileType('r'),
65 help='g-code filename to be streamed')
66parser.add_argument(
'device_file',
67 help=
'serial device path')
68parser.add_argument(
'-q',
'--quiet',action=
'store_true', default=
False,
69 help=
'suppress output text')
70parser.add_argument(
'-s',
'--settings',action=
'store_true', default=
False,
71 help=
'settings write mode')
72parser.add_argument(
'-c',
'--check',action=
'store_true', default=
False,
73 help=
'stream in check mode')
74args = parser.parse_args()
84 time.sleep(REPORT_INTERVAL)
88s = serial.Serial(args.device_file,BAUD_RATE)
91if args.quiet : verbose =
False
93if args.settings : settings_mode =
True
95if args.check : check_mode =
True
98print "Initializing Grbl..."
106 print "Enabling Grbl Check-Mode: SND: [$C]",
109 grbl_out = s.readline().strip()
110 if grbl_out.find(
'error') >= 0 :
111 print "REC:",grbl_out
112 print " Failed to set Grbl check-mode. Aborting..."
114 elif grbl_out.find(
'ok') >= 0 :
115 if verbose:
print 'REC:',grbl_out
118start_time = time.time();
121if ENABLE_STATUS_REPORTS :
122 timerThread = threading.Thread(target=periodic_timer)
123 timerThread.daemon =
True
132 print "SETTINGS MODE: Streaming", args.gcode_file.name,
" to ", args.device_file
136 l_block = line.strip()
137 if verbose:
print "SND>"+str(l_count)+
": \"" + l_block +
"\""
138 s.write(l_block +
'\n')
140 grbl_out = s.readline().strip()
141 if grbl_out.find(
'ok') >= 0 :
142 if verbose:
print " REC<"+str(l_count)+
": \""+grbl_out+
"\""
144 elif grbl_out.find(
'error') >= 0 :
145 if verbose:
print " REC<"+str(l_count)+
": \""+grbl_out+
"\""
149 print " MSG: \""+grbl_out+
"\""
160 l_block = re.sub(
'\s|\(.*?\)',
'',line).upper()
162 c_line.append(len(l_block)+1)
164 while sum(c_line) >= RX_BUFFER_SIZE-1 | s.inWaiting() :
165 out_temp = s.readline().strip()
166 if out_temp.find(
'ok') < 0
and out_temp.find(
'error') < 0 :
167 print " MSG: \""+out_temp+
"\""
169 if out_temp.find(
'error') >= 0 : error_count += 1
171 if verbose:
print " REC<"+str(g_count)+
": \""+out_temp+
"\""
173 s.write(l_block +
'\n')
174 if verbose:
print "SND>"+str(l_count)+
": \"" + l_block +
"\""
176 while l_count > g_count :
177 out_temp = s.readline().strip()
178 if out_temp.find(
'ok') < 0
and out_temp.find(
'error') < 0 :
179 print " MSG: \""+out_temp+
"\""
181 if out_temp.find(
'error') >= 0 : error_count += 1
184 if verbose:
print " REC<"+str(g_count)+
": \""+out_temp +
"\""
187print "\nG-code streaming finished!"
188end_time = time.time();
190print " Time elapsed: ",end_time-start_time,
"\n"
193 print "CHECK FAILED:",error_count,
"errors found! See output for details.\n"
195 print "CHECK PASSED: No errors found in g-code program.\n"
197 print "WARNING: Wait until Grbl completes buffered g-code blocks before exiting."
198 raw_input(
" Press <Enter> to exit and disable Grbl.")