After last winters cold spell I was called out to replace several pumps that were used for private water supplies. In some cases all the plumbing needed replacing because of frost damage. To prevent that from happening again I designed a small system that will switch Trace heating on when the pipe temperature falls below 2Deg C. The system has 3 digital temperature probes that detect outdoor, indoor and pipe temperature within the insulation on the furthest point away from a water heater that supplies hot water. 10W/m Trace heating cable is used to protect the water pipes from freezing. Both pipes run in the same insulation, so only one cable is needed.
The logic of the system:
- When the outside temperature falls below -3dgC it will turn the trace heating on.
- When the pipe temperature falls below +2dgC, the pipe heating will come on.
- When the inside temperature (inside the cupboard that houses the water heater) falls below +3dgC a bar heater inside the enclosure comes on irrespective of the outside temperature.
- When the hot water is being used and the pipe run warms up the trace heating will stay on as long as the outside temperature is below -3dgC. Once the temperature outside rises, no hot water is being used and the temperature rises above 2dgC the system will start oscillating 10min on and 5min off depending on the temperature drain.
- The heater in the enclosure will behave similarly as the probes have a lot of mass and react slowly. (saves coding).
The hardware:
- Arduino UNO R3. (just for convenience as they are easily available and inexpensive). ca £6.5.
- 3 digital serial temperature probes in this case DS18B20 as they have good library support and work well. As I can live with crude tolerances for this application 5 for £11 fits the bill. All connected to pin 2 with one ! 4.7K (Signal to 5V+) pull up in the line where all the cables are joined. (Forget that and you get no reading).
- 2 x 1 channel relay modules KY-019 5 for £8.
- 1 128 x 32 I2C (4 pin) OLED display, As no one is going to gaze at it all the time and is only there to give some indication what the probes read and the system state in general it is sufficient. You can get 4 lines with 21 characters readable. SSD 1306 2 for £9. (they change the supply about a bit like VCC and GND) .
- 3 x 3.5mm 3 pole plugs (headphone stereo plugs) solder type to fit onto the end of the probes. V+ in the centre, GND on the shield ad the Signal in the middle. Easy to change a probe if not hard wired into the box. I use 2 wire screened video cable to extend the reach of the probes and make up extension cables.
- 3 x 3.5mm headphone sockets in the casing to connect the probes.
- 1 x 12V 2 amp power supply. As they are the most popular 2 for £11. (they came with a socket that fits in a 10mm hole with a drop of glue to secure it).
- A hand full of heat shrink and hook and loop tape to hold the bits inside in place but removable. In this case to upload the code, the relays have to be lifted away.
- 1 x waterproof Clear cover case (158 x 90 x 60)mm £5. (Just to see the display).
The Code:
// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
Adafruit_SSD1306 display(OLED_RESET);
#define XPOS 0
#define YPOS 1
#define DELTAY 2
int signed tempSetOut = -2;
int signed tempSetIn = 3;
int signed tempSetPipes = 2;
int signed tempDiffState = 10;
int tempStateOut = 0;
int tempStateIn = 0;
int tempStatePipes = 0;
//#if (SSD1306_LCDHIGHT != 32)
//#error("Hight incorrect");
//#endif
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
/*
* The setup function. We only start the sensors here
*/
void setup(void)
{
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
// start serial port
Serial.begin(9600);
Serial.println("Dallas Temperature IC Control Library Demo");
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
// Start up the library
sensors.begin();
}
/*
* Main function, get and show the temperature
*/
void loop(void)
{
float tempOut = sensors.getTempCByIndex(0);
float tempIn = sensors.getTempCByIndex(1);
float pipesOut = sensors.getTempCByIndex(2);
if (tempOut < tempSetOut)
{
tempStateOut = 1;
}
else
{
tempStateOut = 0;
}
if (tempIn < tempSetIn)
{
tempStateIn =1;
}
else {
tempStateIn = 0;
}
if (pipesOut < tempSetPipes)
{
tempStatePipes = 1;
}
else
{
tempStatePipes = 0;
}
if (tempStateOut + tempStatePipes > 0)
{
digitalWrite(8, HIGH); Serial.println(" Pipe heating on !");
}
else
{
digitalWrite(8, LOW); Serial.println(" Trace heating is off !");
}
if (tempStateIn > 0)
{
digitalWrite(9, HIGH); Serial.println(" Inside Heater On !");
}
else
{
digitalWrite(9, LOW); Serial.println(" Inside heater Off !");
}
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("DONE");
// After we got the temperatures, we can print them here.
// We use the function ByIndex, and as an example get the temperature from the first sensor only.
Serial.print("T outside (index 0) is: ");
Serial.println(sensors.getTempCByIndex(0));
Serial.print("T inside (index 1) is: ");
Serial.println(sensors.getTempCByIndex(1));
Serial.print("T Pipes outside (index 2) is: ");
Serial.println(sensors.getTempCByIndex(2));
display.clearDisplay();
display.display();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print("OUT ");
display.print(sensors.getTempCByIndex(0));display.print(" IN ");display.println(sensors.getTempCByIndex(1));
display.print("PIPES OUT ");display.println(sensors.getTempCByIndex(2));
//display.setCursor(0,2);
display.println(" OUT , IN , PIPES");
display.print(tempSetOut);display.print(" ");display.print(tempStateOut);display.print(" ");display.print(tempSetIn);display.print(" ");display.print(tempStateIn);
display.print(" ");display.print(tempSetPipes);display.print(" ");display.print(tempStatePipes);
display.display();
delay(15000);
}
Comments
Please log in or sign up to comment.