* Shell io from and to serial device
@ 2019-02-14 0:00 Dominik Vogt
2019-02-14 0:56 ` Ben Klein
2019-02-15 1:02 ` Bart Schaefer
0 siblings, 2 replies; 3+ messages in thread
From: Dominik Vogt @ 2019-02-14 0:00 UTC (permalink / raw)
To: Zsh Users
Hi Folks,
I'm really stuck with this problem. We need a fast, and reliable
way to send a string to a serial device and grep for a certain
reply, and failed to make that work with "expect" - because its
documentation is awful. Anyway, it should be not too difficult to
do with zsh. The task is:
1. configure serial line, e.g. with
$ stty -F /dev/ttyUSB0 speed 115200 cs8 -cstopb -parenb -echo
2. Send some string to the serial line
$ echo foo > /dev/ttyUSB0
3. Grep for a certain reply with configurable, sub second timeout.
$ ??????
4. In case of a timeout, all input from the serial line is stored
in a file or shell variable.
There should be no noticeable delay if the expected reply shows
up immediately.
Something like this should do it:
-- snip --
#!/usr/bin/zsh
set -u
set -C
SEND="$1"
EXPECT="$2"
TIMEOUT="$3"
DEV="$4"
LOGFILE="$5"
shift 5
trap "exit 1" TERM
# serial setup
stty -F "$DEV" speed 115200 cs8 -cstopb -parenb -echo > /dev/null
# watchdog process
{ sleep "$TIMEOUT"; echo "timeout" 1>&2; kill 0 2> /dev/null; } &
# child sends string with delay
{ sleep 0.01; echo "$SEND" > "$DEV" } &
rm -f "$LOGFILE"
# parent waits for reply
tee "$LOGFILE" < "$DEV" |
while read LINE; do
if { cat <<EOF
$LINE
EOF
} | grep -q "$EXPECT"
then
trap : TERM
kill 0 2> /dev/null
exit 0
fi
done
exit 1
-- snip --
But this looks really complicated and the "sleep 0.01" is
annoying. There must be an easier way.
Also, I'm not convinced that "tee" won't buffer serial input and
cause a timeout, although on the test machine it doesn't.
Ciao
Dominik ^_^ ^_^
--
Dominik Vogt
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Shell io from and to serial device
2019-02-14 0:00 Shell io from and to serial device Dominik Vogt
@ 2019-02-14 0:56 ` Ben Klein
2019-02-15 1:02 ` Bart Schaefer
1 sibling, 0 replies; 3+ messages in thread
From: Ben Klein @ 2019-02-14 0:56 UTC (permalink / raw)
To: dominik.vogt, Zsh Users
[-- Attachment #1: Type: text/plain, Size: 2579 bytes --]
I don't know if you have this available, but `timeout` is a common utility
program: https://manpages.ubuntu.com/manpages/cosmic/en/man1/timeout.1.html
(It's
GNU)
So you could start the whole grep pipeline with that command in a new
shell, or if you wanted you could do a callback to a parent ZSH process
like the zsh-async does with SIGWINCH, catch that and kill a job. (You
could enable job control then kill %0 or similar when you get the
interrupting signal back.)
On Wed, Feb 13, 2019 at 7:01 PM Dominik Vogt <dominik.vogt@gmx.de> wrote:
> Hi Folks,
>
> I'm really stuck with this problem. We need a fast, and reliable
> way to send a string to a serial device and grep for a certain
> reply, and failed to make that work with "expect" - because its
> documentation is awful. Anyway, it should be not too difficult to
> do with zsh. The task is:
>
> 1. configure serial line, e.g. with
>
> $ stty -F /dev/ttyUSB0 speed 115200 cs8 -cstopb -parenb -echo
>
> 2. Send some string to the serial line
>
> $ echo foo > /dev/ttyUSB0
>
> 3. Grep for a certain reply with configurable, sub second timeout.
>
> $ ??????
>
> 4. In case of a timeout, all input from the serial line is stored
> in a file or shell variable.
>
> There should be no noticeable delay if the expected reply shows
> up immediately.
>
> Something like this should do it:
>
> -- snip --
> #!/usr/bin/zsh
>
> set -u
> set -C
>
> SEND="$1"
> EXPECT="$2"
> TIMEOUT="$3"
> DEV="$4"
> LOGFILE="$5"
> shift 5
>
> trap "exit 1" TERM
>
> # serial setup
> stty -F "$DEV" speed 115200 cs8 -cstopb -parenb -echo > /dev/null
> # watchdog process
> { sleep "$TIMEOUT"; echo "timeout" 1>&2; kill 0 2> /dev/null; } &
> # child sends string with delay
> { sleep 0.01; echo "$SEND" > "$DEV" } &
> rm -f "$LOGFILE"
> # parent waits for reply
> tee "$LOGFILE" < "$DEV" |
> while read LINE; do
> if { cat <<EOF
> $LINE
> EOF
> } | grep -q "$EXPECT"
> then
> trap : TERM
> kill 0 2> /dev/null
> exit 0
> fi
> done
> exit 1
> -- snip --
>
> But this looks really complicated and the "sleep 0.01" is
> annoying. There must be an easier way.
>
> Also, I'm not convinced that "tee" won't buffer serial input and
> cause a timeout, although on the test machine it doesn't.
>
> Ciao
>
> Dominik ^_^ ^_^
>
> --
>
> Dominik Vogt
>
--
*\Ben Klein*
Founder and Owner of Robosane, robobenklein@robosane.net
You can find me elsewhere online as 'robobenklein'.
If you need to contact me securely, I am also reachable via GPG, or on
Keybase.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Shell io from and to serial device
2019-02-14 0:00 Shell io from and to serial device Dominik Vogt
2019-02-14 0:56 ` Ben Klein
@ 2019-02-15 1:02 ` Bart Schaefer
1 sibling, 0 replies; 3+ messages in thread
From: Bart Schaefer @ 2019-02-15 1:02 UTC (permalink / raw)
To: dominik.vogt, Zsh Users
On Wed, Feb 13, 2019 at 4:01 PM Dominik Vogt <dominik.vogt@gmx.de> wrote:
>
> 1. configure serial line, e.g. with
>
> $ stty -F /dev/ttyUSB0 speed 115200 cs8 -cstopb -parenb -echo
>
> 2. Send some string to the serial line
>
> $ echo foo > /dev/ttyUSB0
You might get better results using "printf" rather than "echo",
depending on how precise you need to be about what is sent to the
device (where newlines appear, etc.).
> 3. Grep for a certain reply with configurable, sub second timeout.
I think what you want to do here is use "read -E" combined with
"zselect -t" (assuming you have a recent zsh where zselect accepts
hundredths of a second timeouts).
I have a bit of trouble following your example script (what the heck
is that "cat <<EOF" doing in there?), and you haven't said anything
about the "protocol" used on the serial device (is every write by
either side supposed to end with a newline, for example?) so it's hard
to be specific, but something like:
trap "kill 0 2>/dev/null" EXIT
stty -F "$DEV" speed 115200 cs8 -cstopb -parenb -echo > /dev/null
{ zselect -t 1 -w 1 && printf "%s\n" "$SEND" > "$DEV" } &
# $TIMEOUT has to be adjusted to be 100ths before doing this;
# adjusted $TIMEOUT better be > 1 or this will always fail
coproc { zselect -t $TIMEOUT -r 0 || kill 0 2>/dev/null }
# This assumes the "other end" always sends full lines
while read -E LINE >> "$LOGFILE"; do
print -r -- "$LINE"
done | grep --max-lines=1 --quiet "$EXPECT"
# If not exiting here, "print -p $?" to end the coproc
exit $?
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2019-02-15 1:03 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-14 0:00 Shell io from and to serial device Dominik Vogt
2019-02-14 0:56 ` Ben Klein
2019-02-15 1:02 ` Bart Schaefer
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).