#!/usr/bin/env python3
# ---------------------------------------------------------------------------- #
## \file gcodesender.py
## \author Sebastien Beaugrand
## \sa http://beaugrand.chez.com/
## \copyright CeCILL 2.1 Free Software license
## \note Source: https://github.com/gnea/grbl/wiki
# ---------------------------------------------------------------------------- #
import serial
import time
import sys
import argparse
from os import path
RX_BUFFER_SIZE = 128
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--interactive', action='store_true')
parser.add_argument('-r', '--baudrate', default=115200)
parser.add_argument('-f',
'--file',
default=sys.stdin,
type=argparse.FileType('r'))
args = parser.parse_args()
dev = '/dev/ttyACM0'
if path.isfile('pts'):
with open('pts') as f:
dev = f.readline()
elif not path.exists(dev):
dev = '/dev/ttyUSB0'
# ---------------------------------------------------------------------------- #
## \class CNC
# ---------------------------------------------------------------------------- #
class CNC:
def __init__(self, dev):
if not path.exists(dev):
print("{} not found".format(dev))
exit(1)
self.ser = serial.Serial(dev, args.baudrate)
self.ser.write(b"\r\n\r\n")
time.sleep(2)
self.ser.flushInput()
self.length = []
def __del__(self):
self.flush()
self.ser.close()
def flush(self):
try:
while len(self.length) > 0 or self.ser.in_waiting > 0:
self.read()
except OSError:
pass
def read(self):
recv = self.ser.readline().decode().strip()
if args.interactive:
print(recv)
else:
print('recv: {}'.format(recv))
if recv.find('ok') >= 0 or\
recv.find('error') >= 0:
del self.length[0]
return 1
return 0
def write(self, line):
self.length.append(len(line) + 1)
if not args.interactive:
while sum(self.length) >= RX_BUFFER_SIZE - 1 or\
self.ser.in_waiting > 0:
self.read()
print('send: {}'.format(line))
self.ser.write(line.encode() + b'\n')
# ---------------------------------------------------------------------------- #
# main
# ---------------------------------------------------------------------------- #
cnc = CNC(dev)
if not args.interactive:
start = time.time()
try:
if args.interactive:
print('> ', end='', flush=True)
for line in args.file:
line = line.strip()
if len(line) == 0 or line[0] == '(':
if args.interactive:
print('> ', end='', flush=True)
continue
cnc.write(line)
if args.interactive:
while cnc.read() == 0:
pass
print('> ', end='', flush=True)
except KeyboardInterrupt:
cnc.ser.write(b'\030')
time.sleep(1)
cnc.ser.write(b'?')
time.sleep(1)
if not args.interactive:
cnc.flush()
h, r = divmod(time.time() - start, 3600)
m, s = divmod(r, 60)
print('time: {}h{}m{:.2f}s'.format(int(h), int(m), s))