Channel 8 - Documentation

Features:

Introduction:

Channel 8 is a data logging system for Linux that allows the user to record and display up to 8 analog readings from an external A/D converter. The user interface is a webserver so that Channel 8 can be used over a LAN or the Internet. Channel 8 provides user-specified scale and offset factors for each channel to convert the analog readings into engineering units. Readings can be viewed at any time via browser and updated by simply refreshing the webpage. The data can be logged to a text file at scan rates from 1/minute to 1/hour - each scan is time and date stamped. The data file can be viewed at any time from a browser connected to the network.

Channel 8 Configuration parameters include:

Channel 8 is ideal for use as a remote data logging system connected to a network. It can be used in the home or at work to record temperatures, light levels, voltages or any analog parameter accepted by your A/D converter.

Channel 8 includes Linux server C code that can be customized by the user to interface to external devices via serial or parallel ports. A server for generating random numbers is included, and server design for commonly available A/D devices is discussed.

Installation:

Channel 8 is installed by creating a subdirectory in your Linux system and copying a series of files:

Ch8WebServer.c - This is the user interface webserver.
Ch8Logger.c - This is the data logging program.
Ch8RndServer.c - This is a random number data generator.
Killer - This is used to stop the data logging program
data.txt - The file containing recorded data
log.cfg - Configuration file holding logging parameters
lfile - Configuration file containing channel labels and units
cfile - Configuration file containing scale and offset factors

Several additional files are included in Channel 8:

shttpd.c - This is the basic simple webserver
shttpd.h - Library for shttpd.c
simplesrvr.c - An example server program
simpleclient.c - An example client program for simplesrvr.c
Readme.txt - A text version of this documentation.
License.txt - The GNU General Public License

Compiling the Channel 8 Source Files:

You first need to compile the random server program Ch8RndServer.c using gcc, as follows:

gcc -O Ch8RndServer.c

Then copy the compiled output file, a.out,, as follows:

cp a.out Ch8RndServer.run

Similarly, compile Ch8Logger.c and then copy the compiler output file (a.out) to Ch8Logger.run

gcc -O Ch8Logger.c
and
cp a.out Ch8Logger.run

Finally, compile Ch8WebServer.c as shown, and copy the compiler output file to Ch8WebServer.run:

gcc -O Ch8WebServer.c shttpd.c -DEMBEDDED -ldl
and
cp a.out Ch8WebServer.run

Running Channel 8:

The Channel 8 webserver uses port 80 of the Linux PC. If you already have a webserver running on your Linux system you must halt it. The command for this will vary from server to server, but you can always look at the system process list (ps -A), and kill the webserver process.

To launch Channel 8 first run the random data server as a background process:

./Ch8RndServer.run&

Next, start the webserver:

./Ch8WebServer.run&

That's it. You can check the system processes using the ps command to verify that these are running.

To see Channel 8 in operation, launch a web browser somewhere on the network and enter the Channel 8 PC's IP address. You should see the opening screen.

Operating Channel 8:

A series of links across the top of the Channel 8 screen comprise the logging system menu. The choices are:

The screens and menus are mostly intuitive, but here is a description of how they are used:

Channel 8 Home Page:

No action when on the home page, just the Channel 8 menu along the top.

Configuration Page:

The Configuration page has a table of editable boxes for each of the 8 channels containing:

Channel ID - Put any descriptive text here up to 12 characters that describes the signal on the channel. One quirk is that spaces are given spurious characters somehow when stored by Channel 8. You can avoid spaces by using an underscore "_". Default values of Channel ID are simply Channel_0, Channel_1, etc.

Units - Normally incoming Units are in Volts DC from most A/D converters so this is the default. The application of Scale and Offset Factors to an input in Vdc, however, will convert it to a reading in engineering units. If, for example, a sensor produced 0 Vdc output at 0 deg F and +5 Vdc output at 100 Deg F, then a Scale Factor of 20 would produce a Channel 8 reading in degrees F. So the Units box would contain "Deg_F".

Scale Factor - This is a floating point number that multiplies the incoming value from the A/D converter.

Offset Factor - This is a floating point number added to the product of the incoming value and the Scale Factor.

Scale and Offset Factors are simply linear conversion factors where the Scale Factor is the slope and the Offset Factor is the Intercept of a first order function that converts incoming voltages into engineering units. The format is familiar to algebra students: Y = mX + b, where X is Vdc, Y is the value in engineering units, m is the Scale Factor and b is the Offset Factor.

An example will help:

A pressure sensor produces 0.5 Vdc at 0 pressure and 4.5 Vdc at a pressure of 20 psig. Find the Scale and Offset Factors that will convert the incoming voltages to units of pressure in psig.

