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

6

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

4
  • 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
  • First you use setserial -a /dev/ttyUSB0 to get Baud_base. Here e.g. 24000000. Then divisor needs to be 96 to get to 250000. Subsequently setserial /dev/ttyUSB0 divisor 96 spd_cust makes it such that when using 38400 a custom speed is selected. Dec 6, 2023 at 22:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .