4

I am connecting to a serial port using screen: screen /dev/cu.usbserial-A703XAOG. The device on the other end sends only a carriage return to separate lines. Screen only starts at the beginning of the line when receiving a carriage return, and does not go down a line, and thus overwrites the last line of output with the next line of output.

I can change the icrnl setting of the serial port, and it will convert the carriage return to a line feed. Although screen now goes down a line before writing the next line of output, it doesn't start at the beginning when receiving only a line feed.

I dumped the .termcap file using the Ctrl-A, Ctrl+.. I read up on termcap and I learned that:

If the terminal has a command that moves to the first column of the next line, that command can be given as nw (newline).

source

So this is my current ~/.screenrc file:

termcap SC nw=^M

Where SC matches the name in the dumped .termcap file.

This does not give the effect that I hoped for. Maybe the termcap command is not the way to go?

How can I make screen go down a line AND start at the beginning when receiving only CR from a serial device?

Edit:

Here is the output of sudo stty -f /dev/cu.usbserial-A703XAOG -a when screen is connected to the serial port:

speed 9600 baud; 0 rows; 0 columns;
lflags: -icanon -isig iexten -echo echoe echok echoke -echonl echoctl
        -echoprt -altwerase -noflsh -tostop -flusho -pendin -nokerninfo
        -extproc
iflags: -istrip -icrnl -inlcr -igncr -ixon -ixoff -ixany -imaxbel -iutf8
        -ignbrk brkint -inpck ignpar -parmrk
oflags: -opost -onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd -hupcl clocal -cstopb -crtscts -dsrflow
        -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = ^@; eol2 = ^@;
        erase = ^?; intr = ^C; kill = ^H; lnext = ^V; min = 100;
        quit = ^\; reprint = ^R; start = ^Q; status = ^T; stop = ^S;
        susp = ^Z; time = 2; werase = ^W;

Edit:

I understand some software may solve this, for example, in PuTTY I would need to enable the "implicit LF in every CR" setting, and in Serial I would need to enable "Interpret Standalone CR as CRLF". But my question is specifically about screen, because that is the software I am using currently to connect to the serial port.

Edit:

Screen emulates the VT100 terminal, and it should recognize control sequences (source). I need to set "Automatic Linefeed Mode" (also known as new line mode). This should be done using the set mode control sequence with the parameter value 20: ESC [ 20 h.

How can I pass this control sequence to screen?

5
  • you may have better luck using software like minicom with a serial device Aug 12, 2019 at 23:18
  • @RafaelKitover Yes, I understand some software may solve this, but my question is related to screen, because that is the software I am using currently to connect to the serial port. Aug 13, 2019 at 7:42
  • 1
    @roaima I have added the serial port settings to my question. Aug 13, 2019 at 7:43
  • Thanks. Is stty -a from inside screen any different? Aug 13, 2019 at 8:09
  • Yes, many differences. But that is after running screen, so it's not connected to a serial port, but to Bash. Aug 13, 2019 at 10:33

1 Answer 1

1

Something that seemed to work for me was to manipulate the pseudo-tty that screen has by sending it the newline mode escape sequence you found, and also giving it an stty command to convert the carriage return to a newline. Use ps a to find the pty:

16947 pts/4    Ss+    0:00 screen -S myscreen /dev/ttyS0

and then give the commands

pty=/dev/pts/4
stty -F $pty  ocrnl
echo -en '\e[20h' >$pty
4
  • Thanks for the insightful answer. I could already change the settings of the serial port after the connection is open, by executing sudo stty -f /dev/cu.usbserial-A703XAOG icrnl in a separate Terminal tab. Notice that I need to set icrnl, not ocrnl. But trying to send the control sequence to the serial port by executing sudo echo -en '\e[20h' >/dev/cu.usbserial-A703XAOG gives an error: "-bash: /dev/cu.usbserial-A703XAOG: Resource busy". I am running this on macOS. Aug 17, 2019 at 18:52
  • 1
    Your sudo echo... will fail because the >/dev/... is being done by the shell before the sudo takes effect. You would need to messily quote it all: sudo sh -c 'echo -en '\''\e[20h'\'' >/dev/...'. But I am operating on the pty that screen creates for every virtual terminal, not the real tty. This makes it easier as I don't need to be root and explains why I used ocrnl rather than icrnl. It seems to work for me on Linux, and I would have thought it should also work on MacOS, though I cannot try.
    – meuh
    Aug 17, 2019 at 19:10
  • Ok, this makes sense, again, thanks for bringing insight by explaining the details (about sudo and redirection). On macOS, the screen process also has a TTY associated with it: ttys001. So I executed echo -en '\e[20h' >/dev/ttys001 and the result is that in screen this text is literally shown: "\e[20h". I tried to echo a different escape sequence: echo hello\tworld, and the result is "hello world" where the white space is a tab. So there is something with the \e escape sequence that is not right yet. Aug 19, 2019 at 8:56
  • 1
    Using \033 instead of \e works. And using the pseudo terminal, I can also use ocrnl instead of icrnl, which makes more sense. Aug 19, 2019 at 9:04

You must log in to answer this question.

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