Reputation: 13
I recently bought a Slice of Radio - https://www.wirelessthings.net/slice-of-radio-wireless-rf-transciever-for-the-raspberry-pi, which I connected to my serial port in an RPi with Raspbian.
I have a temperature+humidity sensor which connects to the Slice of Radio and periodically sends a string of characters with several information, which can be read in the RPi from the serial port (/dev/ttyAMA0).
To read this information and make use of it, I decided to write a Bash script. This information is transmitted concatenated with 12-char strings and each string always starts with a fixed set of characters (in the case, aSD).
This Bash script is supposed to be running in an infinite loop, to make sure that all the information that is sent periodically, is captured and processed as it should.
For that purpose, the following small script works properly:
#!/bin/bash
IFS='aSD'
while read -r -n 12 char1 char2 char3 char4 char5
do
date=`/bin/date -u +%F@%X`
echo $date
echo "1= ""$char1"
echo "2= ""$char2"
echo "3= ""$char3"
echo "4= ""$char4"
echo "5= ""$char5"
done < /dev/ttyAMA0
and outputs the following (every line 4 is the information I need):
2016-02-13@23:06:12
1=
2=
3=
4= RHUM77.0-
5=
2016-02-13@23:06:12
1=
2=
3=
4= TEMP20.0-
5=
2016-02-13@23:11:08
1=
2=
3=
4= RHUM77.0-
5=
2016-02-13@23:11:08
1=
2=
3=
4= TEMP19.9-
5=
2016-02-13@23:11:08
1=
2=
3=
4= BATT3.32-
5=
2016-02-13@23:11:08
1=
2=
3=
4=
5= LEEPING-
Still then, if I run the following script (a simplified version of mine):
!/bin/bash
log_file="/home/pi/logs/Temp_$(date +%Y%m%d).log"
log_file_copy="/home/pi/logs/Temp_$(date +%Y%m%d)_copy.log"
sensor="/home/pi/sensor"
IFS='aSD'
while read -r -n 12 char1 char2 char3 value char5
do
date=`/bin/date -u +%F@%X`
msgid=$( /bin/echo $value | cut -c1-4 )
echo $msgid
if [ "$msgid" = "TEMP" ]; then
#Write current temperature to log file
log=`/bin/date -u +%F@%X`
log+=" | Current Temperature: "
temp=$( /bin/echo $value | cut -c5-8 )
log+=$temp
log+=" ºC"
/bin/echo $log>>$log_file
elif [ "$msgid" = "RHUM" ]; then
#If log file backup still exists, start by deleting it
if [ -f "$log_file_copy" ]; then
/bin/rm $log_file_copy > /dev/null 2>&1 &
fi
#If log file already exists, start by creating a backup
if [ -f "$log_file" ]; then
/bin/mv $log_file $log_file_copy > /dev/null 2>&1 &
fi
#Write current relative humidity to log file
log=`/bin/date -u +%F@%X`
log+=" | Current Relative Humidity: "
rhum=$( /bin/echo $value | cut -c5-8 )
log+=$rhum
log+=" %"
/bin/echo $log>>$log_file
elif [ "$msgid" = "BATT" ]; then
#Write current battery voltage to log file
log=`/bin/date -u +%F@%X`
log+=" | Current Battery Voltage: "
volt=$( /bin/echo $value | cut -c5-8 )
if [ "$volt" != "LOW-" ]; then
volt="LOW"
log+=$volt
else
log+=$volt
log+=" V"
fi
/bin/echo $log>>$log_file
fi
#Store values to display in website - personal.xively.com
time=`/bin/date -u +%FT%XZ`
if [ -n "$temp" ]; then
/bin/echo "$time,$temp">>/home/pi/cosm/sensor/temperature/cosm.csv
fi
if [ -n "$rhum" ]; then
/bin/echo "$time,$rhum">>/home/pi/cosm/sensor/humidity/cosm.csv
fi
if [ -n "$volt" ]; then
/bin/echo "$time,$volt">>/home/pi/cosm/sensor/voltage/cosm.csv
fi
/bin/bash /home/pi/cosm/sensor/upload-cosm.sh > /dev/null 2>&1 &
log=`/bin/date -u +%F@%X`
log+=" | Values sent to xively.com"
/bin/echo $log>>$log_file
done < /dev/ttyAMA0
This is all that it processes:
RHUM
RHUM
RHUM
If I take out the last block of code (to send the values to xively.com), it shows (which is what I need):
RHUM
TEMP
RHUM
TEMP
RHUM
TEMP
I've spent a lot of time trying to find out why doesn't the loop go through all the records and only processes the first one.
Can anyone shed a light or provide any working alternative?
Thanks in advance for any help.
Upvotes: 0
Views: 222
Reputation: 1184
I edited the script for clarity, and ran it against input I made based on your first set of output. I don't think the loop skipped records - perhaps the input didn't match what you expected. The version below captures the raw data to a file, so you can verify the outcomes against the raw data.
#!/bin/bash
PATH=/bin:/usr/bin
log_file="/home/pi/logs/Temp_$(date +%Y%m%d).log"
log_file_raw=${log_file/./_raw.}
while read -r -n 12 dozen
do
echo -n "$dozen" >> $log_file_raw
date=`date -u +%F@%X`
key=${dozen:3:4}
val=${dozen:7}
val=${val%-}
case $key in
TEMP)
log="$date | Current Temperature: $val ºC"
csv=/home/pi/cosm/sensor/temperature/cosm.csv
;;
RHUM)
log="$date | Current Relative Humidity: $val %"
csv=/home/pi/cosm/sensor/humidity/cosm.csv
;;
BATT)
log="$date | Current Battery Voltage: $val V"
csv=/home/pi/cosm/sensor/voltage/cosm.csv
;;
*)
continue
;;
esac
echo "$log" >> $log_file
echo "${date/@/T}Z,$val" >> $csv
/bin/bash /home/pi/cosm/sensor/upload-cosm.sh > /dev/null 2>&1 &
echo "$date | Values sent to xively.com" >> $log_file
done < /dev/ttyAMA0
exit 0
One important change is that this script does not alter IFS. Each character of IFS is a separator. A good example of this is the LEEPING-
for char5 when the input was (presumably) aSDSLEEPING-
. Instead, this script uses the builtin bash substring feature of parameter expansion.
I left out the log rotation, because I want to suggest you log to syslog over the long term. The logger
command will send a message to syslog. On most systems those logs are already rotated on a regular basis.
Upvotes: 1