I have a Sketch that has the Setup() code continually looping. HW is UNO R3.
In Setup() there is some code then three possible calls to code to check if a particular button is pressed during Arduino powerup/reset.
They are:
CheckSetRTC();
CheckSetSlotButton();
CheckClearSlotButton();
Now here is the issue.
If I comment out these calls to CheckSetSlotButton() and CheckClearSlotButton() and compile the code I assume that the compiler realises that those two are not called in the program and creates a shorter set of instructions to load into the Arduino. The actual functions are still in the Sketch code.
If I Compile only with CheckSetRTC(); uncommented; I get:
Sketch uses 17642 bytes (54%) of program storage space
Global variables use 816 bytes (39%) of dynamic memory
The program loads and runs into Loop() OK
If I Compile with CheckSetRTC() and CheckSetSlotButton(); uncommented; I get:
Sketch uses 19270 bytes (59%) of program storage space
Global variables use 973 bytes (47%) of dynamic memory
The program loads and displays DJS Starting in Setup() and does not appear to go into Loop()
If I Compile with CheckSetRTC() and CheckSetSlotButton(); and CheckClearSlotButton();uncommented; I get:
Sketch uses 20390 bytes (63%) of program storage space
Global variables use 1069 bytes (52%) of dynamic memory
and the program loads and displays DJS Starting in Setup() over and over again.
It seems there is a issue related to how long the code is triggering a Arduino internal reset.
Any ideas on how to fix? Thanks
/**************************************************************************
RDF TX START STOP TIMER - Arduino UNO
**************************************************************************/
/* HARDWARE
Arduino UNO - ATMega328P Bare IC
Level Converter module - not currently used
RTC with EEPROM module
OLED Display
Relay module or MOSFET Power Switching Circuit
Switches
--------
Black Yellow White Yellow Green White Red
MENU DOWN ENTER UP CANCEL TX TEST RESET
D5 D6 D7 D8 D9 4 RST Capacitor
TIME
Time = Month * 1000000 + Day * 10000 + Hour * 100 + Minute
**************************************************************************/
//#include "Arduino.h"
#include "uRTCLib.h"
//#include <SPI.h>
//#include <Wire.h>
#include <uEEPROMLib.h>
// uEEPROMLib eeprom;
uEEPROMLib eeprom(0x57);
//For the larger 128x64 display
//SCL = On Nano A5 // On MEGA D21 // On UNO // On Bare ATMega328P
//SDA = On Nano A4 // On MEGA D20 // On UNO // On Bare ATMega328P
//#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
#define i2c_Address 0x3c //initialize with the I2C addr 0x3C Typically eBay OLED's
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // QT-PY / XIAO
Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// uRTCLib rtc;
//SCL = On Nano A5 // On MEGA D21 // On UNO // On Bare ATMega328P
//SDA = On Nano A4 // On MEGA D20 // On UNO // On Bare ATMega328P
uRTCLib rtc(0x68);
// I/O pins
// Need to add Analoge pins to test battery voltage
#define RDFTXBAT1VOLTS 0
#define RDFTXBAT2VOLTS 0
#define RDFTXPWRMOSFET1 14
#define RDFTXPWRRLY1_ON 10
#define RDFTXPWRRLY1_OFF 11
#define RDFTXPWRRLY2_ON 12
#define RDFTXPWRRLY2_OFF 13
#define SW_TX_TEST 4
#define SW_MENU 5
#define SW_DOWN 6
#define SW_ENTER 7
#define SW_UP 8
#define SW_CANCEL 9
#define DEBOUNCE_DELAY 100
// For UP DOWN switch counting
int Counter = 0; //use int so can detect -ve numbers if we dec 0
byte SetStep = 0;
byte CurrentSlot = 0;
bool ExitRTCSet = true;
bool ExitSLOTSet = true;
bool ExitSLOTSelect = true;
bool ExitSLOTClear = true;
#define YEAR_INDEX 0
#define MONTH_INDEX 1
#define DAY_INDEX 2
#define DoW_INDEX 3
#define HOUR_INDEX 4
#define MINUTE_INDEX 5
#define SAVE_INDEX 6
#define QUIT_INDEX 7
#define SLOT_ON_MONTH_INDEX = 0
#define SLOT_ON_DAY_INDEX = 1
#define SLOT_ON_HOUR_INDEX = 2
#define SLOT_ON_MIN_INDEX = 3
#define SLOT_OFF_MONTH_INDEX = 4
#define SLOT_OFF_DAY_INDEX = 5
#define SLOT_OFF_HOUR_INDEX = 6
#define SLOT_OFF_MIN_INDEX = 7
#define SLOT_SAVE_INDEX 8
// 0 1 2 3 4 5
// Y M D DoW h m
byte RTCNewValues[] = { 24, 1, 1, 0, 0, 0 };
byte SetRTCMax[] = { 40, 12, 31, 6, 23, 59 }; // For rollover detect
byte SetRTCMin[] = { 24, 1, 1, 0, 0, 0 }; // For rollover min
byte SetSLOTMin[] = { 1, 1, 0, 0, 1, 1, 0, 0 };
byte SetSLOTMax[] = { 12, 31, 23, 59, 12, 31, 23, 59 }; // One dat the day per Feb code will get changed in SW based on Month selected
byte MonthDayMax[] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
byte SLOTNewValues[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; // Used to hold the slot values entered by user before commiting values to the EEPROM
byte OnOffProg[] = { 1, 2, 4, 5, 1, 2, 4, 5 };
char buffer[11];
const char DoW_0[] PROGMEM = "SUN"; // We store DoW strings here
const char DoW_1[] PROGMEM = "MON";
const char DoW_2[] PROGMEM = "TUE";
const char DoW_3[] PROGMEM = "WED";
const char DoW_4[] PROGMEM = "THUR";
const char DoW_5[] PROGMEM = "FRI";
const char DoW_6[] PROGMEM = "SAT";
const char* const DoWs[] PROGMEM = { DoW_0, DoW_1, DoW_2, DoW_3, DoW_4, DoW_5, DoW_6 };
const char SetBanner_0[] PROGMEM = "YEAR"; // We store Setting display Banner strings here
const char SetBanner_1[] PROGMEM = "MONTH";
const char SetBanner_2[] PROGMEM = "DAY";
const char SetBanner_3[] PROGMEM = "DofW";
const char SetBanner_4[] PROGMEM = "HOUR";
const char SetBanner_5[] PROGMEM = "MIN";
const char SetBanner_6[] PROGMEM = "SAVE = UP";
const char SetBanner_7[] PROGMEM = "QUIT";
const char* const SetBanners[] PROGMEM = { SetBanner_0, SetBanner_1, SetBanner_2, SetBanner_3, SetBanner_4, SetBanner_5, SetBanner_6, SetBanner_7 };
const char S_OFF_0[] PROGMEM = "S0 OFF"; // We store RDF OFF setting Banner strings here
const char S_OFF_1[] PROGMEM = "S1 OFF";
const char S_OFF_2[] PROGMEM = "S2 OFF";
const char* const RDFOffBanners[] PROGMEM = { S_OFF_0, S_OFF_1, S_OFF_2 };
const char S_ON_0[] PROGMEM = "S0 ON"; // We store RDF ON setting Banner strings here
const char S_ON_1[] PROGMEM = "S1 ON";
const char S_ON_2[] PROGMEM = "S2 ON";
const char* const RDFOnBanners[] PROGMEM = { S_ON_0, S_ON_1, S_ON_2 };
const char SlotBanner_0[] PROGMEM = "SLOT 0"; // We store RDF ON setting Banner strings here
const char SlotBanner_1[] PROGMEM = "SLOT 1";
const char SlotBanner_2[] PROGMEM = "SLOT 2";
const char* const SlotBanners[] PROGMEM = { SlotBanner_0, SlotBanner_1, SlotBanner_2 };
// EEPROM location defintions
#define EEP_ON_MONTH 0
#define EEP_ON_DAY 1
#define EEP_ON_HOUR 2
#define EEP_ON_MIN 3
#define EEP_OFF_MONTH 4
#define EEP_OFF_DAY 5
#define EEP_OFF_HOUR 6
#define EEP_OFF_MIN 7
#define EEP_SLOT0 0x00
#define EEP_SLOT1 0x10
#define EEP_SLOT2 0x20
// To convert clock MM/DD hh:mm to a number for easy value comparison to start/stop RDF TX
// Ingnore the Year as RDF TX will not occur over New Year period
unsigned long RTC_TimeVal;
// To convert Slot0 MM/DD hh:mm to a number for easy value comparison to start/stopRDF TX
unsigned long on_Time0;
unsigned long off_Time0;
bool Tx = false;
void setup() {
bool ExitRTCSet = true;
bool ExitSLOTSet = true;
byte SetStep = 0;
Serial.begin(9600);
delay(1000); // wait for console opening
Serial.println("DJS Starting");
delay(500);
//Configure the RTC
rtc.disable32KOut(); //Do not need this signal in the RDF TX Power Control
// Pin for controlling the power to the RDF TX unit set as output
pinMode(RDFTXPWRMOSFET1, OUTPUT);
// Pins for input switches
pinMode(SW_TX_TEST, INPUT_PULLUP);
pinMode(SW_UP, INPUT_PULLUP);
pinMode(SW_DOWN, INPUT_PULLUP);
pinMode(SW_ENTER, INPUT_PULLUP);
pinMode(SW_MENU, INPUT_PULLUP);
pinMode(SW_CANCEL, INPUT_PULLUP);
URTCLIB_WIRE.begin();
//For the 128x64 OLED display
display.begin(i2c_Address, true); // Address 0x3C default
// Clear the buffer.
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SH110X_WHITE);
//As a boot screen display the current Date and Time
display.setCursor(0, 0);
display.println("RDF TX ON/OFF TIMER");
display.println(" DJS 2024");
display.println(" ");
display.println("Current RTC is");
display.println("Date");
displayDate(true);
display.println("Time");
displayTime(true);
display.display();
delay(500);
// Run the following line during development to pre-load the RTC with current date and time
// rtc.set(second, minute, hour, dayOfWeek, dayOfMonth, month, year)
//rtc.set(0, 50, 17, 5, 4, 7, 24);
CheckSetRTC();
CheckSetSlotsButton();
CheckClearSlotsButton();
} //Setup End
void loop() {
// Display current Date Time
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
displayDate(false);
display.println(" TX");
displayTime(true);
for (int i = 0; i <= 2; i++) {
display.print("S0 ON :");
if (eeprom.eeprom_read(EEP_ON_DAY + (0x10 * i)) == 0 && eeprom.eeprom_read(EEP_ON_MONTH + (0x10 * i)) == 0 && eeprom.eeprom_read(EEP_ON_HOUR + (0x10 * i)) == 0 && eeprom.eeprom_read(EEP_ON_MIN + (0x10 * i)) == 0) {
display.println(" - NOT SET");
} else {
displayZeroPaddedEEPROMData(EEP_ON_DAY + (0x10 * i), false);
display.print("/");
displayZeroPaddedEEPROMData(EEP_ON_MONTH + (0x10 * i), false);
display.print(" ");
displayZeroPaddedEEPROMData(EEP_ON_HOUR + (0x10 * i), false);
display.print(":");
displayZeroPaddedEEPROMData(EEP_ON_MIN + (0x10 * i), false);
display.print(" ");
if (IsSlotON(i)) {
display.println("ON"); //need to calc this
} else {
display.println("");
}
}
display.print("S0 OFF:");
if (eeprom.eeprom_read(EEP_OFF_DAY + (0x10 * i)) == 0 && eeprom.eeprom_read(EEP_OFF_MONTH + (0x10 * i)) == 0 && eeprom.eeprom_read(EEP_OFF_HOUR + (0x10 * i)) == 0 && eeprom.eeprom_read(EEP_OFF_MIN + (0x10 * i)) == 0) {
display.println(" - NOT SET");
} else {
displayZeroPaddedEEPROMData(EEP_OFF_DAY + (0x10 * i), false);
display.print("/");
displayZeroPaddedEEPROMData(EEP_OFF_MONTH + (0x10 * i), false);
display.print(" ");
displayZeroPaddedEEPROMData(EEP_OFF_HOUR + (0x10 * i), false);
display.print(":");
displayZeroPaddedEEPROMData(EEP_OFF_MIN + (0x10 * i), false);
display.println("");
}
}
display.display();
// TBD - If building the Dual Battery Relay Switched version will need to check which Battery we will connect to the RDF TX
if (IsSlotON(0) || IsSlotON(1) || IsSlotON(2)) {
// TURN ON THE TX POWER RELAY
digitalWrite(RDFTXPWRMOSFET1, HIGH);
} else {
// TURN OFF THE TX POWER RELAY
digitalWrite(RDFTXPWRMOSFET1, LOW);
}
//delay(500);
} // End Loop
//*********************************************************
// ____ _ _____ _ ____ ____ _ ___ _____ ____
// / ___| | | ____| / \ | _ \ / ___|| | / _ \_ _/ ___|
// | | | | | _| / _ \ | |_) | \___ \| | | | | || | \___ \
// | |___| |___| |___ / ___ \| _ < ___) | |__| |_| || | ___) |
// \____|_____|_____/_/ \_\_| \_\ |____/|_____\___/ |_| |____/
//
//*********************************************************
void CheckClearSlotsButton(void) {
if (digitalRead(SW_UP) == LOW) { // As the SW_UP was held down during power up, we do the SLOT clearing.
Serial.println("Entering SLOT Clearing Menu");
delay(DEBOUNCE_DELAY);
while (digitalRead(SW_UP) == LOW) {} //Wait for SW_UP to be released
ExitSLOTClear = false;
ExitSLOTSelect = false;
SetStep = 0;
CurrentSlot = 0;
while (ExitSLOTClear == false) {
while (ExitSLOTSelect == false) {
// Display the three slot options with a selection pointer
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2); // Display the top line banner for what we are doing
display.println("CLEAR SLOT");
displayCursor(0);
strcpy_P(buffer, (char*)pgm_read_word(&(SlotBanners[0])));
display.println(buffer);
displayCursor(1);
strcpy_P(buffer, (char*)pgm_read_word(&(SlotBanners[1])));
display.println(buffer);
displayCursor(2);
strcpy_P(buffer, (char*)pgm_read_word(&(SlotBanners[2])));
display.println(buffer);
display.display();
if (digitalRead(SW_UP) == LOW) {
delay(DEBOUNCE_DELAY);
CurrentSlot++;
if (CurrentSlot == 3) {
CurrentSlot = 0;
}
}
if (digitalRead(SW_DOWN) == LOW) {
delay(DEBOUNCE_DELAY);
CurrentSlot--;
if (CurrentSlot == 255) {
CurrentSlot = 2;
}
}
if (digitalRead(SW_ENTER) == LOW) { //The selected slot is remebered by global CurrentSlot
delay(DEBOUNCE_DELAY);
while (digitalRead(SW_ENTER) == LOW) {} //Wait for SW_ENTER to be released
ExitSLOTSelect = true;
}
if (digitalRead(SW_CANCEL) == LOW) { //Get out of SLOT clearing
delay(DEBOUNCE_DELAY);
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2);
display.println("QUITING");
display.println("SLOTS");
display.println("CLEAR");
display.display();
delay(2000);
ExitSLOTSelect = true;
ExitSLOTClear = true;
}
} //End while(ExitSLOTSelect)
// Having selected a SLOT (CurrentSlot) we now confirm with user to clear the Start End Date/Times
display.clearDisplay();
display.setCursor(0, 0);
display.println("CLEARING");
strcpy_P(buffer, (char*)pgm_read_word(&(SlotBanners[CurrentSlot])));
display.println(buffer);
display.println("ENTER or");
display.println("EXIT");
// Refresh the display with the new information
display.display();
// Check Enter for next step
if (digitalRead(SW_ENTER) == LOW) {
delay(DEBOUNCE_DELAY);
while (digitalRead(SW_ENTER) == LOW) {} //Wait for SW_ENTER to be released
//Clear SLOT data in EEPROM
for (int i = 0; i <= 7; i++) {
// eeprom.eeprom_write(addr, data)
if (!eeprom.eeprom_write(i + (0x10 * CurrentSlot), 0)) {
Serial.println("EEPROM Write Failed");
}
}
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2);
display.println("SLOT DATA");
display.println("CLEARED");
display.display();
delay(3000);
ExitSLOTClear = true;
}
if (digitalRead(SW_CANCEL) == LOW) {
delay(DEBOUNCE_DELAY);
ExitSLOTClear = true;
}
} // End while(ExitSLOTClear == false)
if (digitalRead(SW_CANCEL) == LOW) {
delay(DEBOUNCE_DELAY);
ExitSLOTClear = true;
}
} // End (digitalRead(SW_UP) == LOW)
}
//*********************************************************
// ____ _____ _____ ____ _ ___ _____ ____
// / ___|| ____|_ _| / ___|| | / _ \_ _/ ___|
// \___ \| _| | | \___ \| | | | | || | \___ \
// ___) | |___ | | ___) | |__| |_| || | ___) |
// |____/|_____| |_| |____/|_____\___/ |_| |____/
//
//*********************************************************
void CheckSetSlotsButton(void) {
// There ar three possible Slots to store Start and End RDF TX times. Slot_0 to Slot_2
// Will assume a RDF TX will not go through midnight as we need to get some sleep.
// So basically an RDF TX will start and stop on the same day.
// Slot times should not overlap
if (digitalRead(SW_DOWN) == LOW) { // As the SW_DOWN was held down during power up, we do the SLOT Date/Time setting.
Serial.println("Entering SLOT Date/Time Setting Menu");
delay(DEBOUNCE_DELAY);
while (digitalRead(SW_DOWN) == LOW) {} //Wait for SW_DOWN to be released
ExitSLOTSet = false;
ExitSLOTSelect = false;
SetStep = 0;
CurrentSlot = 0;
SLOTNewValues[SetStep] = SetSLOTMin[SetStep]; // eg 1 for the Set MONTH
//or
//Preload the new values with current RTC values. Saves on button presses when setting Date / Time
rtc.refresh();
SLOTNewValues[0] = rtc.month();
SLOTNewValues[1] = rtc.day();
SLOTNewValues[2] = rtc.hour();
while (ExitSLOTSet == false) {
while (ExitSLOTSelect == false) {
// Display the four slot options with a selection pointer
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2); // Display the top line banner for what we are setting
display.println("SET SLOT");
displayCursor(0);
strcpy_P(buffer, (char*)pgm_read_word(&(SlotBanners[0])));
display.println(buffer);
displayCursor(1);
strcpy_P(buffer, (char*)pgm_read_word(&(SlotBanners[1])));
display.println(buffer);
displayCursor(2);
strcpy_P(buffer, (char*)pgm_read_word(&(SlotBanners[2])));
display.println(buffer);
display.display();
if (digitalRead(SW_UP) == LOW) {
delay(DEBOUNCE_DELAY);
CurrentSlot++;
if (CurrentSlot == 3) {
CurrentSlot = 0;
}
}
if (digitalRead(SW_DOWN) == LOW) {
delay(DEBOUNCE_DELAY);
CurrentSlot--;
if (CurrentSlot == 255) {
CurrentSlot = 2;
}
}
if (digitalRead(SW_ENTER) == LOW) {
delay(DEBOUNCE_DELAY);
while (digitalRead(SW_ENTER) == LOW) {} //Wait for SW_ENTER to be released
ExitSLOTSelect = true;
}
if (digitalRead(SW_CANCEL) == LOW) { //Get out of SLOT setting
delay(DEBOUNCE_DELAY);
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2);
display.println("QUITING");
display.println("SLOTS");
display.println("NO");
display.println("SAVE");
display.display();
delay(2000);
ExitSLOTSelect = true;
ExitSLOTSet = true;
}
}
// Having selected a SLOT (CurrentSlot) we now load the Start End Date/Times
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2); // Display the top line banner for what we are setting
if (SetStep <= 3) {
strcpy_P(buffer, (char*)pgm_read_word(&(RDFOnBanners[CurrentSlot])));
} else {
strcpy_P(buffer, (char*)pgm_read_word(&(RDFOffBanners[CurrentSlot])));
}
display.println(buffer);
strcpy_P(buffer, (char*)pgm_read_word(&(SetBanners[OnOffProg[SetStep]])));
display.println(buffer);
// Display the data Value for this setting
if (SetStep < SLOT_SAVE_INDEX) {
display.setTextSize(4);
display.println(SLOTNewValues[SetStep]);
}
// Save window goes here
if (SetStep == SLOT_SAVE_INDEX) {
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2);
display.println(" ENTER To");
display.println(" Save");
display.print(" SLOT ");
display.println(CurrentSlot);
display.println("or QUIT");
}
// Refresh the display with the new information
display.display();
//Check the UP and DOWN buttons for Value Counter
if (digitalRead(SW_UP) == LOW) {
delay(DEBOUNCE_DELAY);
while (digitalRead(SW_UP) == LOW) {} //Wait for SW_UP to be released
SLOTNewValues[SetStep]++;
if (SLOTNewValues[SetStep] > SetSLOTMax[SetStep]) {
SLOTNewValues[SetStep] = SetSLOTMin[SetStep];
}
}
if (digitalRead(SW_DOWN) == LOW) {
delay(DEBOUNCE_DELAY);
while (digitalRead(SW_DOWN) == LOW) {} //Wait for SW_DOWN to be released
SLOTNewValues[SetStep]--;
if (SLOTNewValues[SetStep] > SetSLOTMax[SetStep]) { // Byte 0 decrement rollover to 255
SLOTNewValues[SetStep] = SetSLOTMax[SetStep];
}
if (SLOTNewValues[SetStep] < SetSLOTMin[SetStep]) {
SLOTNewValues[SetStep] = SetSLOTMax[SetStep];
}
}
// Check Enter for next step
if (digitalRead(SW_ENTER) == LOW) {
delay(DEBOUNCE_DELAY);
while (digitalRead(SW_ENTER) == LOW) {} //Wait for SW_ENTER to be released
//will need to check if we can copy previous entry as start point or are we at the last step
switch (SetStep) {
case 0: //Moving from Month ON to Day ON
SetStep++;
//SLOTNewValues[SetStep] = SetSLOTMin[SetStep]; //as have moved to new data location update initial data
break;
case 1: //Moving from Day ON to Hour ON
SetStep++;
//SLOTNewValues[SetStep] = SetSLOTMin[SetStep]; //as have moved to new data location update initial data
break;
case 2: //Moving from Hour ON to Minute ON
SetStep++;
SLOTNewValues[SetStep] = SetSLOTMin[SetStep]; //as have moved to new data location update initial data
break;
case 3: //Moving from Minute ON to Month OFF, so copy Month ON as a start value
SetStep++;
SLOTNewValues[SetStep] = SLOTNewValues[SetStep - 4]; //as have moved to new data location update initial data
break;
case 4: //Moving from Month OFF to Day OFF, so copy Day ON as a start value
SetStep++;
SLOTNewValues[SetStep] = SLOTNewValues[SetStep - 4]; //as have moved to new data location update initial data
break;
case 5: //Moving from Day off to Hour OFF, so copy Hour ON as a start value
SetStep++;
SLOTNewValues[SetStep] = SLOTNewValues[SetStep - 4]; //as have moved to new data location update initial data
break;
case 6: //Moving from Hour OFF to Minute OFF, so copy Minute ON as a start value
SetStep++;
SLOTNewValues[SetStep] = SLOTNewValues[SetStep - 4]; //as have moved to new data location update initial data
break;
case 7: //Moving from Minute OFF to SAVE message. Do not copy any data
SetStep++;
break;
case 8: //Moving from SAVE message to do SAVE. Copy data to EEPROM
//save data to EEPROM
for (int i = 0; i <= 7; i++) {
// eeprom.eeprom_write(addr, data)
if (!eeprom.eeprom_write(i + (0x10 * CurrentSlot), SLOTNewValues[i])) {
//Serial.println("EEPROM Write Failed");
}
}
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2);
display.println("SLOT DATA");
display.println("SAVED");
display.display();
delay(3000);
ExitSLOTSet = true;
break;
default:
// Nothing to see here
break;
}
}
if (digitalRead(SW_CANCEL) == LOW) {
delay(DEBOUNCE_DELAY);
ExitSLOTSet = true;
}
}
} // End (digitalRead(SW_DOWN) == LOW)
}
//*********************************************************
// ____ _____ _____ ____ _____ ____
// / ___|| ____|_ _| | _ \_ _/ ___|
// \___ \| _| | | | |_) || || |
// ___) | |___ | | | _ < | || |___
// |____/|_____| |_| |_| \_\|_| \____|
//
//*********************************************************
void CheckSetRTC(void) {
//To fully set the RTC the user needs to input all Y,M,D,DoW,h,m. The seconds will be set to 00 on save
//To enable time setting the SW_MENU must be held during power up
//Month, Day, DayofWeek, Hours and Minutes will roll over.
//A press on SW_CANCEL will exit and does NOT store the entered values into the RTC
//The buttons are:
// MENU DOWN ENTER UP CANCEL
// To save the entered data into the RTC:
// Enter required value with the UP and DOWN buttons
// Press ENTER
// Display will move to the next RTC item - repeat above
// When on the Save RTC display - Pressing UP will save the data into the RTC
// When on the Save RTC display - Pressing CANCEL will exit not saving the data into the RTC
if (digitalRead(SW_MENU) == LOW) { // As the SW_MENU was held down during power up, we do the RTC Date/Time setting.
Serial.println("Entering RTC Setting Menu");
ExitRTCSet = false;
SetStep = 0;
Counter = SetRTCMin[SetStep]; // eg 24 for the Set YEAR
delay(DEBOUNCE_DELAY);
while (digitalRead(SW_MENU) == LOW) {} //wait for button release
while (ExitRTCSet == false) {
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2); // Display the top line banner for what we are setting
strcpy_P(buffer, (char*)pgm_read_word(&(SetBanners[SetStep])));
display.println(buffer);
if (SetStep <= MINUTE_INDEX && SetStep != DoW_INDEX) { // Show the data as a number
display.setTextSize(5);
display.println(RTCNewValues[SetStep]);
}
if (SetStep == DoW_INDEX) { // Show the data as text
display.setTextSize(5);
strcpy_P(buffer, (char*)pgm_read_word(&(DoWs[Counter])));
display.println(buffer);
//Serial.println(buffer);
}
if (SetStep == SAVE_INDEX) { // Show the data that will be stored in the RTC
if (RTCNewValues[DAY_INDEX] <= 9) { display.print("0"); }
display.print(RTCNewValues[DAY_INDEX]);
display.print("/");
if (RTCNewValues[MONTH_INDEX] <= 9) { display.print("0"); }
display.print(RTCNewValues[MONTH_INDEX]);
display.print("/");
display.println(RTCNewValues[YEAR_INDEX]);
display.print(" ");
strcpy_P(buffer, (char*)pgm_read_word(&(DoWs[RTCNewValues[DoW_INDEX]])));
display.println(buffer);
if (RTCNewValues[HOUR_INDEX] <= 9) { display.print("0"); }
display.print(RTCNewValues[HOUR_INDEX]);
display.print(":");
if (RTCNewValues[MINUTE_INDEX] <= 9) { display.print("0"); }
display.print(RTCNewValues[MINUTE_INDEX]);
display.print(":");
display.println("00");
display.display();
while (1) {
if (digitalRead(SW_UP) == LOW) {
delay(DEBOUNCE_DELAY);
while (digitalRead(SW_UP) == LOW) { //wait for button release
//Serial.println("Waiting for SW_UP release");
}
//save the data to RTC
//rtc.set(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
Serial.println("Saving RTC");
rtc.set(0, RTCNewValues[MINUTE_INDEX], RTCNewValues[HOUR_INDEX], RTCNewValues[DoW_INDEX], RTCNewValues[DAY_INDEX], RTCNewValues[MONTH_INDEX], RTCNewValues[YEAR_INDEX]);
ExitRTCSet = true;
break;
}
if (digitalRead(SW_CANCEL) == LOW) {
delay(DEBOUNCE_DELAY);
//Serial.println("QUIT - No RTC Save");
//Do not save into RTC
ExitRTCSet = true;
break;
}
}
}
display.display();
//delay(100);
//Check the UP and DOWN buttons
if (digitalRead(SW_UP) == LOW) {
delay(DEBOUNCE_DELAY);
Counter++;
if (Counter > SetRTCMax[SetStep]) {
Counter = SetRTCMin[SetStep];
}
}
if (digitalRead(SW_DOWN) == LOW) {
delay(DEBOUNCE_DELAY);
Counter--;
if (Counter < SetRTCMin[SetStep]) {
Counter = SetRTCMax[SetStep];
}
}
RTCNewValues[SetStep] = Counter;
//Serial.print("Counter: ");
//Serial.println(Counter);
if (digitalRead(SW_ENTER) == LOW) {
delay(DEBOUNCE_DELAY);
while (digitalRead(SW_ENTER) == LOW) {
}
SetStep++;
if (SetStep >= 8) {
SetStep = QUIT_INDEX;
}
if (SetStep < SAVE_INDEX) {
Counter = SetRTCMin[SetStep]; // have moved to a new setting option so load the Min value
}
if (SetStep == QUIT_INDEX) {
// DO NOT Save the RTC temp data to the RTC
// Clear the RTC temp data
}
if (SetStep >= 8) {
SetStep = QUIT_INDEX;
}
}
if (digitalRead(SW_CANCEL) == LOW) {
delay(DEBOUNCE_DELAY);
//Need to cancel any RTC changes
ExitRTCSet = true;
}
}
} //End digitalRead(SW_MENU) == LOW)
}
//* CALC LONG TIME ***********************************
unsigned long CalcLongTime(byte Month, byte Day, byte Hour, byte Minute) {
return Month * 1000000 + Day * 10000 + Hour * 100 + Minute;
}
//* IS SLOT ON ***********************************
bool IsSlotON(byte Slot) {
rtc.refresh();
if (CalcLongTime(rtc.month(), rtc.day(), rtc.hour(), rtc.minute())
>= CalcLongTime(eeprom.eeprom_read(EEP_ON_MONTH + (0x10 * Slot)), eeprom.eeprom_read(EEP_ON_DAY + (0x10 * Slot)), eeprom.eeprom_read(EEP_ON_HOUR + (0x10 * Slot)), eeprom.eeprom_read(EEP_ON_MIN + (0x10 * Slot)))
&& CalcLongTime(rtc.month(), rtc.day(), rtc.hour(), rtc.minute())
< CalcLongTime(eeprom.eeprom_read(EEP_OFF_MONTH + (0x10 * Slot)), eeprom.eeprom_read(EEP_OFF_DAY + (0x10 * Slot)), eeprom.eeprom_read(EEP_OFF_HOUR + (0x10 * Slot)), eeprom.eeprom_read(EEP_OFF_MIN + (0x10 * Slot)))) {
return true;
} else {
return false;
}
}
//* DISPLAY ZERO PADDED EEPROM DATA ***********************************
void displayZeroPaddedEEPROMData(unsigned int EEP_Address, bool DoCR) {
if (eeprom.eeprom_read(EEP_Address) <= 9) {
display.print("0");
}
display.print(eeprom.eeprom_read(EEP_Address));
if (DoCR == true) {
display.println("");
}
}
//* DISPLAY CURSOR ***********************************
void displayCursor(byte row) { //uses the global CurrentSlot
if (CurrentSlot == row) {
display.print("> ");
} else {
display.print(" ");
}
}
//* DISPLAY DATE ***********************************
void displayDate(bool DoLF) {
rtc.refresh();
if (rtc.day() <= 9) {
display.print("0");
}
display.print(rtc.day());
display.print("/");
if (rtc.month() <= 9) {
display.print("0");
}
display.print(rtc.month());
display.print("/");
if (rtc.year() <= 9) {
display.print("0");
}
display.print(rtc.year());
if (DoLF == true) {
display.println("");
}
}
//* DISPLAY TIME ***********************************
void displayTime(bool DoLF) {
rtc.refresh();
if (rtc.hour() <= 9) {
display.print("0");
}
display.print(rtc.hour());
display.print(":");
if (rtc.minute() <= 9) {
display.print("0");
}
display.print(rtc.minute());
display.print(":");
if (rtc.second() <= 9) {
display.print("0");
}
display.print(rtc.second());
if (DoLF == true) {
display.println("");
}
}