Inexpensive Incubator Alarm System using Linux


Diagram of alarm system
This is the setup of our incubator alarm system. The incubator has a serial port on the back that sends out readings of the temperature, carbon dioxide concentration, and humidity at regular intervals. The RS-232 signal goes through our network wiring to a patch panel. A Linux server with a multiport serial card monitors all the incubators simultaneously. The messages from the incubator look like this:
   37.0 deg C      5.0 % CO2     81 % RH
These messages are logged on the server's Web page. When the CO2 drops below a certain level, it is an alarm condition and the message looks like this:
   37.0 deg C      3.0 % CO2 LO  81 % RH
The Linux computer then sends out email messages and dials a modem to notify someone of the problem. Since most cell phones have caller-ID, the modem just hangs up when the scientist answers. The scientist then fixes the incubator, completing the circuit. The software remembers the previous alarm state so that only one email and one phone call are sent out to each user for each event.

Note that only the network wiring, not the network hardware, is used for the signals from the incubator. The RS232 signals never touch the computer network signals. It's a good idea to use a dedicated color for all cables carrying serial signals. We could also have used the telephone wiring system, since in our building the same type of wire is used for the telephones and network connections. But then we would have gotten in trouble with the Phone Cops.

Serial to RJ-45 adapters

Wiring diagram Wiring diagram

We use a DE9F to RJ45 adapter, part no. 01910 from to get the serial signal from the incubator to the network wall jack. The first figure above shows the wiring viewed from the back (inside) of the RJ-45 jack on the adapter and the front (outside) of the DE9F. The wiring is not critical, but it's obviously important to be consistent because once the adapter is assembled, the wires are no longer visible. Note that the color of the wires in this adapter is unconventional. If your incubator used a DB25 serial connector instead, it would be wired as shown on the second figure. An identical adaptor is used in the wire closet to convert the RJ45 back to a DE9, which is then plugged into a serial port on the server.

For the telephone, a different type of adapter can be made by splicing the appropriate lines of a Cat-5 patch cable to a telephone cable. Note that in a phone cable, the two ends are inverted, while network patch cables are wired 'straight through'. When making the adapter, pay attention to the positions on the plug, not the colors of the wires. This figure shows the positions as viewed from above the clear side or "top" of the plug:

Wiring diagram

In fact, this second adapter is not necessary. Just run a phone cable from the computer's modem to the phone jack. Unfortunately, after we set up our modem, we discovered that we didn't actually have any phone jacks in the wire closet. But there were lots of phone wires. So we purchased a little box that has a RJ12 surface-mount jack with a 110 punchdown block inside and connected it to the fax line. The box is wired up as shown below, viewing the RJ45 from the front (outside).
Wiring diagram

A punch-down block consists of little metal contacts on either side of color-coded plastic dividers. Traditionally, the solid color wire is always punched down on one side and the striped color wire on the other. Be sure you use the correct punch-down tool. There are two types: 66 and 110. If you use the wrong type, you will break the plastic divider.

Only two wires are needed to connect to a phone line. These correspond to the center two lines (green and red) in the RJ-11 plug and the blue and blue/white wires (the center pair) in the patch cable. The two lines go to the appropriate location on the 110 punch down block used by the phone system. The voltage across the phone line should be 47 volts DC. It goes without saying that you must be very careful not to accidentally connect the phone line to your router or any other network equipment.

TIA/EIA-568A and 568B wiring color codes

EIA-568A and B

Category 5 cables are wired in either EIA-568A or EIA-568B patterns. The figure above shows 568A and B color coding as viewed from the clear side (the "top") of the RJ-45 plug. These configurations give better performance than other arrangements. Obviously, both ends of the cable must be wired identically. Even though 568A and 568B patch cables can be used interchangeably, it's best to standardize on one or the other. Ideally, this fact should be documented somewhere.

Just for the record, we use EIA-568B at this location.

Important: The computer and freezer should be protected from electrostatic discharge by placing an RS-232 optical isolator or a diode-based surge protector such as a Tripp-Lite DRS232 between them. Otherwise, a surge could destroy the serial port on the computer or the freezer.

How to make a category 5 patch cable

When making a Category 5 network cable, it's important to minimize the untwisting of the twisted pairs. This is not important for serial cables, but for network cables, untwisting causes loss of bandwidth, making your network connections slower.

  1. Cut the desired length of Category 5e or higher cable.
  2. Remove 1 inch of the outer insulation from the cable jacket.
  3. Line up the individual wires as shown for 568A or B and untwist them to about 1/2 inch from the end. If the colored pairs are stuck together, carefully cut them apart with a razor blade. Do not de-insulate the wires. If any of the wires get nicked, start over. Trim the end with a pair of scissors so the ends of the wires are even.
  4. Insert the wires into a blank RJ-45 plug and crimp the plug with a plug crimper.
  5. Test the cable with a Category 5 cable tester. Cable testers have separate remote and local units so that cables of any length can be tested.

