Heat/Cool Temp Controller

I was just curious if someone could look over this code and let me know if it looks right, or if you’d make any changes. What I’m trying to achieve is a temp controller that heats to a specified temp, or cools to a specified temp. The hardware is an arduino UNO, a DS18B20 waterproof probe, an LCD and an MDFLY 4CH Relay Control Board - Optical-Coupler Isolated. If I haven’t provided any necessary info, please let me know, and I’ll provide immediately.

Thank you!

#include <OneWire.h>
#include <Wire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>

//RGBLED
int bluePin1 = 10;                        //Digital Pin for blue LED1 in RGB-LED 
int redPin1 = 12;                         //Digital Pin for red LED1 in RGB-LED 

int redIn1 = 0;
int blueIn1 = 2;

int redVal1;
int blueVal1;

//Relays
int relPin1 = 2;                        //Digital Pin Relay1
int relPin2 = 3;                        //Digital Pin Relay2

//Heating Status
int heat1Val;
#define BACKLIGHT_PIN 13
#define ONE_WIRE_BUS 7
LiquidCrystal_I2C lcd(0x20,20,4);  // set the LCD address to 0x20 for a 20 chars and 4 line display
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup() {
  Serial.begin(9600);
  sensors.begin();
  lcd.init();                      // initialize the lcd
  lcd.backlight();
  pinMode(relPin1, OUTPUT);      //Output Mode for Relay1
  pinMode(relPin2, OUTPUT);      //Output Mode for Relay2
}

void loop() {
  sensors.requestTemperatures();
  float temperature1 = sensors.getTempFByIndex(0);
  lcd.setCursor(0, 0);
  lcd.print("Johnson's Reef");
  lcd.setCursor(0, 1);
  lcd.print("Aquarium: ");
  lcd.print(sensors.getTempFByIndex(0));
  lcd.print(" F ");

  //HEATER
  if(temperature1 < 77)
  {
    redVal1 = 0;
    blueVal1 = 5;
    digitalWrite(relPin1, LOW);  //FAN
    digitalWrite(relPin2, HIGH); //HEATER
    lcd.setCursor(0, 2);
    lcd.print("Heater:   ON ");
    lcd.setCursor(0, 3);
    lcd.print("Fan:      OFF ");
    delay(5000);
  }
  //FAN
  else if(temperature1 > 80)
  {
    redVal1 = 150;
    blueVal1 = 0;
    digitalWrite(relPin1, HIGH);  //FAN
    digitalWrite(relPin2, LOW);  //HEATER
    lcd.setCursor(0, 2);
    lcd.print("Heater:   OFF ");
    lcd.setCursor(0, 3);
    lcd.print("Fan:      ON ");
    delay(5000);
  }
  //HEATER
  else if(temperature1 == 78)
  {
    redVal1 = 0;
    blueVal1 = 0;
    digitalWrite(relPin1, LOW);  //FAN
    digitalWrite(relPin2, LOW);  //HEATER
    lcd.setCursor(0, 2);
    lcd.print("Heater:   OFF ");
    lcd.setCursor(0, 3);
    lcd.print("Fan:      OFF ");
    delay(5000);
  }
  //FAN
  else if(temperature1 == 79)
  {
    redVal1 = 0;
    blueVal1 = 0;
    digitalWrite(relPin1, LOW);  //FAN
    digitalWrite(relPin2, LOW);  //HEATER
    lcd.setCursor(0, 2);
    lcd.print("Heater:   OFF ");
    lcd.setCursor(0, 3);
    lcd.print("Fan:      OFF ");
    delay(5000);
  }
  {
    analogWrite(redPin1, redVal1);
    analogWrite(bluePin1, blueVal1);

  }
}

I'm not sure whether you are saying you've written it and it doesnt work, but one thing that is wrong is

if (temperature1 == 78)

Comparing floats like this doesn't really work, because the chances are the value if not exactly 78 its going to be 78.0001 in which case your comparison would fail, even though you may want it to trigger something to happen

The other thing is that really to get good temperature control you need more complex logic

Look up the Arduino PID library, this will give you better temperature control, but is an entirely different way to do it

It actually works perfectly, but I'm curious being a newbie if I made any mistakes. I don't need this to be super accurate, so long as its accurate to within 2 degrees. I originally only had the lines like this if (temperature1 = 78) but when I was having an issue someone on another forum suggested I use the two equal signs, it solved my problem.

Sorry, my typo

if(temperature1 == 78)

don’t compare floats like this

Use something like

if (fabs(temperature1 - 78)<0.1)
{
}

Ok, I’ll try that tomorrow. What does the “fabs” mean?

