Hi All
I am in the final throws of finishing my lock-down project of a spa controller to replace my basic time switch on or off.
The last major part of the project is an error checking to make sure the times, when the spa is at a comfort heat level, entered do not overlap or conflict.
Premise is that there is typedef that sets a structure to capture on, off and freq. Frequency being Everyday, Weekends, Weekdays, and off (not set). time is captured in bytes of hrs and mins. (I should note these are set by an admin user and should rarely be changed) There are 6 comfortTimes in an array to store them.
The hrs and min are converted to seconds past midnight as that was the east way I could think of to check if at any point in time the spa should be at comfort level or not (((hrs *60) + min) * 60). These are stored in two arrays, Comfort_on_times and comfort_off_times.
The code below works and tests out correctly but my questions is could I have done this a more betterer
way rather than nested for and if statement as i have done?. I tried making the function a bool to avoid another global variable but I couldn't get it to work so i made it a void and put bool "conflict" as a global.
One of the reasons I am asking is the overall spa program (attached but not completed) is running out of space so I may have to investigate progmem but don't know which things I should put into progmem (other than they should be static). Should I be putting all of my LCD display text (menu options and messages) in progmem and just calling it, will that help?
The full spa code reports as (before I add the error checking code)
"Sketch uses 17706 bytes (54%) of program storage space. Maximum is 32256 bytes.
Global variables use 1589 bytes (77%) of dynamic memory, leaving 459 bytes for local variables. Maximum is 2048 bytes....Low memory available, stability problems may occur."
Serial.prints are only for testing and will be removed
// structure to store comfort times
typedef struct {
byte On_hrs;
byte On_min;
byte Off_hrs;
byte Off_min;
byte Freq; // Weekdays, Weekends, Everyday
}__attribute__((packed)) Comfort;
// 0 = off
// 1 = Weekends
// 2 = weekdays
// 3 = everyday
Comfort comfortTimes[] =
{
// on off
// hr min hr min freq LCD display starts at comfort 1
{13, 30, 14, 30, 3}, // Comfort 0 On Everyday
{8, 0, 9, 0, 1}, // Comfort 1 On Weekends only
{8, 30, 10, 0, 2}, // Comfort 2 On Weekdays only
{19, 30, 22, 30, 1}, // Comfort 4 On weekends only
{18, 30, 21, 30, 2}, // Comfort 3 On Weekends only
{0, 00, 9, 30, 0}, // Comfort 5 not set
}; // array of 6 items
// convert the on and off times to seconds past midnight
// 0 1 2 3 4 5
unsigned long comfort_on_sec[6] = { 48600, 28800, 30600, 70200, 66600, 0};
unsigned long comfort_off_sec[6] = { 50400, 32400, 36000, 79200, 75600, 0};
bool conflict = false;
void CheckConflict()
{
byte i; //local variable for item to be tested
byte x; //local variable for item to be tested against
for(i = 0; i < 6; i++){ // cycle through the list 0 - 6
Serial.print("i=");
Serial.println(i);
if(comfort_on_sec[i] > comfort_off_sec[i]) // test the start time is before the end time
{
conflict = true; // if true no need to test further.
}
else if(conflict == false){ // continue testing
for (x = i+1 ; x < 6; x++ ) { // for loop with reducing tests per loop ie 1 against 2-5, 2 against 3-5
Serial.print ("x=");
Serial.println(x);
// test only freqof everyday or if freq is the same and is neither are set to off
if((comfortTimes[i].Freq == 3 || comfortTimes[i].Freq == comfortTimes[x].Freq) && comfortTimes[i].Freq != 0)
{
if((comfort_on_sec[i] > comfort_on_sec[x]) && (comfort_off_sec[x] < comfort_on_sec[i])){
conflict = false; // no conflict exists so move on to next number in for loop
}
else if((comfort_on_sec[i] < comfort_on_sec[x]) && (comfort_on_sec[x] > comfort_off_sec[i])){
conflict = false; // no conflict exists so move on to next number in for loop
}
else// if neither test is true return false and break for loop
{Serial.println("conflict exists");
conflict = true; // return true to the main for loop.
break; // break the sub [x] for loop as a conflict was found don't test any further
}
}//end if
} // end sub [x] for loop
} // end if conflict test
else break; // break the main [i] for loop as a conflict was found and conflict returned true
} // end main [i] for loop
if(conflict == true){
Serial.println("conflict exists");
}
else Serial.println("no conflict");
}// end function
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
CheckConflict();
Serial.println(conflict);
}
void loop() {
// put your main code here, to run repeatedly:
}
spa_controller_V6.ino (61.3 KB)