What Can you Expect? —A Data Collection Project Using Linux

The author describes the end-to-end process of defining and implementing a data collection project using Linux. The project illustrates the use of Expect, stty, cron, a little C programming, gnuplot and ioctl to the serial device driver.

I have been doing a fair amount of testing and monitoring on the system and hardware clocks of my Debian 2.0 machine that I use for file (Samba), communication (ISDN/masq/diald), printing and modem pool (mserver) service on my home office network. I wanted to see how well I could correct the system clock with adjtimex without running ntpd all the time and keeping the ISDN line to my ISP up. I had been recording daily data for the clocks and an ntp (network time protocol) reference server using the logging feature of adjtimex with cron and an Expect script. I was noticing some odd changes from day to day, and was beginning to wonder if temperature was affecting the server's system clock.

Why Debian?

adjtimex allows you to fiddle with the kernel parameters which control the system clock. The file /etc/rc.boot/adjtimex contains settings for TICK and FREQ, the coarse and fine settings used to tune out variations in the frequency of the crystal oscillator on the motherboard which supplies the interrupts to the system clock timekeeping process. The command:

/usr/sbin/adjtimex --log --host ns.nts.umn.edu

logs data for the reference ntp server, in this case ns.nts.umn.edu, the system clock and the hardware clock to /var/log/clocks.log. By using

adjtimex --review=/var/log/clocks.log
you can get suggested changes for TICK and FREQ which will tune the kernel clock and hopefully get it to match the ntp reference server. This is all well and good, as long as the clock crystal is stable; but what if it varies with temperature?

The Idea

What if I could measure and record the temperature near or actually inside the server? I could then correlate the temperature data with the system clock data to see if they were related. I have a Micronta (Radio Shack) digital multimeter with a serial interface. All I needed to collect the data was a circuit to convert temperature to voltage and interface the meter to a serial port on the server.

Gathering the Hardware Tools

A little research on the Net turned up a couple of thermocouple to millivolt converters, but they cost much more than I wanted to pay. Being an electrical engineer and having worked at a measurement company for many years, I knew that a temperature to volts converter circuit is fairly simple. A couple of friends helped out by putting together a circuit that provides .01 volts out per degree Fahrenheit that fits on a piece of vector board about an inch square and runs from a 9-volt battery. See Figures 1 and 2 for the schematic diagram and a picture.

Figure 1. Schematic for Temperature-to-Volts Converter

Figure 2. Converter

The Micronta No. 22-182 LCD Digital Multimeter comes with a five-conductor cable and a short section in the manual describing test programs for MS-DOS and MS-BASIC. A quick check showed that these worked fine. The serial interface communication parameters are 1200 baud, 7 data bits, no parity and 2 stop bits. Using the meter's continuity test function, I made a cable drawing as shown in Figure 3, a complete pinout and description of the serial port signals as found on a PC. These ports have male connectors with either 9 or 25 pins, and are wired as DTE (data terminal equipment). The RS-232 specification is designed so that a DTE port as on the PC can be connected to a piece of DCE (data communication equipment), typically a modem, with a straight-through cable. DCE usually has a female connector. You can use Table 1 to wire up a 9-pin to 25-pin conversion cable if you need one. Now I was ready to try reading the meter on Linux.

Figure 3

Table 1

Gathering the Software Tools

Before I hooked up the cable to /dev/ttyS0, I checked to see if there were any drivers like getty or gpm running on the port. Sure enough, there was a leftover gpm driver for a mouse, even though the mouse had long since been disconnected. I did an

/etc/init.d/gpm stop

and renamed the init script with

mv /etc/init.d/gpm /etc/init.d/nogpm
to prevent gpm from restarting in the event of a reboot. If you have a getty process running on the port, you will have to disable it by commenting out the correct line in /etc/inetd.conf and restarting init with
kill -HUP 1
Use something like
ps auxw|grep tty
to make sure the serial port you are trying to use is free.

I used stty to set the port to the meter's communication parameters with this command:

stty speed 1200 cs7 cstopb -echo clocal < \

speed 1200 sets the baud rate, cs7 sets 7 data bits, cstopb sets 2 stop bits and parity is none by default. I added the -echo to make sure the device driver didn't echo back characters sent to the port and clocal to disable the modem control signals.

I decided to use Expect to collect the data, since the meter has a very simple “send a command” and “get a response” paradigm. Expect is a powerful tool and can be used to automate UNIX programs which interact with a user or processes needing a command or trigger and return some kind of response. Expect is built on top of Tcl, a widely used extensible language. I had recently discovered Expect and found it is one of those tools you just don't know how you ever got along without. You can easily automate things with Expect that are extremely difficult or next to impossible with shell scripts or other languages. Sol Libes' book, Exploring Expect, was a valuable resource. Mr. Libes is the author of Expect. I also found the Expect and Tcl web pages very helpful. I had previously used Expect to automate a couple of tasks such as the clock data logging mentioned above.

The meter protocol is very simple: send the meter a D\r (a capital D followed by a return), and it sends back a 14-character string ending in a \r (return). The message sent back by the meter is of the form:

Byte     1 2 3 4 5 6 7 8 9 A B C D E
Ex. 1    D C - 1 . 9 9 9 9   V     \r
Ex. 2          1 . 9 9 9 9 M o h m \r

In practice, since this is a 3-1/2 digit multimeter, a space character replaces the least significant digit in column 9.