Application Note 1

Logging DACS Data with a Bash Shell Script


The BOBZ Data Acquisition and Control System (DACS) provides an easy way to monitor and control using a serial connection and terminal. However, DACS can also be used effectively when data acquisition and control is performed automatically with the use of scripts or a microprocessor. The following provides a simple example of how a Linux processor running Debian, such as a Raspberry Pi, can control a DACS using a simple bash shell script.

There are many scripting options available in a Linux/Debian environment and bash shell scripting may not be the best choice if you are new to scripting and programming on a Linux machine. Perhaps the best investment of time would be in learning PERL or learning to program in Python. However, the bash shell is usually loaded and ready to go so this example uses what is readily available to provide a quick demonstration of DACS scripting.

Example Script

Figure 1 shows a shell script that acquires DACS data whenever it is executed at a command line. The following sections refer to this script and to individual numbered lines within it. You can download a tar archive of the script, cron_dacs_v1.tgz.

To extract the script from the tar archive, enter: tar -xvf ./cron_dacs_v1.tgz at a command prompt. Note that this command line assumes that the archive file is in the current directory, which is most likely the download directory you selected or your default download directory.

We suggest moving the extracted file to your local "bin" directory (i.e., "~/bin"). You may have to change the permissions on the extracted file using a command such as "sudo chmod 755 ./" before using it.

The first part of the script, shown in Figure 1 above, consists of the usual boilerplate describing the name, date, purpose and usage of the script. Following this, starting at line 14, is a section for declaring script variables (i.e., with "declare").

On line 15, the first declaration is the string to send to read analog input 1. Note that the string includes a blank at the end to terminate DACS input.

Line 16 specifies the name and location of the output file. In this case, the location is a logs directory for the current user, bob.

Lines 17 and 18 define two temporary files (each with a PID appended, per usual practice).

Page 2

Example Script (Cont.)

     1    #!/bin/bash
     2    #
     3    # -- 140531rjn
     4    #
     5    # Description:
     6    # 1. Reads dacs analog 1 with the "v1" command. 
     7    # 2. Date/time tagged reading is appended to the output file for plotting.
     8    # 3. Serial port setup is in this script. Response captured with bg. task.
     9    # 4. Now set up to read values once an hour in a cron task.
    10   # 5. Usage: ./
    11   #
    12   shopt -s -o nounset  # disallow uninitialed variables
    13   # 
    14   # ----- variables
    15   declare RA="v1 "  # the "v1" command reads the voltage on analog input 1
    16   declare DOUT="/home/bob/logs/dacs_v1.txt"    # dacs output file
    17   declare TMP0="/tmp/tmp0.$$" ; touch ${TMP0}  # temp file
    18   declare TMP1="/tmp/tmp1.$$" ; touch ${TMP1}  # temp file
    19   declare PORT="/dev/ttyUSB0"  # serial port device name
    20   #
    21   stty -F ${PORT} 19200     # serial port setup
    22   cat ${PORT} >> ${TMP0} &  # bg. task to capture serial out from stdout
    23   bgPid=$?    # save PID of serial bg. task
    24   echo ${RA} > ${PORT}      # send the command to dacs
    25   sleep 0.1   # wait for bg. task to complete
    26   # send date/time and edited serial output to output file
    27   echo  `date '+%y%m%d-%T'` `cut -c 4-8 ${TMP0}` >> ${DOUT}
    28   rm ${TMP0} ${TMP1}        # delete temp files
    29   kill $bgPid  # kill bg. task
    30   exit 0

Figure 1. Script to Capture DACS Analog 1

Page 3

Example Script (Cont.)

Line 19 specifies the device name of the serial port attached to DACS. The serial port device name, /dev/ttyUSB0, may have to be changed, depending on your system's naming conventions and whether or not the scripts uses a direct serial connection or a USB to serial adapter. To see what serial devices are mapped, use a command such as: dmesg | grep "ttyUSB" or dmesg | grep "tty".

If using the hardware port on a Raspberry Pi, the serial device is: /dev/ttyAMA0.

The command stty -F ${PORT} 19200 in Line 21 sets up the serial port to use the DACS baud rate of 19.2K baud. Line 22 gets output from the serial port and puts it in a temporary file. The serial port capture is performed as a background task (specified by the appended "&"). Line 23 saves the process ID of the task so that it can be terminated before exiting the script. At this point, everything is set up and ready for data acquisition.

Line 24 sends the "v1" command to DACS and line 25 performs a delay to allow time for the response.

Line 27 sends the current date and time to the output file and also sends an edited version of the DACS response (captured in TMP0) to the output file. This terse coding was suggested by Bill Kibler. Note that the "cut" command sends only selected characters to the output file, ignoring things such as the "v1" command echo and the command response that follows the voltage readout.

Lines 28, 29 and 30 perform script cleanup, deleting the temporary files, killing the serial background task and exiting the program with a zero response.

Figure 2 shows the contents of a typical output file generated by the script.

  140530-16:00:01 2.951
  140530-17:00:01 2.942
  140530-18:00:01 2.938
  140530-19:00:01 2.939
  140530-20:00:01 2.925
  140530-21:00:01 2.930
  140530-22:00:01 2.923
  140530-23:00:01 2.922
  140531-00:00:01 2.919
  140531-01:00:01 2.914

Figure 2. Voltage Data in Output File

Page 4


Each time is manually entered from a command prompt, it puts a date/time-tagged voltage reading in the output file. Note that the readings in Figure 2 are spaced one hour apart. This is because the script was specified to run once an hour as a periodic background (cron) task. To use the Linux cron facility to automatically execute the script, use the command: crontab -e and add a new entry such as: 00 * * * * /home/bob/bin/ > /dev/null 2>> /home/bob/logs/cron.log

Be forewarned that you may have to deal with the dreaded "vi" editor if it is set up as the default (it usually is). Try editing (and exiting) a test file before launching into the wilds of crontab editing. In the suggested entry, note the use of full path names. These are necessary. The "> /dev/null" just discards script output and the "2>> /home/bob/cron.log" routes error output to cron.log. The "00" entry specifies execution at the first minute of each hour. The other "*" entries are defaults for hour, day, month, and year. There are many examples on the Internet.


If the previous sections are somewhat new and confusing to you, we suggest reading a basic book on shell scripting such as Linux Shell Scripting with Bash by Ken O. Burtch, available at the Developer's Library site.

An excellent supplement or alternative to curling up with a good book is to spend a few sessions browsing the Internet. You will start to learn the basics and build confidence that tutorials, examples and help are plentiful. You will also be convinced that small Linux machines, such as the Raspberry Pi or Beaglebone Black, can be easily used with DACS to provide an inexpensive and versatile platform for automated data acquisition and control.

Revision Summary

Initial Release

email for BOBZ product support

Copyright © May 31, 2014, Bob Nash.