5

I am using screen to communicate with arduino over serial port, i start screen like this:

screen /dev/ttyACM0 115200

then I try to send a command but every key I press on the keyboard get sent straight away, how to make it wait until I press Enter key before sending input to arduino?


Here's my serial device /dev/ttyACM0 settings:

$ sudo ssty -F /dev/ttyACM0 -a
speed 115200 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^H; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 100; time = 2;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread clocal -crtscts
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -flusho -extproc

My .screenrc file is empty.

  • -icanon indicates canonical (line-based) processing is disabled, so one thing to try would be using stty to flip that (the screen docs I have don't list a direct means to change that). – thrig Nov 10 '16 at 21:13
  • @thrig I enabled icanon with sudo stty -F /dev/ttyACM0 icanon but nothing changed. – razzak Nov 10 '16 at 21:20
  • Hmm, is there a different tty that screen is presenting to type in whose inputs then get shuffled off to ttyACM0? (Other options to consider include minicom or on OpenBSD cu is maintained.) – thrig Nov 10 '16 at 21:38
  • 1
    You can't. ttyACM0 is unbuffered. See if using stdbuf syscall makes a difference. – ErectCrested Apr 17 at 18:08
  • You should use a terminal emulator (minicom, for example), it'll set up the terminal for you properly. stty could also work, but it's a pain to use it in such a way. Also, make sure that your host system is not trying to run a getty on your serial line! It could interfere with your activity. – Laszlo Valko Apr 20 at 14:01
2

I don’t work with Arduino devices, so I can’t be of specific help, but in lack of other answers I can try and give you some general hints (for the UNIX/Linux side) as to how address your particular problem.

Unfortunately there’s no setting you can give to your serial port to make it send data in lines. That is a responsibility of the application, i.e. the terminal emulator you use, screen in your case. But I’m afraid (AFAIK) that neither screen nor other terminal emulator applications allow a line-oriented mode of what you type.

You might rather obtain something usable with tools like expect, or minicom’s companion command runscript (which is along the lines of expect), which normally do send data in lines.

Otherwise, as another possibly good resort, you might implement a (very) rudimental line-oriented “terminal application” yourself.

As crazy as this normally is, it might turn out very easy to do it for your specific case, with just a few commands from the shell.

(
set -e
prev_settings="$(stty -g -F /dev/ttyACM0)"
trap 'stty "${prev_settings}" -F /dev/ttyACM0' EXIT
stty -F /dev/ttyACM0 raw -echo -echoe -echok -echoctl -echoke
cat < /dev/ttyACM0 &
cat > /dev/ttyACM0
)

The set -e just serves to quit execution at the first error (if any) encountered by the following commands.

The stty -g saves the serial port’s current settings.

The trap sets up the restoring of the saved settings on EXIT from the commands.

The stty raw ... sets (what I think should be) the sanest (for this particular case) settings to the serial port.

The first cat command just outputs to your terminal window whatever comes from the Arduino.

The second cat command sends to the Arduino whatever you type from then on.

To quit this bunch of commands, just type Ctrl-C.

The “trick” here is simply that the cat command, by design, sends output line by line, as you requested.

On the other hand, the input cat command (the first cat) shows you immediately each single character coming from the Arduino thanks to the stty raw setting. If the Arduino happens to send streams of data, you might want to add the min 100 time 2 settings that I see in your current stty -a output. That might display things a bit faster in case of streams.

The parentheses serve to run these commands in a subshell, which is handy to restore the tty settings thanks to the trap command. You may also put the commands in a script (naturally without the parentheses) and then run that.

Note that it’s best if you quit or otherwise suspend any other application that might access the serial port while you use the above commands, otherwise they might interfere with each other.

This simple solution works best if your Arduino device does not echo back what it receives. If it does, you’ll just see twice whatever you type, once for your actual typing, and again for the echoing from the Arduino. The thing is, what you see on your terminal cannot be controlled by Arduino because of the line-oriented setup. It can be possible to turn off that too (by acting locally to turn off character displaying), but I suppose you prefer to see what you’re typing before you send it to Arduino.

One final (and hopefully irrelevant) thing I note is that your serial port is classified as ttyACM. This normally means that the serial port you’re using has advertised itself as capable of some additional feature, otherwise it would have been classified by the system as a more generic ttyUSB port. Being a ttyACM is more typical of specialized serial devices (such as 3G/4G cellular modems) rather than simple serial ports. However it can be just a serial port with a silly chip, and in practice this should not pose any real problem, but who knows..

HTH

  • Thanks for the detailed answer. It's been a long time since I was experimenting with arduino. I will try to test your suggestions next time I work with arduino, but it may take a while. – razzak Apr 24 at 8:02

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.