Skip to content

Instantly share code, notes, and snippets.

@jhgorse
Last active December 19, 2021 23:44
Show Gist options
  • Save jhgorse/bb1fdd9f81ef11035ba792fa5037a33d to your computer and use it in GitHub Desktop.
Save jhgorse/bb1fdd9f81ef11035ba792fa5037a33d to your computer and use it in GitHub Desktop.
Poll serial device at 2 Hz write/read using Bash, Screen, bc
#!/bin/bash
set -x # debug
# This polls the windows serial device over screen(1) connection
# with one command and one response.
# Clean the data point, print to stdout and log it to LOGFILE.
# Uses named pipe, unix fifo, attached to bash fd 4 to take the serial data.
if [[ "Darwin" != $(uname) ]]; then # windows
cd /home/joeg/Work/collector_data
STTYDEV="/dev/ttyS$(mode.com | grep COM | sed -e 's/.*\([0-9]\).*/\1/' | head -n 1)"
DATE=date
else # macos
cd ~/Work/collector_rev_c
STTYDEV="$(ls /dev/tty.usb*)"
DATE=gdate # gnu coreutiles from brew to get %N
fi
NL=$(echo -ne '\015') # darwin needs it, wsl linux can use \r or \n
DELAY=0.5 # seconds
CMD="gt2"
CMD="ffr"
SCREEN_NAME="SCOL"
FIFO=/tmp/fifo_s
LOGFILE="$($DATE +%Y-%m-%d_%T)_logfile"
function egress {
set -x
screen -S $SCREEN_NAME -p0 -X colon "quit$NL"
rm -f $FIFO
}
trap egress EXIT
# this sequencing is important with the fifo and screen
if [[ ! -p $FIFO ]]; then
mkfifo $FIFO
fi
screen -dmS $SCREEN_NAME $STTYDEV 115200 # headless -dm
screen -S $SCREEN_NAME -p0 -X colon "logfile $FIFO$NL"
screen -S $SCREEN_NAME -p0 -X log on
screen -S $SCREEN_NAME -p0 -X logfile flush 0
exec 4<>$FIFO # fd 4 fifo, named pipe, used for temp buffer
$DATE "+%Y-%m-%d_%H:%M:%S.%3N"
# TODO: link -ls logfile_latest to the last $LOGFILE
# screen -S $SCREEN_NAME -p0 -X stuff "$CMD$NL" # put one in the queue
while :; do
# use \r for the command, \n for the log
t1=$($DATE "+%S%3N")
screen -S $SCREEN_NAME -p0 -X stuff "$CMD$NL"
sleep 0.1
read -ru 4 REPLY # this line takes 433 ms
t2=$($DATE "+%S%3N")
echo $($DATE "+%T.%3N ") $(echo $REPLY | sed -e "s/$CMD$NL//") | tee -a $LOGFILE
set -x
dt=$(bc <<< "($t2-$t1) / 1") # millis
if [[ $dt -lt 0 ]]; then dt=60000+$dt; fi # handle boundary condition for 60 second rollover
ddt=$(bc <<< "($DELAY*1000 - 0.1*1000 - $dt) / 1")
# if dt elapsed time is less than desired delay time, delay for what is left
if [[ $ddt -gt 0 ]]; then
sleep $(bc <<< "scale=3;$ddt/1000.0")
fi
set +x
done
# TODO: read can take more than 400 ms to complete, work around it with extra reading in fifo
# or something else that reads one string from fifo up to the newline.
#
# $(echo -ne '\015')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment