5

I wish to directly monitor the serial-over-usb connection to my 3d printer, which runs at 250000 baud. e.g I might monitor it with cat /dev/ttyUSB0

However first I need to set the baud rate, e.g stty -F /dev/ttyUSB0 115200

But if I try and set the baud rate to 250k, it fails:

stty -F /dev/ttyUSB0 250000

gives result:

stty: invalid argument 250000

It appears that baud rate 250000 is not supported under Ubuntu/Mint. Can anyone suggest an alternative way to monitor this serial connection?

3
  • 1
    Try screen /dev/ttyUSB0 250000, but afaik, you can only stablish one serial connection, so it's monitorization or 3d printer
    – Mc Kernel
    Dec 1, 2016 at 17:09
  • 250000 is a non-standard bitrate, but stty -F /dev/ttyUSB0 500000 works. I couldn't get 250000 with stty, screen, setserial, python, or whatever else I tried. I eventually gave up, recompiled and set bitrate to 500000 in 3D printer firmware. It turned out to be easy. I get faster transfers. And the Configuration.h header file comment said it could even speed up the 3D printer's sd-card access.
    – hellork
    Sep 30, 2021 at 4:43
  • That's a great tip thanks. Just curious if you tried the below mysetbaud.py? It should allow you to set the baud rate to stty...250000. (not that you need to any more)
    – Mtl Dev
    Sep 30, 2021 at 21:25

2 Answers 2

5

There are some undocumented ioctls you can use to set non-standard speeds, provided the driver implements them. A simple way to call them is with a small piece of python. Eg put in file mysetbaud.py and chmod +x it:

#!/usr/bin/python
# set nonstandard baudrate. 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]))

This takes some code from the pyserial package with constants for the various values needed from Linux C include files, and an array for the struct termios2. You use it with a baud rate parameter and your device on stdin, eg from bash:

./mysetbaud.py <>/dev/ttyUSB0 250000
1
  • 1
    Thankyou that worked perfectly! Amazing. I can now directly send Gcode to the printer, example: echo "M115" >> /dev/ttyUSB0 while monitoring the status in another terminal with just tail -f /dev/ttyUSB0
    – Mtl Dev
    Dec 1, 2016 at 20:23
4
setserial -a /dev/ttyUSB0 spd_cust
setserial -a /dev/ttyUSB0 divisor 96

Now set the port to 38400 to get 250000

stty -F /dev/ttyUSB0 38400

(or use it as 38400 in an application, e.g. ser2net)

Got my info from http://www.linurs.org/linux/SerialPort.html

3
  • This worked great for connecting to my 3D printer. I used the first two commands and then "screen /dev/ttyUSB0 38400". I can type to the printer and receive output, too.
    – Eyal
    Apr 26, 2018 at 14:11
  • Would append that setserial -a /dev/ttyUSB0 displays Baud_base by which you can determine the divisor value to use. Apr 10, 2019 at 13:42
  • Why 96? 250000 / 38400 = 6.51. Can you elaborate? Sep 27, 2021 at 23:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.