SOLVED - Calling days of the week and time from RTC DS3231

I am in the process of trying to create a three heating zone controller. I have the temperature control section working fine. The RTC and dispaly are also working fine in that the correct time and date are displaying properly. The section of code at Line 127 is meant to initiate the temperature control during a spoecific time period fom Monday to Saturday, with a different time schedule for Sundays. At present the timed section is jsut being bypassed as the temperature congtrol works fine for all three zones, irrespective of the time settings at Line 51-58. I am not sure what to change in my timeswitch coide, Any suggestions, please?

type or paste code here

// Created : 25/01/2024
// Description : Display the current date, time and temperature on the 20x4 LCD screen and create a thermostatic heating control of three zones
// Inspired from this code : File => Examples => RTClib => ds3231 along with parts from several other files/sketches

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

#define ONE_WIRE_BUS_1 3
#define ONE_WIRE_BUS_2 4
#define ONE_WIRE_BUS_3 5

OneWire oneWire_range(ONE_WIRE_BUS_1);
OneWire oneWire_club(ONE_WIRE_BUS_2);
OneWire oneWire_airgun(ONE_WIRE_BUS_3);

const byte range_relay = 9;  // Relay outputs
const byte club_relay = 10;
const byte airgun_relay = 11;
const byte boiler_relay = 12;

float range_temperature;
float club_temperature;
float airgun_temperature;

const float temperature_setpoint_range = 16.0;   // C
const float temperature_setpoint_club = 19.0;    // C
const float temperature_setpoint_airgun = 18.0;  // C
const float frost_setpoint = 12;                 // C
const float deadzone = 0.75;                     // C

DallasTemperature sensor_range(&oneWire_range);
DallasTemperature sensor_club(&oneWire_club);
DallasTemperature sensor_airgun(&oneWire_airgun);

// UNCHANGABLE PARAMATERS
#define Sunday 0
#define Monday 1
#define Tuesday 2
#define Wednesday 3
#define Thursday 4
#define Friday 5
#define Saturday 6

byte Weekday[] = { 1, 2, 3, 4, 5, 6 };
byte Weekend[] = { 0 };

const int OnHour_Normal = 16;  // Timeswitch settings
const int OnMin_Normal = 00;
const int OffHour_Normal = 23;
const int OffMin_Normal = 30;
const int OnHour_Sunday = 12;
const int OnMin_Sunday = 00;
const int OffHour_Sunday = 18;
const int OffMin_Sunday = 00;

LiquidCrystal_I2C lcd(0X27, 20, 4);
RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
byte char_temp[8] = { B00100, B01010, B01010, B01110, B01110, B11111, B11111, B01110 };  // for thermometer icon

void setup() {

  pinMode(range_relay, OUTPUT);
  pinMode(club_relay, OUTPUT);
  pinMode(airgun_relay, OUTPUT);
  pinMode(boiler_relay, OUTPUT);

  rtc.begin();
  lcd.init();
  lcd.backlight();
  lcd.createChar(0, char_temp);
  lcd.setCursor(4, 0);
  lcd.print("Take it easy!");
  lcd.setCursor(4, 1);
  lcd.print("Working on it");
  lcd.setCursor(2, 2);
  lcd.print("G0RJM Three Zone");
  lcd.setCursor(1, 3);
  lcd.print("Temperature Control");
  delay(3000);
  lcd.clear();
  if (rtc.lostPower()) {
    // When the time needs to be set up on a new device, or after a power loss, uncomment the
    // following line. This sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  {
    Serial.begin(9600);
    Serial.println("G0RJM Three zone Temperature Control");

    sensor_range.begin();
    sensor_club.begin();
    sensor_airgun.begin();
  }
}


//------------------------------Temperature control-----------------------------//

