Noob help with bash scripting

I have two questions....the first I think I already know the answer to: I am programming a Uno, and I can communicate with the board using the IDE serial monitor, and with sleep /dev/ttyACM0. But, if I try to communicate from the shell, the only thing that works is cat after the program is running. Tail does not work and echo does not work. From reading on the forum, I need a capacitor to jumper between the reset and 5V pins, correct? CouldI use the 3V pin instead, or does it have to be the 5V pin?

My second question is how to end monitoring of the serial port with cat to close the file and end the bash script. Does anyone have example code where a bash script reads Arduino output into a text file and then terminates somehow?

Thanks!!!

From reading on the forum, I need a capacitor to jumper between the reset and 5V pins, correct?

To stop the Arduino from resetting when the serial port is opened or closed, yes.

CouldI use the 3V pin instead,

No.

or does it have to be the 5V pin?

Yes. You can have multiple things connected to the 5V pin.

zeke: My second question is how to end monitoring of the serial port with cat to close the file and end the bash script. Does anyone have example code where a bash script reads Arduino output into a text file and then terminates somehow?

If you send one byte with a numeric value 5, then I think cat will take that as the EOT (end of transmission). That's CTRL_D, by the way.

justjed: If you send one byte with a numeric value 5, then I think cat will take that as the EOT (end of transmission). That's CTRL_D, by the way.

Not true. First, ctrl-D is value 4 :-) However, more importantly, the ctrl-D-means-EOT behavior of UNIX comes from the "cooked" terminal driver that the environment sets up for you when you log in. "cat" does no such setup on the tty that it opens, so ctrl-D will just come out as ctrl-D.

The best thing to do is probably to write the program you need in something like C, Python or Perl, where doing character I/O is simple. Something like (untested Python):

#!/usr/bin/env python
import sys, os;

f = open(argv[1], 'rb')
if not f:
  print('usage: program.py /dev/ttywhatever')
  sys.exit(1)
while True:
  ch = f.read(1)
  if ch == chr(4):
    break
  sys.stdout.write(ch)

Start it with "myprogram.py /dev/ttywhatever" It will stop when it sees the character valued at 4 come in. (You can change chr(4) to something like '$' if you want to stop on a $)

jwatte:
Not true. First, ctrl-D is value 4 :slight_smile: However, more importantly, the ctrl-D-means-EOT behavior of UNIX comes from the “cooked” terminal driver that the environment sets up for you when you log in. “cat” does no such setup on the tty that it opens, so ctrl-D will just come out as ctrl-D.

Eh, must’ve been reading ‘man ascii’ with my head sideways. Should’ve just counted on my fingers. :slight_smile:

I wonder about the raw and the cooked. As long as you’re sending ascii values over the line, is there reason why you couldn’t use stty to set that port cooked? cat isn’t going to do anything one way or the other, I think, so if you set it cooked before invoking cat, it should stay that way.

Well anyway, I found my buried cable and plugged in my Uno:

$ stty -a -F /dev/ttyACM0
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;

So, it’s calling it eof instead of EOT. Looks sorta cooked.

ETA: Huh. I tried with a little test sketch I have for using analog buttons. Initially, I just did cat < /dev/ttyACM0 and got the output from the sketch just as it’s supposed to be. So I added in code to do a Serial.print(byte(4)); after a some iterations, and it shows up in the serial monitor as a non-printing character. But when I do the cat command now, it exits immediately. From what I can tell in the serial monitor, the EOT isn’t getting sent right off, and I can see the Uno reset when I issue the cat command. Well, too late tonight to bang on it any more. Also, tail /dev/ttyACM0 gets the output, but of course it won’t exit on EOT.

Thanks everyone, got it working. I used some C code I found and merged it with justjed's EOF suggestion. I can now send and receive data from my board!!!!! :grin:

With the jumpered connection, I can't upload a new sketch...I assume I can't use avrdude from a script to do it either?

If I want to be able to change the program the Arduino is running from a script, is there no way to do that and still maintain my ability to send and receive data?

I could see putting a switch on the jumper, but that is pretty clunky, and would have to be integrated into the timing of the script.

Cool you got it working.

I could be wrong, but I think you need the reset on serial comm to upload because the bootloader has a brief delay where it looks for a new sketch coming in, before it loads the existing program to run.

I need to come back to this and check if/how the IDE changes the serial settings, to see if that's why the cat command stopped working once I'd uploaded a new sketch.

So when I took out the jumper, the C code kept on working, and I can upload programs with no problem, so I think my problem is solved!!!!

Woohoo!

Thanks everyone.....