Evening all, I am at the next stage of my central heating control project and I am now trying to incorporate four buttons to be able to change some of the temperature parameters. However before getting way too complicated I am trying to set up a single button to provide simple function of printing to the LCD and serial print.
I have decided not to use a debounce library and have follwed the online advice from UKHeliBob.
I am sure that I have mistyped or not completely understand his very good article.
Here is the code that I am working on. There are several items in the global area that refer to more of the project.
Any thoughts or suggestions would be most appreciated.
/* Author : John Marchant G0RJM
Created : 25/01/2024 - 19/06/2024
Description : A project to display the current date, time and temperature on the 20x4 LCD screen
and create a thermostatic heating control of three zones to include frost protection.
This has been based on the RTClib ds3231 example along with many parts borrowed
from several other files/sketches and in collaboration with several authors from the
Arduino Forum in particular alto777, blh64, StefanL38 and UKHeliBob. */
#include "RTClib.h"
#include <OneWire.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DST_RTC.h>
#include <DallasTemperature.h>
#include <EEPROM.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 = 10; // Relay outputs
const byte club_relay = 11;
const byte airgun_relay = 12;
float range_temperature;
float club_temperature;
float airgun_temperature;
const float range_temperature_setpoint = 24.0; // C
const float club_temperature_setpoint = 24.0; // C
const float airgun_temperature_setpoint = 24.0; // C
const float frost_setpoint = 24.0; // C
const float deadzone = 1.0; // C
const byte leftbutton = 6;
const int upbutton = 7;
const int downbutton = 8;
const int rightbutton = 9;
const int ledPin = 13;
const unsigned printInterval = 3000;
const unsigned backlightOnTime = 10000;
const unsigned menuOnTime = 20000;
int buttonState = 0;
int lastButtonState = 0; // the previous reading from the input pin
int buttonPushCounter = 0; // counter for the number of button presses
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 50; // the debounce time; increase if the output flickers
unsigned long startMillis = 0;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long previousMillisBacklight = 0;
unsigned long previousMillisMenu = 0;
unsigned long periodStartMillis = 0;
const unsigned long period = 5000;
byte currentButtonState;
byte previousButtonState;
int count = 0;
boolean printFinalMessage = true;
unsigned long debounceStartMillis;
unsigned long debouncePeriod = 20;
boolean debouncing = false;
bool backlightOn = false;
bool menuOn = false;
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 = 16 * 60UL + 00; // 16:00
const int Off_Normal = 21 * 60UL + 30; // 21:30
const int On_Sunday = 12 * 60UL + 00; // 12:00 for Sundays
const int Off_Sunday = 17 * 60UL + 30; // 17:30 for Sundays
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(leftbutton, INPUT_PULLUP);
pinMode(upbutton, INPUT_PULLUP);
pinMode(downbutton, INPUT_PULLUP);
pinMode(rightbutton, INPUT_PULLUP);
Serial.begin(9600);
startMillis = millis();
Wire.begin();
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(1000);
lcd.clear();
if (rtc.lostPower()) {
Serial.println("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("G0RJM Three zone Temperature Control");
range_sensor.begin();
club_sensor.begin();
airgun_sensor.begin();
pinMode(ledPin, OUTPUT);
} // End of setup
void loop() {
//----------------------------Button control-----------------------//
currentMillis = millis();
if (currentMillis - periodStartMillis <= period) //true until the period elapses
{
previousButtonState = currentButtonState; //save the previous button state
currentButtonState = digitalRead(leftbutton); //read the current state of the input
if (currentButtonState != previousButtonState) //if the button state has changed
{
debounceStartMillis = currentMillis; //save the time that the state change occured
debouncing = true; //flag that debouncing in progress
} //end state change check
if (currentMillis - debounceStartMillis >= debouncePeriod) //if the debounce period has elapsed
{
if (debouncing == true) //debouncing taking place
{
if (currentButtonState == LOW) //if the button is currently pressed
{
debouncing = false; //debouncing is finished
digitalWrite(ledPin, HIGH);
Serial.println("ON");
lcd.setCursor(0, 2);
lcd.print(" ON ");
} else {
// if the current state is HIGH then the button went from on to off:
digitalWrite(ledPin, HIGH);
Serial.println("Off");
lcd.setCursor(0, 2);
lcd.print(" OFF ");
}
}
}
}
}