Incubator Monitoring Software

The include file is incubator.h.
The alarm program is

Note the following points about the program:

  1. The serial ports are multiplexed using the select() statement, which blocks waiting for input.
  2. In open_port(), the serial port is set to canonical I/O.
  3. The program tries to find the port address automatically. If it can't, the address is assumed to be 0xC800, which is the address of the RocketPort serial port (ttyR0 to ttyR7). See linuxsetup67.html for details on setting up the RocketPort in Linux.
  4. The program spends most of its time in monitor(), waiting on the select() statement. This keeps the system load at 1.0, but in fact there is actually very little load on the processor.
  5. When input comes in on one of the serial ports, the program figures out which serial port sent a signal and then jumps to handle_input() where it figures out what to do next.
  6. The first 29 bytes of the incubator string contain the date and time, which are often (or should I say "always") set incorrectly on incubators, so they are stripped from the string and replaced with the computer's date and time. Trailing junk is also stripped.
  7. Every time input comes in, it is appended to a log file and the external command "logcommands" is executed, which copies the log file to the http directory. The program also creates a small web page with a META command that causes the user's browser to automatically refresh every 40 seconds. This way, the user can leave a browser window open and monitor what is happening to the incubator continuously. (This is fun for some people.)
  8. If an alarm state is reached, the program executes the appropriate command from the alarm-commands file, which is shown below.
  9. The software should be run as its own user, e.g. "incubator", not as root. This may mean setting the device node to 777 or changing its ownership. Set the incubator's name to "The Incubator" in /etc/passwd so recipients of emails know they're coming from the computer.

Auxiliary files

  1. logcommands does whatever extra processing is needed when data is received. It must be made executable.
    # logcommands - Commands 
      to be executed by alarm
    # after each temperature 
    # Use alarm-commands to 
      add commands in case of 
      temp alarm.
    cp ./incubator.txt  

  2. The locations file gives a descriptive list of what is on each serial port. It's needed for the freezer alarm but mostly ignored for the incubator alarm.
    # Locations for conifer
    # Syntax is:
    #  port (0,1,2,etc) 
      <tab> Text string
    # For DGH module, 
      up to 4 freezers per 
    0       Incubator 0 ttyR1
    1       Incubator 1 ttyR3

  3. The alarm-commands file is a list like the one shown below. This example shows two incubators, 0 and 1. If no commands are found for a given incubator, the incubator is ignored. We have three columns to make the syntax compatible with our freezer alarm software. For incubators, the second column is ignored. The program automatically sends a message to syslog, so it is not needed here.
    # alarm-commands file 
    # Any commands here will  
      be executed when alarm 
    # Format is:   Incubator 
      Threshold  Command
    # 2nd arg is ignored but 
      needed for compatibility 
      with freezer software
    #Incubator no.  Command
    #incubator 0
    0    0   /bin/mail jrip <\
    0    0   ./alarmdial
    1    1   /bin/mail jrippe < \
    1    1   ./alarmdial

    (Note that these commands must be on a single line. They are wrapped here because one browser (from a large company whose name starts with 'M') doesn't render the page properly if the text is too wide.)

  4. alarmdial is another text file that dials the modem, waits for an answer, and then hangs up. It must be made executable.
    # alarmdial file
     /usr/sbin/pppd connect
      '/usr/sbin/chat -V "" ATM0 \
     "" ATDT9,13015551212 CONNECT'

    Note that we have to dial a '9' to get an outside line. In order for alarmdial to work, the linux kernel must be configured for ppp.

  5. /etc/ppp/options must be set up to "noauth", which prevents pppd from requiring a password, and "maxfail 1", which prevents it from trying to redial when the modem gets a "NO CARRIER" signal.
    # /etc/ppp/options
    maxfail 1
    idle 20

    I originally tried a program called "wvdial" for this purpose, but it proved impossible to get wvdial to stop redialing when the carrier was dropped by the recipient. A new version of wvdial appears to have this capability, but it proved to be impossible to get it to run for some unknown reason.

  6. Set up the file /etc/ppp/chap-secrets to a dummy password to cover the unlikely possibility that someone is running a ppp server on their cell phone.
    # /etc/ppp/chap-secrets
    #hostname       *       password
    fsdfsfs         *       fsfsf33sfs

  7. The incubator.html file uses one frame (incubators-left.html) for contact information and one frame (incubator.txt) for the incubator readings. (Sorry for the wraparound)
    <!-- Could be <FRA
    MESET cols="90%,10%">
    <FRAMESET cols="25%,7
          <FRAME src="in
          <FRAME src="ht

          xt" frameborder="1">
     <A HREF="incubator.
     txt> Incubators</A>

  8. serial.h is also needed to get to compile. If you don't have this, a serial.h appropriate for your system is in the linux kernel source.