Solar Pool Heater Project

I have a completed project I would like to share. I am not sure how to do that.
I have schematic, code, pictures
Ron W6FIF

#include <OneWire.h>

/* DS18B20 Temperature chip i/o
Solar Pool heater.
I have 2 temperature sensors one on the solar panel input pipe and one on the solar panel output pipe.
I have a Light Sensitive Resistor that I read with an Analog input to determine if it is day or night.
If it is day I check to see if heat is flowing into the pool -- if it is night I wait 20 minutes and check to see if it is day yet.

If the temp of the output is greater than the input then heat is flowing into the pool and
I leave the pump motor on to circulate the water. (I use a opto Triac to drive a power Triac which controls the motor. (LN-2556 Q8012LH5-ND)
Also turn on a LED to give an indication that the pump should be running.
If heat is not flowing into the pool I turn the motor off and wait for 20 minutes and check again by turning on the motor for 1 minute and then rechecking the direction of heat flow.

This code works - but I could use some input on how to make it more compact.
If you see structure blunders - please tell me.

I am only using 2 18S20's in this application so I only use one byte, addr[1], of the device ID to indentify which sensor I am reading.
I should only have to read the sensor loop twice but something is wrong with my code and I must read the sensors 3 times to keep them in sync (so that the first reading always reads the same sensor.)
In the WHILE loop the j goes from 0 to 2 and the second sensor is read twice. I should have j = 0 and 1 and only read the sensors twice but this does not work right.
I must read the second sensor twice to keep the sensor reading order consistent. I can't find what causes this.
The app runs fine with code as is.
|----[0.1uf]----|
The light sensor circuit looks like this V+ o------[3.3Mohm] ----+-----[LSR] ----o GND
|----------I -------o Pin 5 of analog input

If the pool get hotter then 95F shut off the circulation motor.

Ron Spooner 6/20/12 8/16/2012

*/
const int TempPin = 10; // 18B20 data pin is 10
const int MotorPin = 6; // drives the Triac for the motor
const int LEDPin = 13; // used as an indicator that the motor is to be ON or OFF
const boolean ON = HIGH; // makes the code easier to read
const boolean OFF = LOW; // makes the code easier to read
const int LSRPin = A5; // pint for Analog input to read LSR sensor - Analog pin 5 . in series with 3.3Mohm to V+
unsigned long PrimPump = 60000; // Pump runs for 1 minute to get the water flowing.
unsigned long Cycle = 1200000; // Test to be sure heat is flowing into the pool evey cycle.
OneWire Temp18B20(TempPin); // declare TempSensor as a OneWire object and assign I/O pin
byte i, j = 0; // j counts the numbe of time I read the sensors.
byte present = 0; // Keeps the number of 18B20 in use
byte data[12]; // data bytes 12 bytes
byte addr[8]; // address bytes 8 bytes
float Temp; // used to make the temp reading F or C
float Temp1, Temp2; // storage for comparing the inlet and outlet temps
// #define DEBUG; // ***** comment this line out to get rid of Serial.print printout.

void setup(void) { // initialize inputs/outputs - start serial port
#ifdef DEBUG
Serial.begin(9600);
Serial.println(" ID ,Time ,Temp");
PrimPump = 800;
Cycle = 6000;
#endif
pinMode(MotorPin, OUTPUT); // control the Triac - motor controller
pinMode(LEDPin, OUTPUT); // indicator LED to show the motor is to be ON
}
// Check to see if the sun is up.
boolean IsSunUp(void) {
#ifdef DEBUG
Serial.print(analogRead(LSRPin));
#endif
if (analogRead(LSRPin) < 300){ // high value when in the dark and low value when in the light.
#ifdef DEBUG
Serial.println(" Day");
#endif
return true;
}
else{
#ifdef DEBUG
Serial.println(" Night");
#endif
return false;
}
}
/*
Function IsHeatFlowing reads the temperature of the two sensors.
One sensor is on the inlet pipe of the solar panel, the other is on the outlet pipe of the solar panel.
If heat is flowing into the pool then return true if not then false.
*/

