home   articles   archive   forum   masthead  
Published at 5.05.05
Author: Prof. Dr.-Ing Arnold Beck
Translator: Sebastian Kueppers
Languages: de
Printer printer-version
Support Us!
  Warning: This article needs a proof reader.

Heizungssteuerung mit Linux
Linuxrechner für Steuer- und Überwachungsfunktionen

1. Introduction

Linux is a reliable operating system which stays stable over a longer period of time. Though it has only little requirements it can be run on older systems, too, and turn them into a monitoring and control system. In this case a radiator monitoring and control system shall be realised. The PC has to be enabled to read temperatures, use actuating elements and work with digital signals. For that older PC systems provide one or two serial interfaces and one parallel interface usually. The remote control and monitoring shall work via Internet over ISDN.
A PC 166 Mhz with AMD K6 CPU, 64 MB Ram and ISDN-card running Suse-Linux 6.1 is used by the author.

2. Measuring temperature

For measuring temperature digitemp has been proven to work for linux. 4 sensors have been connected to the serial interface as described in the manual. One of them measures the temperature of the radiator return flow, another one the temperature in the living room. Using Google a number of articles regarding digitemp can be found. On the mechanical part of the project there are different possibilities:
- compiling it on a 9-pin plug
- compiling it on a unused slot bracket inside the PC
- compiling it using an external case

To initialise the sensors use:

  >> digitemp -i -s/dev/ttyS0 oder digitemp -i -s/dev/ttyS1
  
depending on what interface you use.

The temperature can be measured using:

  >> digitemp -a
  

digitemp will give the temperatures for all 4 sensors as standard output if the measurement was successful:

DigiTemp v3.2.0 Copyright 1996-2003 by Brian C. Lane
GNU Public License v2.0 - http://www.brianlane.com
Nov 14 11:33:15 Sensor 0 C: 15.44 F: 59.79
Nov 14 11:33:18 Sensor 1 C: 35.38 F: 95.67
Nov 14 11:33:21 Sensor 2 C: 11.81 F: 53.26
Nov 14 11:33:24 Sensor 3 C: 10.50 F: 50.90

Using a Java-programm the measures are taken frequently.

Java-Programm
  import java.util.*;
  import java.lang.*;
  import java.io.*;
  
  //////////////////////////////////////////////////////////////
  // Benutzt das C-Programm isdndial
  //////////////////////////////////////////////////////////////
  public class tempCheck
  {
    static final String CmdMeasure ="/usr/local/bin/digitemp -a -r750";
    static final String CmdInit    ="/usr/local/bin/digitemp -s/dev/ttyS1 -i";
    FileWriter F;
  
    public tempCheck()
    {
      while(true)
      {
      try
         {
           String line;
           Process p = Runtime.getRuntime().exec(CmdMeasure);
           p.waitFor();
           BufferedReader input = new BufferedReader(
                                     new InputStreamReader(
                                          p.getInputStream()));
           F=new FileWriter("/usr/local/tmp/digitempLog.txt");
           while ((line = input.readLine()) != null)
           {
              System.out.println(line);
              F.write(line+"\n");
              // Heizungsrücklauf
              if (line.indexOf("Sensor 1")!=-1)
           {
             int     idx=line.indexOf("C:");
             String   ts=line.substring(idx+2,idx+6);
             double   td=Double.parseDouble(ts);
             if (td<10.0)
             createMail("Heizung", line);
           }
              if (line.indexOf("Sensor 2")!=-1)
           {
                ...
           }
              if (line.indexOf("Sensor 3")!=-1)
           {
                ...
           }
              // Raumtemperatur
           if (line.indexOf("Sensor 0")!=-1)
           {
             int   idx=line.indexOf("C:");
             String ts=line.substring(idx+2,idx+6);
             double td=Double.parseDouble(ts);
             ...
           }
  
           }
             input.close();
             Thread.sleep(180000);
           }
             catch (Exception err)
           {
             System.out.println("Fehler: " + err.toString());
            err.printStackTrace();
           }
         }
    }
  
    void createMail(String Subject,String Data)
    {
      try
      {
       Data+="\n.\n";
       Process P=Runtime.getRuntime().exec("isdndial ...");
       P.waitFor();
       System.out.println(Data);
       Process p2 = Runtime.getRuntime().exec("mail xxxxxxxxx@yyyyyyyy -s " + Sub + "\n");
       BufferedWriter InputP2=new BufferedWriter(new OutputStreamWriter(p2.getOutputStream()));
       InputP2.write(Data);InputP2.close();
       p2.waitFor();
       // wait 180000 ms 180 sec = 3 min
       Thread.sleep(180000);
       P=Runtime.getRuntime().exec("isdnhang ...");
  
      }catch (Exception e){System.out.println(e);}
    }
  
  
    public static void main(String args[])
    {
      try
      {
        Process p = Runtime.getRuntime().exec(CmdInit);
        p.waitFor();
        System.out.println("Init complete");
      } catch (Exception e){System.out.println(e);}
      tempCheck T=new tempCheck();
    }
  }
  


It is run via
    Process p = Runtime.getRuntime().exec(CmdMeasure);
  