Step 1 - Calculate the Scale Factor:

The Scale Factor, m, is simply the change in pressure divided by the change in signal. (20 - 0)/(4.5 - 0.5) = 5.

Step 2 - Calculate the Offset Factor:

The Offset Factor is b and is solved using the equation below:

-b = mX + Y at some known values of X and Y. So when the pressure, Y, is 0 psig, the signal X is 0.5:

-b = 2.5 + 0 = -2.5

We verify by solving for psig at 4.5 Vdc:

Y = 5(4.5) -2.5 = 20

So for the above example the Channel ID might be "Pressure", the Units will be "Psig", the Scale Factor will be 5 and the Offset Factor -2.5.

Update Button - The Update Button must be pressed before the Scale and Offset Factors will take effect.

Readings Page:

The Readings page present a table of the current readings for all 8 channels, converted into engineering units. The readings can be updated by refreshing the page via the browser "reload" button. On Internet Explorer, clicking on the Channel 8 Readings link again will also update the page.

Some browsers, especially text-mode browsers in Linux (Lynx, specifically) tend to display the web pages from the cache even when you press an Update button on the page. So if you experience difficulty with refreshing the readings, be sure to check the browser cache settings.

Data Logging Setup Page:

This page configures the data logging parameters. A Comments text-box allows a user comment to appear in the data file header.

The Data Logging Setup page provides drop-down menus for Logging Interval and for the Maximum Channel to Record. The logging intervals are:

The Maximum Channel Recorded can be any of the 8 channels, starting at channel 0 and going up to 7. If 0 is selected, then the data appearing in the data file will be Date, Time and the Reading from channel 0, scaled in engineering units.

Log Running & Log Not Running

These are radio buttons that determine the state of the data recording. Log Running starts the data recording to a file named data.txt. Log Not Running stops the data logging.

Note: When Log Running is enabled and then activated with the Update button, the existing data.txt file is deleted and all data contained in it is lost!

You can ftp the data.txt file or display it on a browser page (see below) and copy and paste it to a local file prior to starting a new logging run.

Note: No action on logging is taken until the "Update" button is pressed.

Data Page

The Data page provides a listing of the contents of the data.txt file on a browser page. This makes it easy to view and copy the current contents of the file without having to use an ftp client.

System Details

Channel 8 is actually three programs and a series of ancillary files. Two of the programs are servers, and the logging program is a client. All the programs can be modified and re-compiled to customize the application to your needs. Here is a description of what each program does:

Ch8RndServer.run

This is a server program whose function is to supply the A/D converter readings upon request. This program actually generates random numbers instead of real voltage values so that Channel 8 can be used in a demo mode without any specific A/D hardware. Ch8RndServer.run generates a random number between 0 and 1 for Channel 0, between 1 and 2 for channel 1, etc. You can test the server by Telnetting into Ch8RndServer's port 3490 - the server will return a string of random numbers for each of the 8 channels being simulated.

Ch8RndServer can be modified to include code that opens, say, the serial port, sends a request to an A/D converter, and then parses the A/D response for serving to the other Channel 8 clients. This will be discussed in detail later.

Ch8Logger.run

This is a client program that is launched when the Log On radio button is activated in the browser. The program reads a logging configuration file created by the Ch8WebServer and starts a new data.txt file. Ch8Logger also reads the Scale and Offset Factor files. When the logging interval is reached, Ch8Logger requests the readings from Ch8RndServer, converts the raw voltage readings into engineering units and records them to the data.txt file along with the time and date. Ch8Logger then sleeps until the next logging interval has elapsed.

When the user halts logging from the webserver Logging Setup page, a batch file named Killer is launched, it obtains the PID of Ch8lLogger and sends a process signal that terminates Ch8Logger.

Ch8WebServer.run

This is the webserver that generates all of the user interface pages and forms. This was created from shttpd, a simple webserver program written by Sergey Lyubka. Further information is available on shttpd at http://shttpd.sourceforge.net

Ch8WebServer generates all of the pages that comprise the Channel 8 user interface. Each page has a separate block of code and is a bit complex. The program accepts the Scale and Offset Factors and saves them to a file named cfile. The Units and Channel ID text is saved to a file named lfile. The Logging Setup page parameters are saved to a file named log.cfg. In this way the user can control the actions of the other servers and clients of the Channel 8 system.

The relationship between the various Channel 8 programs and files is shown in the Ch8.jpg file.

Creating a Custom A/D Interface Server

