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/ttyS1depending 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();
}
}
|
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
| 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;
}
|

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)
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