boolean IsHeatFlowing(void) { // Is Heat Flowing into the pool?
j = 0; // J count the number of sensors. If you have 2 sensors then j count from 0 to 1
while(j < 3){ // bug should work for 2 sensors need to read three time to keep sensors in sync. this make the code read 21D3 twice.
#ifdef DEBUG
Serial.print(j);
Serial.print(" ");
#endif
if ( !Temp18B20.search(addr)) { // gets the address of the 18B20's
#ifdef DEBUG
// Serial.print("No more addresses.\n");
#endif
Temp18B20.reset_search();
break; // fixed the j loop problem !!!!! 9/20/12
}
#ifdef DEBUG
/* Serial.println("ID="); // ID=28 identifies the 16S20 family of one-wire sensors.
for( i = 0; i < 8; i++) {
Serial.print(addr*, HEX); // This is the part ID each part has a unique 48 bit Serial#*

  • Serial.print(","); // I use a comma so the serial data can be read by Excel*
    _ } */_
  • Serial.print(addr[1], HEX); // prints the address of the 18B20 that is being read*
  • Serial.print(addr[2], HEX);*
  • Serial.print(", ");*
    *#endif *
  • if ( OneWire::crc8( addr, 7) != addr[7]) { // checks the CRC*
    *#ifdef DEBUG *
  • Serial.print("CRC is not valid!\n");*
    #endif
  • return false;*
  • }*
  • if ( addr[0] != 0x28 ) { // checks to be sure the one-wire part is a 1820 family*
    *#ifdef DEBUG *
  • Serial.print("Device is not a DS18S20 family device.\n");*
    *#endif *
  • return false;*
  • }*
  • Temp18B20.reset();*
  • Temp18B20.select(addr);*
  • Temp18B20.write(0x44,1); // start conversion, with parasite power on at the end*
  • j += 1;*
  • delay(750); *
  • present = Temp18B20.reset();*
  • Temp18B20.select(addr);*
  • Temp18B20.write(0xBE); // Read Scratchpad*
    #ifdef DEBUG
  • Serial.print(millis()/60000); // print time in minutes sense last reset - will roll-over*
  • // Serial.print(", SPad=,"); *
  • // Serial.print(present,HEX);*
  • Serial.print(", ");*
    #endif
  • for ( i = 0; i < 9; i++) { // we need 9 bytes*
    _ data = Temp18B20.read(); // reads each data byte into array data[]_
    #ifdef DEBUG
    _ // Serial.print(data*, HEX);
    // Serial.print(",");
    #endif*
    * }
    Temp=(data[1]<<8 )+data[0]; //take the two bytes from the response relating to temperature == 12 bits*
    * Temp=Temp/16; //divide by 16 to get pure Celsius readout - different for 9, 10, 11, bits resolution*
    Temp=Temp1.8+32; // Fahrenheit conversion comment this line out to get Celsius_
    _#ifdef DEBUG*
    * Serial.println(Temp); // add line feed CR to end of line*
    #endif
    * switch (addr[1]) {
    case 0x21: // first byte of sensor ID this number is unique to the sensor S#
    Temp1 = Temp;
    break;
    case 0x7C: // first byte of sensor ID this number is unique to the sensor S#
    Temp2 = Temp;
    break;
    }
    }
    if ((Temp1 > (Temp2 + .4))&& (Temp2 < 95.0)) { // compare the temps, be sure the outlet is just a bit hotter than the inlet.
    return true; // return true if heat is flowing into the pool*
    * }
    else{
    return false; // return false if heat is flowing out of the pool or pool temp is >= 95F*
    * }
    }
    void loop(void) {
    if(IsSunUp()) { // Check to see if the sun is up.
    digitalWrite(MotorPin, !ON); // turn motor on Triac has negitive logic.
    digitalWrite(LEDPin, ON);
    delay(PrimPump); // ******* turn on the pump and wait about 1 minute to see if water is heated.
    #ifdef DEBUG*
    * Serial.println(" Motor is On");
    #endif
    if (!IsHeatFlowing()) { // if heat is not flowing into the pool turn motor off OR pool temp is >= 95F .
    digitalWrite(MotorPin, !OFF);
    digitalWrite(LEDPin, OFF);
    #ifdef DEBUG
    Serial.println(" Motor Off");
    #endif*
    * }
    }
    else{
    digitalWrite(MotorPin, !OFF); // if sun is down turn motor off*
    * digitalWrite(LEDPin, OFF);
    #ifdef DEBUG*
    * Serial.println(" Motor Off");
    #endif*
    * }
    delay(Cycle); // ******* Wait 20 minutes and then check to see if heat is coming out of the collector_

    _#ifdef DEBUG
    // Serial.print(" CRC = ");
    // Serial.println( OneWire::crc8( data, 8 ), HEX);
    #endif
    }
    Schematic Arduino Forum
    _SDC13882.JPG

    SDC13884.JPG
    SDC13883.JPG
    PoolHeaterSch.PDF (18.5 KB)_