void loop() {

  DateTime now = rtc.now();

  {
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
  }

  if ((now.hour() >= OnHour_Normal) && (now.minute() >= OnMin_Normal) && (now.second() >= 00) && (now.dayOfTheWeek() == Weekday)) {
    //  || (now.hour() >= OnHour_Sunday) && (now.minute() >= OnMin_Sunday) && (now.second() >= 00) && (now.dayOfTheWeek() == Weekend)) {
    digitalWrite(boiler_relay, HIGH);
  }

  if (sensor_range.getTempCByIndex(0) < (temperature_setpoint_range - deadzone)) {
    digitalWrite(range_relay, HIGH);
    lcd.setCursor(15, 1);
    lcd.print("ON  T");
  } else {
    if (sensor_range.getTempCByIndex(0) > (temperature_setpoint_range + deadzone))
      digitalWrite(range_relay, LOW);
    lcd.setCursor(15, 1);
    lcd.print("  OFF");
  }

  if (sensor_club.getTempCByIndex(0) < (temperature_setpoint_club - deadzone)) {
    digitalWrite(club_relay, HIGH);
    lcd.setCursor(15, 2);
    lcd.print("ON  T");
  } else {
    if (sensor_club.getTempCByIndex(0) > (temperature_setpoint_club + deadzone))
      digitalWrite(club_relay, LOW);
    lcd.setCursor(15, 2);
    lcd.print("  OFF");
  }

  if (sensor_airgun.getTempCByIndex(0) < (temperature_setpoint_airgun - deadzone)) {
    digitalWrite(airgun_relay, HIGH);
    lcd.setCursor(15, 3);
    lcd.print("ON  T");
  } else {
    if (sensor_airgun.getTempCByIndex(0) > (temperature_setpoint_airgun + deadzone))
      digitalWrite(airgun_relay, LOW);
    lcd.setCursor(15, 3);
    lcd.print("  OFF");
  }
  if ((now.hour() >= OffHour_Normal) && (now.minute() >= OffMin_Normal) && (now.second() >= 00) && (now.dayOfTheWeek() == Weekday)
      || (now.hour() >= OffHour_Sunday) && (now.minute() >= OffMin_Sunday) && (now.second() >= 00) && (now.dayOfTheWeek() == Weekend)) {
    digitalWrite(boiler_relay, HIGH);
  }

  //lcd.setCursor(column,row);
  //------------------------------Date display-----------------------------//
  lcd.setCursor(0, 0);
  lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);
  lcd.setCursor(3, 0);
  // lcd.print("Date:");
  lcd.print(":");
  lcd.setCursor(4, 0);
  if (now.day() <= 9) {
    lcd.print("0");
    lcd.setCursor(5, 0);
    lcd.print(now.day(), DEC);
  } else {
    lcd.print(now.day(), DEC);
  }
  lcd.setCursor(6, 0);
  lcd.print(":");
  lcd.setCursor(7, 0);
  if (now.month() <= 9) {
    lcd.print("0");
    lcd.setCursor(8, 0);
    lcd.print(now.month(), DEC);
  } else {
    lcd.print(now.month(), DEC);
  }
  lcd.setCursor(9, 0);
  lcd.print(":");
  lcd.setCursor(10, 0);
  lcd.print(now.year(), DEC);
  //------------------------------Time display-----------------------------//
  //  lcd.setCursor(0, 1);
  // lcd.print("Time:");
  lcd.setCursor(15, 0);
  if (now.hour() <= 9) {
    lcd.print("0");
    lcd.setCursor(16, 0);
    lcd.print(now.hour(), DEC);
  } else {
    lcd.print(now.hour(), DEC);
  }
  lcd.setCursor(17, 0);
  lcd.print(":");
  lcd.setCursor(18, 0);
  if (now.minute() <= 9) {
    lcd.print("0");
    lcd.setCursor(19, 0);
    lcd.print(now.minute(), DEC);
  } else {
    lcd.print(now.minute(), DEC);
  }
  lcd.setCursor(17, 0);
  lcd.print(":");
  lcd.setCursor(18, 0);

  // if (now.second() <=9 )
  //  {
  //   lcd.print("0");
  //   lcd.setCursor(13,1);
  //   lcd.print(now.second(),DEC);
  // }
  // else {lcd.print(now.second(),DEC);}
  //------------------------------Temperature display - -----------------------------//
  {
    Serial.print("Requesting temperatures...");
    sensor_range.requestTemperatures();
    sensor_club.requestTemperatures();
    sensor_airgun.requestTemperatures();
    Serial.println(" done");

    Serial.print("Range: ");
    Serial.println(sensor_range.getTempCByIndex(0));

    Serial.print("Club: ");
    Serial.println(sensor_club.getTempCByIndex(0));

    Serial.print("Airgun: ");
    Serial.println(sensor_airgun.getTempCByIndex(0));
  }

  {
    lcd.setCursor(0, 1);  // Range
    lcd.print("Range:");
    lcd.setCursor(7, 1);
    // lcd.print(rtc.getTemperature());
    lcd.print(sensor_range.getTempCByIndex(0));

    lcd.setCursor(12, 1);
    lcd.write((char)223);
    lcd.setCursor(13, 1);
    lcd.print("C");
    // lcd.setCursor(18, 1);
    // lcd.print(char(0));

    lcd.setCursor(0, 2);  // Clubroom
    lcd.print("Club:");
    lcd.setCursor(7, 2);
    // lcd.print(rtc.getTemperature());
    lcd.print(sensor_club.getTempCByIndex(0));

    lcd.setCursor(12, 2);
    lcd.write((char)223);
    lcd.setCursor(13, 2);
    lcd.print("C");
    // lcd.setCursor(14, 2);
    // lcd.print("    ");
    // lcd.print(char(0));

    lcd.setCursor(0, 3);  // Airgun Range
    lcd.print("Airgun:");
    lcd.setCursor(7, 3);
    // lcd.print(rtc.getTemperature());
    lcd.print(sensor_airgun.getTempCByIndex(0));

    lcd.setCursor(12, 3);
    lcd.write((char)223);
    lcd.setCursor(13, 3);
    lcd.print("C");
    // lcd.setCursor(18, 3);
    // lcd.print(char(0));

    delay(5000);
  }
}

