# How to directly send G-code to printer from a Linux terminal?

Should it be possible to directly send G-code to the printer serial connection using pipes under Linux?

Example:

echo M106 > /dev/ttyUSB0


My controller runs at 250000 baud, I have tried setting the TTY baud rate to 250 kBd with:

stty -F /dev/ttyUSB0 250000


But, unfortunately, this particular baud rate appears to be unsupported under Ubuntu, giving the error:

stty: invalid argument ‘250000’


For direct low-level printer control from a terminal, without specific software, I found the following solution with full credit thanks to user: http://stackexchange.com/users/6463673/meuh

Sharing here as may be of use to other users in the 3d Printing community, and I was unable to source a "complete" solution to this elsewhere.

Step 1) Create a custom python script that allows you to set arbitrary baud rates (make executable with chmod u+x).

#!/usr/bin/python
# set nonstandard baudrate. Original Question: http://unix.stackexchange.com/a/327366/119298
import sys,array,fcntl

# from /usr/lib/python2.7/site-packages/serial/serialposix.py
# /usr/include/asm-generic/termbits.h for struct termios2
#  [2]c_cflag [9]c_ispeed [10]c_ospeed
def set_special_baudrate(fd, baudrate):
TCGETS2 = 0x802C542A
TCSETS2 = 0x402C542B
BOTHER = 0o010000
CBAUD = 0o010017
buf = array.array('i', [0] * 64) # is 44 really
fcntl.ioctl(fd, TCGETS2, buf)
buf[2] &= ~CBAUD
buf[2] |= BOTHER
buf[9] = buf[10] = baudrate
assert(fcntl.ioctl(fd, TCSETS2, buf)==0)
fcntl.ioctl(fd, TCGETS2, buf)
if buf[9]!=baudrate or buf[10]!=baudrate:
print("failed. speed is %d %d" % (buf[9],buf[10]))
sys.exit(1)

set_special_baudrate(0, int(sys.argv[1]))


Step 2) Run the script to set your baud rate.
./set_custom_baud_rate.py <> /dev/ttyUSB0 250000

Step 3) You can now monitor your printer output in a terminal window simply with:
tail -f /dev/ttyUSB0

Step 4) And finally, open up a new terminal window, and you can directly send M or Gcode to your printer; example:
echo "M115" >> /dev/ttyUSB0

• Can I ask you how is possible that this script works? I don't understand why you use <>, at first I thought was a typo, but modifying the script and opening the serial directly doesn't modify its baudrate. – gipi Jul 13 '17 at 13:15
• <> on unix opens a file read+write mode, without truncation, and creates the file if it doesn't already exist. i.e system call: open(filename, O_RDWR|O_CREAT) – Mtl Dev Jul 13 '17 at 13:56
• For example, cat < foo.txt it will print the contents of foo.txt, or fail if foo.txt doesn't exist. Whereas cat <> foo.txt,will also print the contents if it exists, but will create the file if it doesn't already exist. – Mtl Dev Jul 13 '17 at 13:59
• I know what <> does, but I don't understand why this works for the baudrate: you are setting the baudrate of the file descriptor 0, i.e. stdin not for the serial port. – gipi Jul 13 '17 at 15:42
• My understanding is the baudrate is simply the first argument to the script, (i.e sys.argv[1]). If you were to modify the script and hardcode a baudrate, and/or open device using the python equiv. of open(filename, O_RDWR|O_CREAT), then I, too, would be surprised if that didn't work. – Mtl Dev Jul 13 '17 at 18:25

you can use screen for that. Open a terminal window and type screen /dev/ttyUSB0 115200 The general form is screen serialdevice baudrate You will then see everything that the printer sends. Everything you type will be send to the printer.

• Thanks! Though does that work with non standard baud rates e.g 250k? I suspect not (at least with Ubuntu/Mint), but that it would be possible to combine the above script, with screen command as per your suggestion. – Mtl Dev Jul 13 '17 at 14:02

This forum page strongly suggests you should be using setserial for a port, not stty , which is for terminals. I'd give the code snippets there a try. Alternatively, stackoverflow has a similar discussion, with somewhat more complicated modifications.

Are you sure you can't talk with your printer at a lower baud rate than the maximum capability of the printer-end?

• You can't lower Marlin's baudrate without recompiling the firmware, I believe. – Tom van der Zanden Dec 1 '16 at 15:23
• @TomvanderZanden bummer :-( – Carl Witthoft Dec 1 '16 at 15:24

That's work solution:

you need 2 terminal, one for in and another for out flows