My simple thermostat code, anyone care to critique?

One thing has been bugging me about my heating system, it's not smart in any way. It just turns on and off at set temperatures and that's it. One thing I want is the house be warm when we get out of bed.

I'm new to Arduino and I've been learning how to code over the last 6 months with this project in mind.
I've finally had the time and head-space to dedicate to this project, my relays have arrived and I've got the Dallas temperature working alongside the time module.

I must say at this stage my heating simply uses a two wire system that is turned off and on by a very basic thermostat. So it's easy for me to program in some functions using the Arduino.

Anyway I've written this code that seems to work but I realize my knowledge is limited and I've probably gone the long way around setting this up. I'd love some feedback or improvements or just how to make the code tighter or better.

I've also just realized that if the power to the Arduino is turned off the trigger for the time won't know where it is, that's something I'll need to work out, expecially as the time rolls over at 12am.

Basic overview is:
Check what time period we are in, then check the temp range for that period by looking at the variable- if it's over or under, turn on or off the relay.

Any feedback appreciated.

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

// Data wire is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS 7

int insideThermometerInt = 0;

//What time mode are we in currently

int dayTime = 0;
int nightTime = 0;
int sixAM = 0;
int sixThirty = 0;


//Temp range for time modes
//Max temps

int dayTimeMaxTemp = 19.50;
int nightTimeMaxTemp = 16.50;
int sixAMMaxTemp = 17.50;
int sixThirtyMaxTemp = 18.50;

//Min temps

int dayTimeMinTemp = 18.50;
int nightTimeMinTemp = 15.50;
int sixAMMinTemp = 16.50;
int sixThirtyMinTemp = 17.50;


// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

DeviceAddress insideThermometer = { 0x28, 0x78, 0xD5, 0xB5, 0x05, 0x00, 0x00, 0x8E };

void setup(void)
{
  // start serial port
  Serial.begin(9600);
  // Start up the library
  sensors.begin();
  // set the resolution to 10 bit (good enough?)
  sensors.setResolution(insideThermometer, 10);

//RTC setup
  Wire.begin();
  rtc.begin();

//LED or relay pins
 pinMode(2, OUTPUT);

}


void loop(void)
{
  //Get time
  DateTime now = rtc.now();
  
  delay(500);
  
  sensors.requestTemperatures();

 delay(500);

 
 float realTimeTempC = sensors.getTempC(insideThermometer);
  Serial.print("Current temperature is: ");
  Serial.print(realTimeTempC);
  
  //printTemperature(insideThermometer);
  Serial.print("\n\r");

//Check what time period we are in currently and set the appropriate variable


  //Check for night time setting
   if(now.hour() == 21){
     dayTime = 0;
     nightTime = 1;
     sixAM = 0;
     sixThirty = 0;
     
   }

   //Check for 6am time setting
   if(now.hour() == 6){
     dayTime = 0;
     nightTime = 0;
     sixAM = 1;
     sixThirty = 0;
     
   }
   
   //Check for 6:30am time setting
     if(now.hour() == 6 && now.minute() == 30){
      dayTime = 0;
     nightTime = 0;
     sixAM = 0;
     sixThirty = 1;
     
   }
   
   //Check for dayTime time setting
   if(now.hour() == 7){
     dayTime = 1;
     nightTime = 0;
     sixAM = 0;
     sixThirty = 0;
     
   }
   
//Check temp is in range for correct time of day

//Day time and temp range check

if (realTimeTempC <= dayTimeMaxTemp && dayTime == 1) {
  //Start heating
  digitalWrite(2, HIGH);
} 

if (realTimeTempC >= dayTimeMinTemp && dayTime == 1) {
  //Stop heating
  digitalWrite(2, LOW);
 } 



//Night time and temp range check

if (realTimeTempC <= nightTimeMaxTemp && nightTime == 1) {
  //Start heating
  digitalWrite(2, HIGH);
} 

if (realTimeTempC >= nightTimeMinTemp && nightTime == 1) {
  //Stop heating
  digitalWrite(2, LOW);
 } 


//6am time and temp range check

if (realTimeTempC <= sixAMMaxTemp && sixAM == 1) {
  //Start heating
  digitalWrite(2, HIGH);
} 

if (realTimeTempC >= sixAMMinTemp && sixAM == 1) {
  //Stop heating
  digitalWrite(2, LOW);
 } 


//6:30am time and temp range check

 if (realTimeTempC <= sixThirtyMaxTemp && sixThirty == 1) {
  //Start heating
  digitalWrite(2, HIGH);
} 

if (realTimeTempC >= sixThirtyMinTemp && sixThirty == 1) {
  //Stop heating
  digitalWrite(2, LOW);
 } 



//Print the current time 
//Debugging section

    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    
    Serial.println();

    Serial.print("dayTime value: ");
    Serial.print (dayTime);
    Serial.println();
    Serial.print("nightTime value: ");
    Serial.print (nightTime);
    Serial.println();
    Serial.print("sixAM value: ");
    Serial.print (sixAM);
    Serial.println();
    Serial.print("sixThirty value: ");
    Serial.print (sixThirty);
    Serial.println();
    Serial.println();
    

delay(3000);
}
int dayTimeMaxTemp = 19.50;
int nightTimeMaxTemp = 16.50;
int sixAMMaxTemp = 17.50;
int sixThirtyMaxTemp = 18.50;

The int type does not hold decimal places so all those .50 have been truncated.

I've also just realized that if the power to the Arduino is turned off the trigger for the time won't know where it is, that's something I'll need to work out, expecially as the time rolls over at 12am.

What do you mean? The RTC will tell it the time.

Thanks Nick. I didn't know that the .50 would be truncated, my original testing only used round numbers.

What do you mean? The RTC will tell it the time.

In my code it's looking for a specific hour to trigger events, if the Arduino lost power after 8am it wouldn't know what time of day it was. I think I need to put in "greater-than"

//Check for dayTime time setting
   if(now.hour() >= 7){
     dayTime = 1;
     nightTime = 0;
     sixAM = 0;
     sixThirty = 0;

Also when it gets to 12am the nighttime mode would need to have another function because it's rolled over from 23:59 - 00:00 therefore the greater-than wouldn't work.

Oh, yeah, you can't test equal-to.

int dayTime = 0;
int nightTime = 0;

It won't be both day and night will it? So you may as well have one variable.

So:

bool dayTime;

...

dayTime = now.hour() >= 7 && now.hour() <= 21;

Then just test dayTime and check the temperature is in the desired range.

if (dayTime)
  {
  // check temperature OK for day
  }
else
  {  // must be night
  // check temperature OK for night
  }

Exactly thanks.

dayTime = now.hour() >= 7 && now.hour() <= 21;

The above code would need to be in the "loop" wouldn't it, because it needs to check every time it runs through the loop or is it put in "setup" because we are defining the variable not actually setting it?

Thanks.

I prefer that pins are declared together in the global section (above setup() ).

const int pinOneWire = 7;
const int pinRelay = 2;

Please use the brackets, spaces and indents in the same way (the way that you prefer). It makes it easier to find a bug.

digitalkiwi:
Exactly thanks.

dayTime = now.hour() >= 7 && now.hour() <= 21;

The above code would need to be in the "loop" wouldn't it, because it needs to check every time it runs through the loop or is it put in "setup" because we are defining the variable not actually setting it?

Thanks.

Yes, it would be in loop. This is assigning to the variable, not defining it. The time of day, after all, varies.