Tuesday, December 13, 2011

Time tagging data streams using a short bash script

I've often had to write Arduino sketches and small PIC programs to read data from sensors for transmission to a PC over the serial link. This is mostly for testing and evaluating sensors in the lab – so I don't want to waste any more time than I have to writing software.  

A common requirement is to have each sensor record time tagged. However implementing a real time clock on a Arduino, PIC etc can be a lot of hassle. It makes more sense to tag the record on the PC as it comes in.

Here is a short bash shell script that runs on a Linux PC which reads data from an input stream (usually the serial port) line by line and prefixes each line with the unix epoch time (seconds since 1 Jan 1970):

while read line ; do
    echo `date +%s` $line

So, for example, right now I have an Arduino sketch polling a SHT75 temperature humidity sensor. The Arduino is writing a record (about 1 every second) with the current temperature and humidity. The data looks like this:

19.70 49.22
19.70 49.38
19.68 49.38
19.66 49.22

This is coming in on /dev/ttyUSB2 in this case. The above script is in file timetag.sh. On the PC I do:

cat /dev/ttyUSB2 | bash timetag.sh > sensor.log

sensor.log looks like this:

1323808719 19.70 49.22
1323808720 19.70 49.38
1323808721 19.68 49.38
1323808723 19.66 49.22

The data can now be plotted with the insanely useful gnuplot utility like this:

$ gnuplot

set title "Temperature and Relative Humidity from SHT75 sensor"
set grid
set xlabel "Time"
set ylabel "Temperature (C) / Relative Humidity (%)"
set xdata time          # X axis is time
set timefmt "%s"     # Input file time format is unix epoc time
set format x "%R"   # Display time in 24 hour notation on the X axis
plot 'sensor.log' using 1:2 title 'T', 'sensor.log' using 1:3 title 'RH'

If you don't like the unix time notation, you can use alternative notations. See the manual page for the unix date command to get alternative time formats. You'll need to match the date format with the gnuplot 'set timefmt' command (help timefmt inside gnuplot will display available formats). For plots spanning more than one day you'll need to adjust time labeling with 'set format x' command (help set format time_specifier will provide information on this).

No comments: