23

So I have a standard RS232 serial port that is looped back to itself by simply running a wire from Tx to Rx. I'm testing loopback by running echo and cat in two separate terminals:

cat /dev/ttyS1
echo "hi" > /dev/ttyS1

My issue is with the output. I would expect to see one "hi" come back on the terminal running cat but instead I get this:

hi
[2 newlines]
hi
[4 newlines]
hi
[8 newlines]
hi
[16 newlines]
hi
[32 newlines]
hi

...and so on until I ctrl+c cat.

After interrupting cat, if I run it again it will not output "hi"s until I run echo a second time.

Is this normal? Any idea why I'm seeing this behavior?

Edit: By newline, I mean ASCII 0x0A. There are no carriage returns in this output.

2
  • Could it be caused by having two processes opening the same device? What if you run tip /dev/ttyS1 (~. to exit) and tried typing data there? It should be displayed in your terminal when the wire is connected, as it receives what it has transmitted.
    – mrb
    Commented Jul 13, 2012 at 14:41
  • 3
    Are you really getting newlines, or a carriage-return/newline pair? The distinction is important at the level you're working. Try "cat /dev/ttyS1 > somefile" then do "od -x somefile" to see exactly what bytes are coming out of the TTY device file. Also, do an "stty -F /dev/ttyS1 -a". Read the man page for "stty" and look at what the output of stty tells you, for every little setting. RS232 serial comms are tricky.
    – user732
    Commented Jul 13, 2012 at 15:26

2 Answers 2

25

Thanks to the second comment by Bruce, I was able to figure out the problem on my own.

After running stty -a -F /dev/ttyS1, there were 3 options I found to contribute to the problem: "echo", "onlcr", and "icrnl".

Since this serial port is looped back to itself, here is what happened after running echo "hi" > /dev/ttyS1:

  1. The echo command appends a newline to the end of the message by default, so "hi" + LF is sent out to /dev/ttyS1
  2. Because "onlcr" was set, the serial device converted the LF to CRLF so the physical message sent out the Tx line was "hi" + CRLF
  3. Because "icrnl" was set, the physical messaged received on the Rx line converted the CR to LF. So the message outputted by 'cat' was "hi" + LFLF.
  4. Because "echo" was set, the message received on the Rx ("hi" + LFLF), was then sent back out on the Tx line.
  5. Because of onlcr, "hi" + LFLF became "hi" + CRLFCRLF.
  6. Because of icrnl, "hi" + CRLFCRLF became "hi" + LFLFLFLF
  7. Because of echo, "hi" + LFLFLFLF was then sent out the Tx

And so on...

In order to fix this problem, I ran the following command:

stty -F /dev/ttyS1 -echo -onlcr

Disabling "echo" prevents an infinite loop of messages and disabling "onlcr" prevents the serial device from converting LF to CRLF on output. Now cat receives one "hi" (with a single newline!) for each time I run echo.

CR = carriage return (ASCII 0x0D); LF = line feed or newline (ASCII 0x0A)

1
  • 1
    -icrnl did the trick for me.
    – tcpaiva
    Commented Sep 26, 2019 at 20:31
6

I had a similar issue as well with concatenating files into a serial tty for testing. In addition to the accepted answer:

If you're testing serial output by doing something like: cat somefile.txt > /dev/ttyS0, it will have a good amount of unexpected byte data if you're testing for exact byte values.

With stty doing a simple stty raw -F /dev/ttyS0 will stop the terminal from inserting/replacing characters (e.g. [...] 0x0A [...] -> [...] 0x0D 0x0A [...]). The raw flag changes the modes of the terminal so no input and output processing is performed.

2
  • 4
    Hmm... doesn't look like stty raw will disable echoing by default. You may need to do stty raw -echo.
    – BMiner
    Commented Dec 23, 2013 at 23:43
  • sudo stty raw -F /dev/ttyUSB0 -echo fixed it for me.
    – fadedbee
    Commented Mar 12, 2020 at 14:21

You must log in to answer this question.

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