floating point absolute value

Returns an always positive number

e.g.

fabs(3.0 - 5.0) = 2.0 and

fabs(5.0 - 2.0) = 2.0

see

http://www.cplusplus.com/reference/cmath/fabs/

Good to know, I’ll take a read. How does this look?

#include <OneWire.h>
#include <Wire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>

//RGBLED
int bluePin1 = 10;                        //Digital Pin for blue LED1 in RGB-LED 
int redPin1 = 12;                         //Digital Pin for red LED1 in RGB-LED 

int redIn1 = 0;
int blueIn1 = 2;

int redVal1;
int blueVal1;

//Relays
int relPin1 = 2;                        //Digital Pin Relay1
int relPin2 = 3;                        //Digital Pin Relay2

//Heating Status
int heat1Val;
#define BACKLIGHT_PIN 13
#define ONE_WIRE_BUS 7
LiquidCrystal_I2C lcd(0x20,20,4);  // set the LCD address to 0x20 for a 20 chars and 4 line display
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup() {
  Serial.begin(9600);
  sensors.begin();
  lcd.init();                      // initialize the lcd
  lcd.backlight();
  pinMode(relPin1, OUTPUT);      //Output Mode for Relay1
  pinMode(relPin2, OUTPUT);      //Output Mode for Relay2
}

void loop() {
  sensors.requestTemperatures();
  float temperature1 = sensors.getTempFByIndex(0);
  lcd.setCursor(0, 0);
  lcd.print("Johnson's Reef");
  lcd.setCursor(0, 1);
  lcd.print("Aquarium: ");
  lcd.print(sensors.getTempFByIndex(0));
  lcd.print(" F ");

  //HEATER
  if(temperature1 < 77)
  {
    redVal1 = 0;
    blueVal1 = 5;
    digitalWrite(relPin1, LOW);  //FAN
    digitalWrite(relPin2, HIGH); //HEATER
    lcd.setCursor(0, 2);
    lcd.print("Heater:   ON ");
    lcd.setCursor(0, 3);
    lcd.print("Fan:      OFF ");
    delay(5000);
  }
  //FAN
  else if(temperature1 > 80)
  {
    redVal1 = 150;
    blueVal1 = 0;
    digitalWrite(relPin1, HIGH);  //FAN
    digitalWrite(relPin2, LOW);  //HEATER
    lcd.setCursor(0, 2);
    lcd.print("Heater:   OFF ");
    lcd.setCursor(0, 3);
    lcd.print("Fan:      ON ");
    delay(5000);
  }
  //HEATER
  else if(fabs(temperature1 - 78)<0.1)
  {
    redVal1 = 0;
    blueVal1 = 0;
    digitalWrite(relPin1, LOW);  //FAN
    digitalWrite(relPin2, LOW);  //HEATER
    lcd.setCursor(0, 2);
    lcd.print("Heater:   OFF ");
    lcd.setCursor(0, 3);
    lcd.print("Fan:      OFF ");
    delay(5000);
  }
  //FAN
  else if(fabs(temperature1 - 79)<0.1)
  {
    redVal1 = 0;
    blueVal1 = 0;
    digitalWrite(relPin1, LOW);  //FAN
    digitalWrite(relPin2, LOW);  //HEATER
    lcd.setCursor(0, 2);
    lcd.print("Heater:   OFF ");
    lcd.setCursor(0, 3);
    lcd.print("Fan:      OFF ");
    delay(5000);
  }
  {
    analogWrite(redPin1, redVal1);
    analogWrite(bluePin1, blueVal1);

  }
}

braces are not needed around

  {
    analogWrite(redPin1, redVal1);
    analogWrite(bluePin1, blueVal1);

  }

As a general point using delay e.g.

delay(5000);

can cause performance issues.

i.e the whole system is locked for 5 seconds and can't do anything even if the temperature has changed

Using the same sort of technique as is used in he BlinkWithoutDelay example (supplied with the Arduino IDE) is often better than using delay()

But delay() is OK for some things, so it could be that delay is Ok for what you want it to do.

The point of the delay was originally to prevent the relay from clicking on and off rapidly if the temp hovered around an ON/OFF temp. There were times when I found that if the probe was reading just over or under the set point, the relay would click on and off rapidly. The delay seemed to help that. Maybe your changes to the code will help though.

If the relay is going on and off quickly, you may need to program in some hysteresis .

But is delay() works, then its not really worth messing around with it.

Seems to so far. I'd like to try with the changes you suggested first.

I've tried to read about hysteresis but it immediately went straight over my head. I understand the principle behind it, but the programming baffles me.