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?


    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’

  • Mtl Dev

    Mtl Dev Correct answer

    5 years ago

    For direct low-level printer control from a terminal, without specific software, I found the following solution with full credit thanks to user:

    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).

    # set nonstandard baudrate. Original Question:
    import sys,array,fcntl

    # from /usr/lib/python2.7/site-packages/serial/
    # /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]))

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

    Step 2) Run the script to set your baud rate.

    ./ <> /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.

    ``<>`` 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)``

    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.

    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.

    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.

    @gipi The "<> /dev/ttyUSB0" argument defines stdin and stdout for the script. When the script operates on stdin, it is operation on /dev/ttyUSB0.

    This didn't work for me, nor this guy: The tail command doesn't output anything The printer seems to thing "ok" is an unknown command, which is its response, right? So why is it receiving its own response as a command?

License under CC-BY-SA with attribution

Content dated before 7/24/2021 11:53 AM