Logging random numbers is hardly useful, so how do you make Channel 8 work with an actual A/D converter? The answer is to modify Ch8RndServer so that it communicates to an actual A/D interface, recieves the analog voltages, and then processes the values into a string that can be received by the other Channel 8 clients.

Example of A/D Interface Code

A simple example will show how to write the code needed to communicate to a basic A/D converter connected to the PC serial port.

Let's say we have a simple A/D converter that connects to the serial port of a PC. Serial devices generally work with command sets consisting of strings. In this example the A/D converter has eight 10-bit channels that read from 0 to +5 Vdc. To request the reading from a channel on the A/D converter, the requesting PC sends the channel number out over the serial line. The A/D converter responds within 10 milliseconds with a string of numbers representing the A/D counts. The counts run from 0 to 1023 (2^10), and are proportional to the voltage applied to that channel such that 0 Vdc = 0 counts and 1023 counts = +5.000 Vdc.

So the code to communicate to the A/D converter will consist of a few very simple steps:

  1. Open the Serial Port
  2. Write the Required Channel Number
  3. Wait for the Device to respond
  4. Read in the A/D Counts
  5. Process the Counts into Vdc

The best way to develop the code is to write a separate program. When it works, you can simply paste the code into Ch8RnDServer.c and re-compile.

Here is some C code that communicates to the A/D converter and prints the incoming counts to the screen. This simple program can be used as a starting point for development:

/* Serial Interface Program */
#include stdlib.h
#include stdio.h
#include time.h
main()
{
FILE *fptr;
char IP[5];
printf("Trying ttyS0 Port! \n");
fptr = fopen ("/dev/ttyS0", "r+");
fprintf(fptr, "0");
usleep(100000);
fgets(IP, 5, fptr);
fclose(fptr);
printf("Device Output %s \n", IP);
}

Note that the serial port, ttyS0, is treated like a normal file. In this way read and write operations are simplified.

In order to try the program, compile using the following Linux command:

gcc -O serial1.c

Next, change the permissions for serial port 0:

chmod 777 /dev/ttyS0

You can also set the serial port communication parameters: baud rate, handshaking, etc using the Linux stty command. Use stty --help for a summary of the command syntax. Most Linux systems default the serial ports to 9600 baud, 8 bits, 1 stop bit and no handshaking. Check the specifications of your serial A/D to be sure these parameters are set correctly.

To run the compiled interface program:

./a.out
Trying ttyS0 Port!
Device Output 789

Now that the basic program works, we can calculate the voltage using the following formula:

Vdc = (C/1024) * 5

Where C = the incoming counts and Vdc is the reading on the channel in volts..

Data Format for Channel 8 Client Programs

Now that we have a way to get readings from the external A/D in units of Vdc, we are ready to format the data for the other Channel 8 clients. The format is very straightforward and consists of a single string that has 5-digit values for each channel separated by a single space, as shown below:

0.123 1.234 2.345 3.456 4.567 5.678 6.789 7.890

Note that each value must have the same number of digits, even if they are zeroes: the client programs parse this string into the eight separate substrings and determine the values in Vdc and then apply Scale and Offset Factors. Any missing places or extra digits in the string will cause the parsing scheme to produce incorrect values.

With the above requirements in mind, here is the final serial interface program that collects values from all 8 A/D channels, converts them to Vdc and formats a string for passing to client programs:

/* Serial Interface Program */
#include stdlib.h
#include stdio.h
#include time.h
#include string.h

main()
{

FILE *fptr;
char IP[5];
char *Vlu;
char Val[50];
double v[7];
double volts;
int ctr = 0;

while (ctr <8)
{
fptr = fopen ("/dev/ttyS0", "r+");
fprintf(fptr, "%d", ctr);
usleep(150000);
fgets(IP, 5, fptr);
volts = atof(IP);
v[ctr] = 5*volts/1024;
fclose(fptr);
usleep(150000);
ctr++;
}

ctr = 0;
while (ctr < 8)
{
asprintf(&Vlu, "%5.3f ", v[ctr]);
strcat(Val, Vlu);
ctr++;
}

printf("%s ", Val);

}

Now that the A/D interface code has been verified, it is simply a matter of inserting it into the Ch8RndServer.c file, compiling and testing it with the rest of the Channel 8 system. The section of Ch8RndServer.c that is appropriate is identified by the comments:

"// ------ Put A/D Code Here ---------"

and

" // ------------ End A/D Code ----------------".

Be sure to remove the code for generating random numbers.

Note that if the floating-point A/D values in volts are kept in an array named v[], the correct string will be automatically generated by the existing code for random values. This code is duplicated in the above example.