Sure ! You seem to have not looked into many other threads than your own.
this is still way too UNprecise for analysing.
One way to find a bug is extra-ordinary excessive serial debug printing.
You observe switching relays. Which should not happen. So making visible
WHEN and WHERE in the code the switching happends will guide to the place in the code where it happends.
I have taken the effort to add a lot of serial debug-printing into your code.
For this I moved all fixed-string printing from RAM to flash-memory by using the
F-Macro which frees up 1 kB of RAM
I added my debug-macros at the top of the code.
I added this function
void printRelayStateChanges() {
dbgc("01", digitalRead(range_relay) );
dbgc("02", digitalRead(club_relay) );
dbgc("03", digitalRead(airgun_relay) );
dbgc("04", digitalRead(boiler_relay) );
}
which works this way:
example for digitalRead(range_relay)
only in case the expression digitalRead(range_relay) has changed its value this change will be printed.
If the value stayed the same it will not print.
dbgc
dbg for "debug"
"c" for Change
I added serial printing to most of the functions when entering an when leaving the function.
This will make visible the code-execution in much more detail.
Analysing this amout of serial printing requires IDE 1.8.19
I am really sorry to continiue with big red bolded capital letters. They are meant as
emphasizing.
They are not meant as aggressive shouting.
Read it ? They are not meant as aggressive shouting.
They are meant as
the 25th time complaining about Arduino IDE 2.X not beeing able to use serial printing in a comfortable way
Analysing this amout of serial printing
CAN'T BE DONE WITH ARDUINO IDE 2.X !!
(as a sidemark: @ptillisch if you know the person who is repsonsible for deciding
to add this functionality to IDE 2.X Ask this person what alternatives does IDE 2.X offer for debugging in a case like this. Can it be done by hardware-debugging on an Arduino Uno R3?"
)
For analysing this, Arduino IDE 1.8.19 must be used
Here is a tutorial that explains how tp install Arduino IE Version 1.8.19 as a portable version
that works completely independant of any other Arduino IDE-installation
You can flash your code with IDE 2.X and then run IDE 1.8.19 adjust serial monitor to the correct COM-Port and open serial monitor
// MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *
// a detailed explanation how these macros work is given in this tutorial
// https://forum.arduino.cc/t/comfortable-serial-debug-output-short-to-write-fixed-text-name-and-content-of-any-variable-code-example/888298
#define dbg(myFixedText, variableName) \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName);
#define dbgi(myFixedText, variableName,timeInterval) \
{ \
static unsigned long intervalStartTime; \
if ( millis() - intervalStartTime >= timeInterval ){ \
intervalStartTime = millis(); \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName); \
} \
}
#define dbgc(myFixedText, variableName) \
{ \
static long lastState; \
if ( lastState != variableName ){ \
Serial.print( F(#myFixedText " " #variableName" changed from ") ); \
Serial.print(lastState); \
Serial.print( F(" to ") ); \
Serial.println(variableName); \
lastState = variableName; \
} \
}
#define dbgcf(myFixedText, variableName) \
{ \
static float lastState; \
if ( lastState != variableName ){ \
Serial.print( F(#myFixedText " " #variableName" changed from ") ); \
Serial.print(lastState); \
Serial.print( F(" to ") ); \
Serial.println(variableName); \
lastState = variableName; \
} \
}
// MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *
unsigned long MyTestTimer = 0; // Timer-variables MUST be of type unsigned long
const byte OnBoard_LED = 2; // onboard-LEDESP32 / ESP8266
/* Author : John Marchant G0RJM
Created : 25/01/2024 - 18/10/2024
Description : A project to display the current date, time and temperature on the 20x4 LCD screen
and create a programmable thermostatic heating control of three zones to include frost protection and override facilities.
This has been loosely based on the RTClib ds3231 example along with many code parts borrowed
from several other files/sketches and in collaboration with several authors from the
Arduino Forum in particular @alto777, @blh64, @cattledog, @StefanL38 and @UKHeliBob. */
#include "RTClib.h"
#include <OneWire.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ezButton.h>
#include <DallasTemperature.h>
#include <EEPROM.h>
#include <DST_RTC.h>
#define ONE_WIRE_BUS_1 3
#define ONE_WIRE_BUS_2 4
#define ONE_WIRE_BUS_3 5
#define TEMPERATURE_PRECISION 11 // 0.125deg resolution
#define buzzer_pin A0
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 = 10; // Relay outputs
const byte club_relay = 11;
const byte airgun_relay = 12;
const byte boiler_relay = 13;
float range_temperature;
float club_temperature;
float airgun_temperature;
float range_temperature_setpoint; // C
float club_temperature_setpoint; // C
float airgun_temperature_setpoint; // C
const int frost_setpoint = 12.0; // C
const float deadzone = 1.0; // C
ezButton leftbutton(6); // create ezButton object that is attached to pin 6;
ezButton upbutton(7); // create ezButton object that is attached to pin 7;
ezButton downbutton(8); // create ezButton object that is attached to pin 8;
ezButton rightbutton(9); // create ezButton object that is attached to pin 9;
const int ledPin = 13;
const unsigned menuOnTime = 20000;
const unsigned upButtonTime = 50;
const unsigned downButtonTime = 50;
const unsigned printInterval = 3000;
const unsigned overrideRunTime = 45000;
const unsigned backlightOnTime = 30000;
int value = 0;
int selector = 0;
int EEPROM_address_1 = 0; // Address of the location of range setpoint temperature
int EEPROM_address_2 = 4; // Address of the location of club setpoint temperature
int EEPROM_address_3 = 8; // Address of the location of airgun setpoint temperature
unsigned long startMillis = 0;
unsigned long menuOffTime = 0;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long previousMillisMenu = 0;
unsigned long previousMillisBacklight = 0;
unsigned long previousMillisOverrideStart = 0;
unsigned long previousMillisAdjustSetpointUp = 0;
unsigned long previousMillisAdjustSetpointDown = 0;
bool isMenuOn = false; // if = True initiiates the setup menu
bool isRangeHeatOn = false; // if = True this allows the Range heating
bool isClubHeatOn = false; // if = True this allows the Club heating
bool isAirgunHeatOn = false; // if = True this allows the Airgun heating
bool isSetpointSave = false; // if = True allows the new setpoints to be saved to EEPROM
bool isTimeControlOn = false; // if = True allows normal time control function
bool isHeatingOverride = false; // if = True allows the heating override facility
bool isAdjustSetpointUp = false; // if = True allows the Setpoint increment
bool isAdjustSetpointDown = false; // if = True allows the Setpoint decrement
bool isRangeSetpointAdjust = false; // if = True allows the range setpoint to be adjusted
bool isClubSetpointAdjust = false; // if = True allows the club setpoint to be adjusted
bool isAirgunSetpointAdjust = false; // if = True allows the airgun setpoint to be adjusted
DallasTemperature range_sensor(&oneWire_range);
DallasTemperature club_sensor(&oneWire_club);
DallasTemperature airgun_sensor(&oneWire_airgun);
enum { SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
};
const int On_Normal_Range = 16 * 60UL + 00; // 16:00 Normal ON time
const int Off_Normal_Range = 19 * 60UL + 30; // 21:30 Normal OFF time
const int On_Normal_Club = 16 * 60UL + 00; // 16:00 Normal ON time
const int Off_Normal_Club = 19 * 60UL + 30; // 21:30 Normal OFF time
const int On_Normal_Airgun = 16 * 60UL + 00; // 16:00 Normal ON time
const int Off_Normal_Airgun = 19 * 60UL + 30; // 21:30 Normal OFF time
const int On_Sunday = 12 * 60UL + 00; // 12:00 Sunday ON time
const int Off_Sunday = 17 * 60UL + 30; // 17:30 Sunday OFF time
LiquidCrystal_I2C lcd(0X27, 20, 4);
RTC_DS3231 rtc;
DST_RTC dst_rtc; // DST object
// Define US or EU rules for DST comment out as required. More countries could be added with different rules in DST_RTC.cpp
// const char rulesDST[] = "US"; // US DST rules
const char rulesDST[] = "EU"; // EU DST rules
char daysOfTheWeek[7][4] = { "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(ledPin, OUTPUT);
pinMode(buzzer_pin, OUTPUT);
leftbutton.setDebounceTime(50); // set debounce time to 50 milliseconds
upbutton.setDebounceTime(50); // set debounce time to 50 milliseconds
downbutton.setDebounceTime(50); // set debounce time to 50 milliseconds
rightbutton.setDebounceTime(50); // set debounce time to 50 milliseconds
Serial.begin(9600);
// EEPROM.put(EEPROM_address_1, range_temperature_setpoint); // write the float value to EEPROM ONLY used to initially set up setpoint
// EEPROM.put(EEPROM_address_2, club_temperature_setpoint); // write the float value to EEPROM ONLY used to initially set up setpoint
// EEPROM.put(EEPROM_address_3, airgun_temperature_setpoint); // write the float value to EEPROM ONLY used to initially set up setpoint
RetrieveSetpoint();
startMillis = millis();
Wire.begin();
rtc.begin();
lcd.init();
lcd.backlight();
lcd.createChar(0, char_temp);
lcd.setCursor(2, 0);
lcd.print("G0RJM Three Zone");
lcd.setCursor(1, 1);
lcd.print("Temperature Control");
lcd.setCursor(4, 2);
lcd.print("Take it easy!");
lcd.setCursor(4, 3);
lcd.print("Working on it");
delay(1000);
lcd.clear();
if (rtc.lostPower()) {
Serial.println( F("RTC is NOT running!") ) ;
// Uncomment the following line to set the RTC to the date & time this sketch was compiled
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// rtc.adjust(DateTime(2024,4,24,21,49,00));
/* DST? If we're in it, let's subtract an hour from the RTC time to keep our DST calculation correct. This gives us
Standard Time which our DST check will add an hour back to if we're in DST.
*/
DateTime standardTime = rtc.now();
if (dst_rtc.checkDST(standardTime) == true) { // check whether we're in DST right now. If we are, subtract an hour.
standardTime = standardTime.unixtime() - 3600;
}
rtc.adjust(standardTime);
}
// Serial.println( F("G0RJM Three zone Temperature Control") );
range_sensor.begin();
club_sensor.begin();
airgun_sensor.begin();
range_sensor.setResolution(TEMPERATURE_PRECISION);
club_sensor.setResolution(TEMPERATURE_PRECISION);
airgun_sensor.setResolution(TEMPERATURE_PRECISION);
} // End of setup
void printRelayStateChanges() {
dbgc("01", digitalRead(range_relay) );
dbgc("02", digitalRead(club_relay) );
dbgc("03", digitalRead(airgun_relay) );
dbgc("04", digitalRead(boiler_relay) );
}
void loop() {
printRelayStateChanges();
// ("ABCDEFGHIJ1234567890")
//-------------------------Button control---------------------------//
leftbutton.loop(); // MUST call the loop() function first
upbutton.loop(); // MUST call the loop() function first
downbutton.loop(); // MUST call the loop() function first
rightbutton.loop(); // MUST call the loop() function first
// -----------------------Backlight display-------------------------//
unsigned long currentMillis = millis(); // all time elements are data type unsigned long
if ((isHeatingOverride) || (leftbutton.isPressed() || (rightbutton.isPressed() || (upbutton.isPressed())))) {
lcd.backlight();
previousMillisBacklight = currentMillis;
}
printRelayStateChanges();
if ((!isHeatingOverride) && (currentMillis - previousMillisBacklight >= backlightOnTime)) {
lcd.noBacklight();
isMenuOn = false;
}
printRelayStateChanges();
//---------------------------Heating Override-----------------------//
if ((downbutton.isPressed() && (!isMenuOn) && (!isHeatingOverride))) {
isHeatingOverride = true; // Establishes the heating override
HeatingOverride();
Serial.println( F(" manual start of override" ) );
previousMillisOverrideStart = currentMillis;
}
printRelayStateChanges();
if (isHeatingOverride) {
if (currentMillis - previousMillisOverrideStart >= overrideRunTime) // Automatically cancels the override
{
Serial.println( F(" auto termination of override") );
HeatingOverrideComplete();
}
}
printRelayStateChanges();
if ((downbutton.isPressed() && (!isMenuOn) && (isHeatingOverride))) // Manually cancels the override
{
if (currentMillis - previousMillisOverrideStart >= 10000) {
Serial.println( F(" manual termination of override") );
HeatingOverrideComplete();
}
}
printRelayStateChanges();
//------------------------Boiler Interlock--------------------------//
if ((digitalRead(range_relay) == HIGH) || (digitalRead(club_relay) == HIGH) || (digitalRead(airgun_relay) == HIGH)) {
digitalWrite(boiler_relay, HIGH);
}
else {
digitalWrite(boiler_relay, LOW);
Serial.println( F("08 else to digitalRead(range_relay) == HIGH) || (digitalRead(club_relay) == HIGH) || (digitalRead(airgun_relay) == HIGH ") );
}
printRelayStateChanges();
if (!isMenuOn) {
TemperatureDisplay();
}
printRelayStateChanges();
//------------------------------Menu--------------------------------//
if (leftbutton.isPressed()) {
isMenuOn = true; // Initiiates the setup menu
SettingMenu();
selector++; // this is done after SettingMenu(), so case 0 will be executed on the first button press
if (selector > 5) {
selector = 0;
}
previousMillisMenu = currentMillis;
}
printRelayStateChanges();
if (isMenuOn) {
if (currentMillis - previousMillisMenu >= menuOnTime) {
isMenuOn = false;
selector = 6;
delay(2000);
lcd.noBacklight();
}
printRelayStateChanges();
}
//------------------------------------------------------------------//
if (upbutton.isPressed()) {
isAdjustSetpointUp = true; // Setpoint adjustment upwards is available
previousMillisAdjustSetpointUp = currentMillis;
}
printRelayStateChanges();
if (isAdjustSetpointUp) {
if (currentMillis - previousMillisAdjustSetpointUp >= upButtonTime) {
isAdjustSetpointUp = false;
}
printRelayStateChanges();
}
//------------------------------------------------------------------//
if (isAdjustSetpointUp && isRangeSetpointAdjust) // If True, this allows the Range setpoint to be adjusted
{
range_temperature_setpoint += 0.1; // Range Setpoint increment
// Serial.println( F("range_temperature_setpoint_up") ) ;
RangeDisplay();
Buzzer();
}
printRelayStateChanges();
if (isAdjustSetpointUp && isClubSetpointAdjust) // If True, this allows the Club setpoint to be adjusted
{
club_temperature_setpoint += 0.1; // Club Setpoint increment
// Serial.println( F("club_temperature_setpoint_up") );
ClubDisplay();
Buzzer();
}
printRelayStateChanges();
if (isAdjustSetpointUp && isAirgunSetpointAdjust) // If True, this allows the Airgun setpoint to be adjusted
{
airgun_temperature_setpoint += 0.1; // Airgun Setpoint increment
// Serial.println( F("airgun_temperature_setpoint_up") );
AirgunDisplay();
Buzzer();
}
printRelayStateChanges();
//------------------------------------------------------------------//
if (downbutton.isPressed()) {
isAdjustSetpointDown = true; // Setpoint adjustment Downwards is available
previousMillisAdjustSetpointDown = currentMillis;
}
printRelayStateChanges();
if (isAdjustSetpointDown) {
if (currentMillis - previousMillisAdjustSetpointDown >= downButtonTime) {
isAdjustSetpointDown = false;
}
}
printRelayStateChanges();
if (isAdjustSetpointDown && isRangeSetpointAdjust) // If True, this allows the Range setpoint to be adjusted
{
range_temperature_setpoint -= 0.1; // Range Setpoint decrement
// Serial.println( F("range_temperature_setpoint_down") );
RangeDisplay();
Buzzer();
}
printRelayStateChanges();
if (isAdjustSetpointDown && isClubSetpointAdjust) // If True, this allows the Club setpoint to be adjusted
{
club_temperature_setpoint -= 0.1; // Club Setpoint decrement
// Serial.println( F("club_temperature_setpoint_down") );
ClubDisplay();
Buzzer();
}
printRelayStateChanges();
if (isAdjustSetpointDown && isAirgunSetpointAdjust) // If True, this allows the Airgun setpoint to be adjusted
{
airgun_temperature_setpoint -= 0.1; // Airgun Setpoint decrement
// Serial.println( F("airgun_temperature_setpoint_down") );
AirgunDisplay();
Buzzer();
}
printRelayStateChanges();
//-----------------------Setpoint Save------------------------------//
if (isSetpointSave && isAdjustSetpointUp && isAdjustSetpointDown) // If True, the new temperature setpoints are saved to EEPROM
{
for (int n = 0; n < 1; n++) {
printRelayStateChanges();
Serial.println( F("Changes saved") );
EEPROM.put(EEPROM_address_1, range_temperature_setpoint); // write the new range setpoint value to EEPROM, only if it has changed
EEPROM.put(EEPROM_address_2, club_temperature_setpoint); // write the new club setpoint value to EEPROM, only if it has changed
EEPROM.put(EEPROM_address_3, airgun_temperature_setpoint); // write the new airgun setpoint value to EEPROM, only if it has changed
delay(2000);
RetrieveSetpoint();
printRelayStateChanges();
lcd.setCursor(3, 3);
lcd.print("Settings saved");
delay(3000);
lcd.clear();
TemperatureDisplay();
printRelayStateChanges();
HeatingAvailable();
printRelayStateChanges();
}
}
//----------------------------Print delay---------------------------//
if (currentMillis - previousMillis >= printInterval) // has enough time passed yet?
{
previousMillis = previousMillis + printInterval; // If yes, set the time del;ay for the next print event
// capture & print data, or print latest data, etc.
// the closing curly brace at end of loop.
//--------------------Daylight Saving Setting---------------------//
DateTime standardTime = rtc.now();
Serial.println( F("Standard Time") );
printTheTime(standardTime);
DateTime theTime = dst_rtc.calculateTime(standardTime); // takes into account DST
Serial.println( F("Time adjusted for Daylight Saving Time") );
printTheTime(theTime);
//-----------------------Timeswitch Control-----------------------//
int currentTime = theTime.hour() * 60UL + theTime.minute();
//--------------------Timed heating setting-----------------------//
if (theTime.dayOfTheWeek() != SUNDAY) {
// Monday to Saturday so use normal times
if (currentTime < On_Normal_Range || currentTime > Off_Normal_Range) {
// this is outside normal range heating time
isRangeHeatOn = false;
}
else {
// this is within normal range heating time
isRangeHeatOn = true;
}
}
else {
// Sunday times
if (currentTime < On_Sunday || currentTime > Off_Sunday) {
// this is outside Sunday range heating time
isRangeHeatOn = false;
}
else {
// this is within Sunday range heating time
isRangeHeatOn = true;
}
}
printRelayStateChanges();
if (theTime.dayOfTheWeek() != SUNDAY) {
// Monday to Saturday so use normal times
if (currentTime < On_Normal_Club || currentTime > Off_Normal_Club) {
// this is outside normal club heating time
isClubHeatOn = false;
}
else {
// this is within normal club heating time
isClubHeatOn = true;
}
}
else {
// Sunday times
if (currentTime < On_Sunday || currentTime > Off_Sunday) {
// this is outside Sunday club heating time
isClubHeatOn = false;
} else {
// this is within Sunday club heating time
isClubHeatOn = true;
}
}
if (theTime.dayOfTheWeek() != SUNDAY) {
// Monday to Saturday so use normal times
if (currentTime < On_Normal_Airgun || currentTime > Off_Normal_Airgun) {
// this is outside normal airgun heating time
isAirgunHeatOn = false;
}
else {
// this is within normal airgun heating time
isAirgunHeatOn = true;
}
}
else {
// Sunday times
if (currentTime < On_Sunday || currentTime > Off_Sunday) {
// this is outside Sunday airgun heating time
isAirgunHeatOn = false;
}
else {
// this is within Sunday airgun heating time
isAirgunHeatOn = true;
}
}
printRelayStateChanges();
//---------------------Date & Time display----------------------//
if ((isTimeControlOn) || (!isMenuOn)) {
Serial.println( F("Time & date showing on LCD") );
lcd.setCursor(0, 0);
lcd.print(daysOfTheWeek[theTime.dayOfTheWeek()]);
lcd.setCursor(3, 0);
lcd.print(":");
lcd.setCursor(4, 0);
if (theTime.day() < 10) lcd.print('0');
lcd.print(theTime.day(), DEC);
lcd.print(':');
if (theTime.month() < 10) lcd.print('0');
lcd.print(theTime.month(), DEC);
lcd.print(':');
lcd.print(theTime.year(), DEC);
lcd.setCursor(15, 0);
if (theTime.hour() < 10) lcd.print('0');
lcd.print(theTime.hour(), DEC);
lcd.print(':');
if (theTime.minute() < 10) lcd.print('0');
lcd.print(theTime.minute(), DEC);
HeatingAvailable();
}
printRelayStateChanges();
//------------------------Serial print---------------------------//
Serial.print( F("Requesting temperatures...") );
range_sensor.requestTemperatures();
club_sensor.requestTemperatures();
airgun_sensor.requestTemperatures();
Serial.println( F(" done") );
Serial.print( F("Range: ") );
Serial.println(range_sensor.getTempCByIndex(0));
Serial.print( F("Club: ") );
Serial.println(club_sensor.getTempCByIndex(0));
Serial.print( F("Airgun: ") );
Serial.println(airgun_sensor.getTempCByIndex(0));
}
} // End of loop
//----------------------Print time to serial-------------------------//
void printTheTime(DateTime theTimeP) {
Serial.print(theTimeP.year(), DEC);
Serial.print('/');
Serial.print(theTimeP.month(), DEC);
Serial.print('/');
Serial.print(theTimeP.day(), DEC);
Serial.print(' ');
Serial.print(theTimeP.hour(), DEC);
Serial.print(':');
Serial.print(theTimeP.minute(), DEC);
Serial.print(':');
Serial.print(theTimeP.second(), DEC);
Serial.println();
}
//------------------------Retrieve setpoint--------------------------//
void RetrieveSetpoint() {
EEPROM.get(EEPROM_address_1, range_temperature_setpoint); //retrieve the range setpoint from EEPROM
EEPROM.get(EEPROM_address_2, club_temperature_setpoint); //retrieve the club setpoint from EEPROM
EEPROM.get(EEPROM_address_3, airgun_temperature_setpoint); //retrieve the airgun setpoint from EEPROM
Serial.print( F("Range Temperature Setpoint - ") );
Serial.print(range_temperature_setpoint);
Serial.print( F(" Stored at addr ") );
Serial.println(EEPROM_address_1);
Serial.print( F("Club Temperature Setpoint - ") );
Serial.print(club_temperature_setpoint);
Serial.print( F(" Stored at addr ") );
Serial.println(EEPROM_address_2);
Serial.print( F("Airgun Temperature Setpoint - ") );
Serial.print(airgun_temperature_setpoint);
Serial.print( F(" Stored at addr ") );
Serial.println(EEPROM_address_3);
}
//------------------------Setting Menu-------------------------------//
void SettingMenu() {
switch (selector) {
case 0:
Serial.println( F("Case 0") ); // General menu
MenuScreen();
break;
case 1:
Serial.println( F("Case 1") ); // Displays the Range setpoint
RangeDisplay();
Buzzer();
break;
case 2:
Serial.println( F("Case 2") ); // Displays the Club setpoint
ClubDisplay();
Buzzer();
break;
case 3:
Serial.println( F("Case 3") ); // Displays the Airgun setpoint
AirgunDisplay();
Buzzer();
break;
case 4:
Serial.println( F("Case 4") ); // Instructs how to save the new settings
SaveDisplay();
break;
case 5:
Serial.println( F("Case 5") ); // Reminds you to save
lcd.clear();
lcd.setCursor(3, 2);
lcd.print( F("Did you save?") );
Buzzer();
}
}
//---------------------------Buzzer----------------------------------//
void Buzzer() {
digitalWrite(buzzer_pin, HIGH);
delay(100);
digitalWrite(buzzer_pin, LOW);
}
//-------------------------Menu screen-------------------------------//
void MenuScreen() {
lcd.clear();
lcd.print(" Setting Menu: ");
lcd.setCursor(0, 1);
lcd.print("Range: ");
lcd.print(range_temperature_setpoint, 1);
lcd.write((char)223);
lcd.print('C');
lcd.setCursor(0, 2);
lcd.print("Club: ");
lcd.print(club_temperature_setpoint, 1);
lcd.write((char)223);
lcd.print('C');
lcd.setCursor(0, 3);
lcd.print("Airgun:");
lcd.print(airgun_temperature_setpoint, 1);
lcd.write((char)223);
lcd.print('C');
isSetpointSave = false;
}
//-----------------------Setting Displays---------------------------//
void RangeDisplay() {
Serial.println( F("enter RangeDisplay") );
isRangeSetpointAdjust = true;
isClubSetpointAdjust = false;
isAirgunSetpointAdjust = false;
Serial.println( F("RangeChange") );
lcd.clear();
lcd.print(" Setting Menu: ");
lcd.setCursor(0, 1);
lcd.print("Range: ");
lcd.print(range_temperature_setpoint, 1);
lcd.write((char)223);
lcd.print('C');
printRelayStateChanges();
Serial.println( F("exit RangeDisplay") );
}
//-------------------------------------------------------------------//
void ClubDisplay() {
Serial.println( F("enter ClubDisplay") );
isClubSetpointAdjust = true;
isRangeSetpointAdjust = false;
isAirgunSetpointAdjust = false;
Serial.println( F("ClubChange") );
lcd.clear();
lcd.print(" Setting Menu: ");
lcd.setCursor(0, 2);
lcd.print("Club: ");
lcd.print(club_temperature_setpoint, 1);
lcd.write((char)223);
lcd.print('C');
printRelayStateChanges();
Serial.println( F("exit ClubDisplay") );
}
//-------------------------------------------------------------------//
void AirgunDisplay() {
Serial.println( F("enter AirgunDisplay") );
isAirgunSetpointAdjust = true;
isRangeSetpointAdjust = false;
isClubSetpointAdjust = false;
Serial.println( F("AirgunChange") );
lcd.clear();
lcd.print(" Setting Menu: ");
lcd.setCursor(0, 3);
lcd.print("Airgun:");
lcd.print(airgun_temperature_setpoint, 1);
lcd.write((char)223);
lcd.print('C');
printRelayStateChanges();
Serial.println( F("exit AirgunDisplay") );
}
//------------------------Save Display-------------------------------//
void SaveDisplay() {
Serial.println( F("enter SaveDisplay") );
isRangeSetpointAdjust = false;
isClubSetpointAdjust = false;
isAirgunSetpointAdjust = false;
Serial.println( F("SavingChanges") );
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("To save the changes");
lcd.setCursor(2, 1);
lcd.print("Press Up & Down");
lcd.setCursor(5, 2);
lcd.print("Together");
isSetpointSave = true;
printRelayStateChanges();
Serial.println( F("exit SaveDisplay") );
}
//---------------------Temperature display - ------------------------//
void TemperatureDisplay() {
Serial.println( F("enter TemperatureDisplay") );
lcd.setCursor(0, 1); // Range Temperature
lcd.print("Range: ");
lcd.print(range_sensor.getTempCByIndex(0), 1);
lcd.write((char)223);
lcd.print('C');
lcd.setCursor(0, 2); // Club Temperature
lcd.print("Club: ");
lcd.print(club_sensor.getTempCByIndex(0), 1);
lcd.write((char)223);
lcd.print('C');
lcd.setCursor(0, 3); // Airgun Temperature
lcd.print("Airgun:");
lcd.print(airgun_sensor.getTempCByIndex(0), 1);
lcd.write((char)223);
lcd.print('C');
printRelayStateChanges();
Serial.println( F("exit TemperatureDisplay") );
}
//------------------------Heating Override---------------------------//
void HeatingOverride() {
Serial.println( F("enter HeatingOverride") );
Serial.println( F("Heating Override is On") );
Serial.println( F("LCD showing Override is On") );
isRangeHeatOn = true;
isClubHeatOn = true;
isAirgunHeatOn = true;
isTimeControlOn = false;
HeatingAvailable();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print( F(" OVERRIDE IS ON ") );
printRelayStateChanges();
Serial.println( F("exit HeatingOverride") );
}
//--------------------Heating Override Complete----------------------//
void HeatingOverrideComplete() {
Serial.println( F("enter HeatingOverrideComplete") );
Serial.println( F("Heating Override is complete") );
isHeatingOverride = false;
isRangeHeatOn = false;
isClubHeatOn = false;
isAirgunHeatOn = false;
isTimeControlOn = true;
lcd.setCursor(0, 0);
lcd.print( F(" OVERRIDE IS OFF ") );
delay(2000);
lcd.noBacklight();
Serial.println( F("exit HeatingOverrideComplete") );
}
//-----------------------Heating Available---------------------------//
void HeatingAvailable() {
Serial.println( F("enter HeatingAvailable") );
RangeHeatingAvailable();
ClubHeatingAvailable();
AirgunHeatingAvailable();
Serial.println( F("Heating is available") );
printRelayStateChanges();
Serial.println( F("exit HeatingAvailable") );
}
//-------------------------------------------------------------------//
void RangeHeatingAvailable() {
Serial.println( F("enter RangeHeatingAvailable") );
if (isRangeHeatOn) {
NormalHeatingRange();
Serial.println( F("Heating R") );
} else {
Serial.println( F("Frost Prev. R") );
FrostPreventionRange();
}
printRelayStateChanges();
Serial.println( F("exit RangeHeatingAvailable") );
}
//-------------------------------------------------------------------//
void ClubHeatingAvailable() {
Serial.println( F("enter ClubHeatingAvailable") );
if (isClubHeatOn) {
NormalHeatingClub();
Serial.println( F("Heating C") );
}
else {
Serial.println(F("Frost Prev. C") );
FrostPreventionClub();
}
printRelayStateChanges();
Serial.println( F("exit ClubHeatingAvailable") );
}
//-------------------------------------------------------------------//
void AirgunHeatingAvailable() {
Serial.println( F("enter AirgunHeatingAvailable") );
if (isAirgunHeatOn) {
NormalHeatingAirgun();
Serial.println( F("Heating A") );
}
else {
Serial.println( F("Frost Prev. A") );
FrostPreventionAirgun();
}
printRelayStateChanges();
Serial.println( F("exit AirgunHeatingAvailable") );
}
//-------------------Frost Prevention Range--------------------------//
void FrostPreventionRange() {
Serial.println( F("enter FrostPreventionRange") );
if ((range_sensor.getTempCByIndex(0) <= (frost_setpoint - deadzone))) {
digitalWrite(range_relay, HIGH);
Serial.println( F("Range frost Heating") );
lcd.setCursor(13, 1);
lcd.print( F(" ON F") );
}
else {
if ( (range_sensor.getTempCByIndex(0) >= (frost_setpoint + deadzone)) ) {
digitalWrite(range_relay, LOW);
Serial.println( F("01 range_sensor.getTempCByIndex(0) >= (frost_setpoint + deadzone") );
lcd.setCursor(13, 1);
lcd.print( F(" OFF F") );
}
}
printRelayStateChanges();
Serial.println( F("exit FrostPreventionRange") );
}
//--------------------Frost Prevention Club-------------------------//
void FrostPreventionClub() {
Serial.println( F("enter FrostPreventionClub") );
if ((club_sensor.getTempCByIndex(0) <= (frost_setpoint - deadzone))) {
digitalWrite(club_relay, HIGH);
Serial.println( F("02 Club frost Heating") );
lcd.setCursor(13, 2);
lcd.print( F(" ON F") );
}
else {
if ((club_sensor.getTempCByIndex(0) >= (frost_setpoint + deadzone))) {
digitalWrite(club_relay, LOW);
Serial.println( F("03 club_sensor.getTempCByIndex(0) >= (frost_setpoint + deadzone") );
lcd.setCursor(13, 2);
lcd.print(" OFF F");
}
}
printRelayStateChanges();
Serial.println( F("exit FrostPreventionClub") );
}
//---------------------Frost Prevention Airgun-----------------------//
void FrostPreventionAirgun() {
Serial.println( F("enter FrostPreventionAirgun") );
if ((airgun_sensor.getTempCByIndex(0) <= (frost_setpoint - deadzone))) {
digitalWrite(airgun_relay, HIGH);
Serial.println( F("Air frost Heating") );
lcd.setCursor(13, 3);
lcd.print(" ON F");
}
else {
if ((airgun_sensor.getTempCByIndex(0) >= (frost_setpoint + deadzone))) {
digitalWrite(airgun_relay, LOW);
Serial.println( F("04 airgun_sensor.getTempCByIndex(0) >= (frost_setpoint + deadzone") );
lcd.setCursor(13, 3);
lcd.print(" OFF F");
}
}
printRelayStateChanges();
Serial.println( F("exit FrostPreventionAirgun") );
}
//-------------------Normal Heating Range----------------------------//
void NormalHeatingRange() {
Serial.println( F("enter NormalHeatingRange") );
if ((range_sensor.getTempCByIndex(0) <= (range_temperature_setpoint - deadzone))) {
digitalWrite(range_relay, HIGH);
Serial.println( F("Normal Heating R") );
lcd.setCursor(13, 1);
lcd.print(F(" ON T") );
}
else {
if ((range_sensor.getTempCByIndex(0) >= (range_temperature_setpoint + deadzone))) {
digitalWrite(range_relay, LOW);
Serial.println( F("05 range_sensor.getTempCByIndex(0) >= (range_temperature_setpoint + deadzone") );
lcd.setCursor(13, 1);
lcd.print( F(" OFF T") );
}
}
printRelayStateChanges();
Serial.println( F("exit NormalHeatingRange") );
}
//--------------------Normal Heating Club ---------------------------//
void NormalHeatingClub() {
Serial.println( F("enter NormalHeatingClub") );
if ((club_sensor.getTempCByIndex(0) <= (club_temperature_setpoint - deadzone))) {
digitalWrite(club_relay, HIGH);
Serial.println( F("Normal Heating C") );
lcd.setCursor(13, 2);
lcd.print( F(" ON T") );
}
else {
if ((club_sensor.getTempCByIndex(0) >= (club_temperature_setpoint + deadzone))) {
digitalWrite(club_relay, LOW);
Serial.println( F("06 club_sensor.getTempCByIndex(0) >= (club_temperature_setpoint + deadzone") );
lcd.setCursor(13, 2);
lcd.print( F(" OFF T") );
}
}
printRelayStateChanges();
Serial.println( F("exit NormalHeatingClub") );
}
//---------------------Normal Heating Airgun-------------------------//
void NormalHeatingAirgun() {
Serial.println( F("enter NormalHeatingAirgun") );
if ((airgun_sensor.getTempCByIndex(0) <= (airgun_temperature_setpoint - deadzone))) {
digitalWrite(airgun_relay, HIGH);
Serial.println( F("Normal Heating A") );
lcd.setCursor(13, 3);
lcd.print( F(" ON T") );
}
else {
if ((airgun_sensor.getTempCByIndex(0) >= (airgun_temperature_setpoint + deadzone))) {
digitalWrite(airgun_relay, LOW);
Serial.println( F("07 airgun_sensor.getTempCByIndex(0) >= (airgun_temperature_setpoint + deadzone") );
lcd.setCursor(13, 3);
lcd.print( F(" OFF T") );
}
}
printRelayStateChanges();
Serial.println( F("exit NormalHeatingAirgun") );
}