Commit | Line | Data |
---|---|---|
faffe1c2 JM |
1 | #!/usr/bin/env python |
2 | """\ | |
3 | Stream g-code to Smoothie USB serial connection | |
4 | ||
908d94f4 | 5 | Based on GRBL stream.py, but completely different |
faffe1c2 JM |
6 | """ |
7 | ||
8 | from __future__ import print_function | |
9 | import sys | |
10 | import argparse | |
11 | import serial | |
12 | import threading | |
13 | import time | |
92485600 JM |
14 | import signal |
15 | import sys | |
16 | ||
17 | errorflg= False | |
18 | intrflg= False | |
19 | ||
20 | def signal_term_handler(signal, frame): | |
21 | global intrflg | |
22 | print('got SIGTERM...') | |
23 | intrflg= True | |
24 | ||
25 | signal.signal(signal.SIGTERM, signal_term_handler) | |
faffe1c2 JM |
26 | |
27 | # Define command line argument interface | |
28 | parser = argparse.ArgumentParser(description='Stream g-code file to Smoothie over telnet.') | |
29 | parser.add_argument('gcode_file', type=argparse.FileType('r'), | |
30 | help='g-code filename to be streamed') | |
31 | parser.add_argument('device', | |
32 | help='Smoothie Serial Device') | |
33 | parser.add_argument('-q','--quiet',action='store_true', default=False, | |
34 | help='suppress output text') | |
35 | args = parser.parse_args() | |
36 | ||
37 | f = args.gcode_file | |
38 | verbose = not args.quiet | |
39 | ||
40 | # Stream g-code to Smoothie | |
41 | ||
42 | dev= args.device | |
43 | ||
44 | # Open port | |
45 | s = serial.Serial(dev, 115200) | |
46 | s.flushInput() # Flush startup text in serial input | |
47 | ||
48 | print("Streaming " + args.gcode_file.name + " to " + args.device) | |
49 | ||
50 | okcnt= 0 | |
51 | ||
52 | def read_thread(): | |
53 | """thread worker function""" | |
436daacf | 54 | global okcnt, errorflg |
faffe1c2 JM |
55 | flag= 1 |
56 | while flag : | |
57 | rep= s.readline() | |
58 | n= rep.count("ok") | |
59 | if n == 0 : | |
60 | print("Incoming: " + rep) | |
908d94f4 | 61 | if "error" in rep or "!!" in rep or "ALARM" in rep or "ERROR" in rep: |
436daacf JM |
62 | errorflg= True |
63 | break | |
faffe1c2 JM |
64 | else : |
65 | okcnt += n | |
66 | ||
67 | print("Read thread exited") | |
68 | return | |
69 | ||
70 | # start read thread | |
71 | t = threading.Thread(target=read_thread) | |
72 | t.daemon = True | |
73 | t.start() | |
74 | ||
75 | linecnt= 0 | |
92485600 JM |
76 | try: |
77 | for line in f: | |
78 | if errorflg : | |
79 | break | |
80 | # strip comments | |
81 | if line.startswith(';') : | |
82 | continue | |
83 | l= line.strip() | |
84 | s.write(l + '\n') | |
85 | linecnt+=1 | |
86 | if verbose: print("SND " + str(linecnt) + ": " + line.strip() + " - " + str(okcnt)) | |
908d94f4 | 87 | |
92485600 JM |
88 | except KeyboardInterrupt: |
89 | print("Interrupted...") | |
90 | intrflg= True | |
91 | ||
92 | if intrflg : | |
908d94f4 JM |
93 | # We need to consume oks otherwise smoothie will deadlock on a full tx buffer |
94 | print("Sending Abort - this may take a while...") | |
95 | s.write('\x18') # send halt | |
92485600 | 96 | |
5d401ee2 JM |
97 | if errorflg : |
98 | print("Target halted due to errors") | |
faffe1c2 | 99 | |
5d401ee2 JM |
100 | else : |
101 | print("Waiting for complete...") | |
92485600 | 102 | while okcnt < linecnt : |
5d401ee2 | 103 | if verbose: print(str(linecnt) + " - " + str(okcnt) ) |
92485600 | 104 | if errorflg : |
908d94f4 | 105 | s.read(s.inWaiting()) # rad all remaining characters |
92485600 | 106 | break |
5d401ee2 | 107 | time.sleep(1) |
18ae0219 JM |
108 | |
109 | # Wait here until finished to close serial port and file. | |
110 | raw_input(" Press <Enter> to exit") | |
faffe1c2 | 111 | |
faffe1c2 JM |
112 | |
113 | # Close file and serial port | |
114 | f.close() | |
115 | s.close() |