Serial TTY Communication via Shell Script?

So, after building a small Arduino-base (GRBL) CNC mill, I was a bit disappointed by the lack of a good Linux CLI interface to stream G-code files to my controller firmware. Then I found this python script on GitHub:

https://github.com/grbl/grbl/blob/master/script/simple_stream.py

I'm not all that familiar with python, but basically this script just looks for a file called grbl.gcode and streams it, line by line, to your device. To make this script easier to use, I wrote a few shell scripts as a wrapper to stream files and jog the machine more interactively. This setup works great. However, I would now like to rewrite that python script into a bash script, making it more universal so it could be run on any *nix system with depending on python or the py-serial module. I wrote a shell script that uses echo to send each line of my G-code file, one after another to my machine at /dev/ttyACM0. This script does essentially the same thing as the simple_stream python script and works quite well to jog the machine and stream small gcode files (under about 20 lines or so). However, streaming large files, it begins streaming fine, but then I run into problems:

  1. As soon as I tell the script to begin streaming, about 10 lines of gcode are sent to the Arduino almost immediately. After a few seconds of delay, my machine goes into motion.

  2. After that initial 10 or so lines, the gcode begins steaming MUCH slower, with maybe a 5 or 6 second delay between lines. The script begins streaming gcode lines slower than my machine completes them.

  3. After around line 20 or 30, my machine catches up to the gcode being streamed. At this point, the firmware must wait the 5 or 6 seconds between lines before executing the code.

So my question is, what is the cause of this issue and what can be done to resolve it? I'm assuming that there is some sort of buffer in the firmware that is being filled and overflows. However, I don't know what commands could be issued from a shell script that would clear the buffer for the next code in line. As I understand it, the simple_stream python script waits for a response from GRBL before streaming the next line. Again, I don't know if or how this functionality could be added to a shell script or whether it would solve my issue. Any suggestions would be awesome!

You'd want to double check that your code is not blocking. The Arduino can only do one thing at a time, of course, so when it reaches the point where it reads the serial buffer, it grabs everything that has been buffered all at once, then begins to process the commands it has received. Once it finishes those commands, I'd assume that it loops around and checks the buffer again and grabs whatever is available.

I'd suggest sending all the commands to the Arduino at once, saving them to an SD card or something, and then letting it play out the entire CNC process, rather than trying to pass commands real time. That is, unless you're trying to have real time response from commands you're manually putting into the CLI.

petermetzger:
I'd suggest sending all the commands to the Arduino at once, saving them to an SD card or something, and then letting it play out the entire CNC process, rather than trying to pass commands real time. That is, unless you're trying to have real time response from commands you're manually putting into the CLI.

I did try something like that, without an sd card, but got essentially the same result:

cat mygcode.ngc > /dev/ttyACM0

Since that python script is capable of accomplishing what I'm trying to do, I would assume that it would be possible through bash as well. Somehow the python script constantly listens for responses from the firmware and sends out several lines of code ahead of the machine.

I can't say for certain, but looking at the python script, I am curious about Line #34 and the Serial.readline() function. Do you know if the .readline() function actually waits for available data? If it's assuming data is ready on the tty port, and continues processing regardless, that could be a pitfall right there.