You are expecting too much of the program!

This

  if ((now.hour() >= OnHour_Normal) && (now.minute() >= OnMin_Normal) && (now.second() >= 00) && (now.dayOfTheWeek() == Weekday)) {
    //  || (now.hour() >= OnHour_Sunday) && (now.minute() >= OnMin_Sunday) && (now.second() >= 00) && (now.dayOfTheWeek() == Weekend)) {
    digitalWrite(boiler_relay, HIGH);
  }

uses array variables as if they were scalars. Or some kind of other language feature. Your intent is clear but C/C++ will not examine the arrays and see if a number is in one or the other.

  if ((now.hour() >= OnHour_Normal) && (now.minute() >= OnMin_Normal) && (now.second() >= 00) && (now.dayOfTheWeek() != Sunday) {
      || (now.hour() >= OnHour_Sunday) && (now.minute() >= OnMin_Sunday) && (now.second() >= 00) && (now.dayOfTheWeek() == Sunday)) {
    digitalWrite(boiler_relay, HIGH);
  }

is as closer as I can get you from under the umbrella.

Note: check the valuse of the day of week reported by the RTC. I think it may go 1..7, not 0..6, so you'd have yo adjust your defined constants and other uses of day of the week number.

If you did want Saturday and Sunday, you'd have to use some kind of logic like a simple array of boolean variables to indicate which of two times to use

bool useWeekendTime[7] = {true, true, false,  false,  true,  false,  false,};

but this, too would need to be indexed by Day of Week - 1. I think. PLease check as I recommended.

HTH

a7

Have you tried printing the values that are being used in the test on line 127 before they are tested ? Are they what you expect ?

Is it necessary to test now.second() as it will always be greater or equal to zero ?

Thank you both for your advice and guidance. I will need to rethink and had not thought about missing out the now.second. I will look into printing out the values from Line 127.

The chip uses 1-7. Some libraries remap this to 0-6 to be more compatible with Unix style time functions. Usually from a look at the library .h file(s) you can figure out what they do.

Noted, THX.

That's the kind of thing that causes me lotsa grief, though I understand the library writer's decision.

a7

Thank you alto777 and UKHeliBob. I have checked the day of the week configuration with the Adafruit RTClib and corrected that. I have removed the seconds request from the time call function and used the suggested format from alto777. These suggestions have helped the project along. I am now able to proceed to the next part.
Many thanks again.

We like to help.

I don't know if you are reading other threads, here's a current one that might give you some more ideas:

a7

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.