Doing so the standard-output will be redirected. The following mechanisms analyses the digitemp-output:
    BufferedReader input = new BufferedReader(
                           new InputStreamReader(
                           p.getInputStream()));
    while ((line = input.readLine()) != null)
    {
  
    . . .
  
The digitemp-output will be read line by line.
If the taken temperature is too high this script executes the C-program isdndial to dial into the internet. After generating and sending an email the system hangs up again.

control lines

For controlling devices a 8 channel relais-interface by Conrad Electronic is used which is connected to the parallel interface. A compilation of such relais-interfaces or similar solutions can be found at http://www.franksteinberg.de/hardsteu.htm.

This interface is powered by the PC. To do so a Y-cable-adapter is used:

  • black Ground
  • red +5V
  • yellow +12V
I use the following programm for this card:

lpt1OutBit
   /* Kompilieren mit g++ -o lpt1OutBit lpt1OutBit.cpp                   */
   /* kopieren nach /usr/local/bin, dann s-bit setzen mit chmod als root */
  
   #include <stdio.h>
   #include <string.h>
   #include <stdlib.h>
   #include <sys/io.h>
   #include <sys/types.h>
   #include <unistd.h>
   #include <limits.h>
   #define OP_SET 1
   #define OP_RES 2
   #define OP_NEG 3
   #define PORT1 0x378
   
   /* Wandelt 1 Byte Integer in einen String mit Nullen und Einsen um (zB:0x63 -> "01100011") */
   char* crtBitStr(unsigned char x)
   {
     int i,j=0;
     static char p[7+1]="";
     for (i=0; i<8;)
     {
        if((x&1)!=0)p[i++]='1';
        else p[i++]='0';
        x>>=1;
     }
     return p;
   }
   int main(int argc, char* argv[])
   {
     unsigned int pin;
     int operation;
     int val;
     if (argc!=3)
     {
         printf("usage: lpt1OutBit op bit\n op : set | res \n bit:0..7\n");
         exit (-1);
     }
     if (strcmp(argv[1],"set")==0) operation=OP_SET; else
     if (strcmp(argv[1],"res")==0) operation=OP_RES; else
     if (strcmp(argv[1],"neg")==0) operation=OP_NEG; else
     {
        printf("usage: lpt1OutBit op bit\n op : set | res | neg \n bit:0..7\n");
        exit (-1);
     }
     if (strcmp(argv[2],"all")==0) val=0xff;
     else val=1<<atoi(argv[2]);
     /* want to be root */
     setuid(0);
     /* ioPerm ist Linux spezifisch -> man ioperm */
     ioperm(PORT1, 1, 1); // port 0x378 und die 1 folgenden freischalten
     pin = inb(PORT1); // port lesen
     ioperm(PORT1, 1, 0); // port 0x378 und die 1 folgenden sperren
     /*printf("status:%d\n",pin);*/
     {
        printf("value:%d\n",val);
        switch (operation)
        {
        case OP_SET:pin = pin | val; break; // Eintragen 1
        case OP_RES:pin = pin & (~val);break;
        }
        ioperm(PORT1, 1, 1); // port 0x378 und die 1 folgenden freischalten
        outb(pin,PORT1);
        ioperm(PORT1, 1, 0); // port 0x378 und die 1 folgenden sperren
      }
      printf("Status:%s\n", crtBitStr(pin));
      return 0;
   }
  


Technically this interface provides a closing-contact per bit. This is used to switch a assigned relais in the power house connection unit. This way a differenciation between PC and switched machine is given. The needed power is supplied by an power module from Conrad.

Work like this should be done by a specialist only.
Those relais control an electric valve. The motors used were provided by Fa. Oventrop. This way it is possible to rise or lower the heating remotely by telephone. When the relais are switched off the radiators are controlled by a room thermometer (available for 29 euro in any DIY store)

In addition to those outgoing signals the parallel interface provides several control lines for incoming or bi-directional signals.

  • Error (in)
  • Select (in)
  • PE (in)
  • ACK (in)
  • Strobe (in/out)
  • AutoFeed (in/out)
  • Init (in/out)
  • SelctIn (in/out)
Busy has been connected to Ground and is not available for input.

In order to use the input/output lines for input they have to be connected to 5V through a resistor (3-10 kOhm) and set to logical 1 by the software. In this configuration they will supply logical 1. If the input is bypassed logical 0 will be supplied on this input line. Further information can be found e.g. in the book " PC-Schnittstelen angewandt" by Burkhard Kainka, published by Elektor Verlag Aachen. Also search engines on the web will provide you information over assignments and wireing on the parallel interface.

Go Online

To provide remote administration features a dial-in access has to be provided.
For this purpose different options can be chosen depending on how the computer is connected to the telephone network or the internet.

  • telephone connection with modem: Using mgetty is suggested here
  • ISDN: Dial-in via ISDN. Though no 'flat-fee' was available another way has been choosen: Using a telephone one of the available numbers is dialed. This connecton attempt is logged on the linux PC. This log can be parsed cyclic. If a valid attempt is identificated the system connects to the internet itself and sends a mail containing the current IP adress to a specific eMail adress. For identifiation the callers ID is used.
  • DSL: Request and delivery of the current IP adress as mentioned above


The technology to analyse ISDN caller Ids can be used for other control purposes like hang up, switch on heater, switch off heater, reboot or so on, too.


Arnold Beck, HTW Dresden (FH), FB Informatik/Mathematik, 12/2003


Talkback Area




Enter Own Comment