Hi,
I'm using Arduino Mega to keep temperature and RH within a range in two consequent 4 hour windows (8 hours in total). This is a standard procedure and I need it running for a week in each test. So to make sure there will be no memory issues, I reset the arduino using watchdog timer. The first 4 hour cycle is working at 60 degree C without controlling RH (but with UV light exposure) and the second cycle is 4 hour cycle is working at 50 degree C and RH at 65%. The second cycle is a bit complicated and I am not sure how I can keep the arduino active even if the conditions are met during the cycle. I tried to use delay and use "if" command as much as possible to avoid freezing. But I ended up seeing the code stopping when the ideal conditions are reached. I appreciate any help in solving this problem.
//The following libaries are required for the operation of the chamber
#include <Arduino.h>
#include <Wire.h>
#include "Adafruit_SHT31.h"
#include <LiquidCrystal.h>
//Variable required for testing the Multiplexer
#define TCAADDR 0x70 //serial address of the TCA9458A Multiplexer
#include <avr/wdt.h>
//Temperature Sensor setup
bool enableHeater = false;
//Initialize the SHT31 sensor(s) *NOTE THAT IT MIGHT BE THE CASE THAT ONLY ONE INSTANCE NEED BE INITIALIZED*
Adafruit_SHT31 sht31_1 = Adafruit_SHT31();
Adafruit_SHT31 sht31_2 = Adafruit_SHT31();
Adafruit_SHT31 sht31_3 = Adafruit_SHT31();
//Adafruit_SHT31 sht31_4 = Adafruit_SHT31();
//define relay pins (these values are not changeable unless the requisite change has been made on the arduino board)
const byte Safety_Lights_Relay = 22; // Relay I : https://www.mcmaster.com/8262T14/ ; Safety Lights: Some 12VDC lights
const byte Heat_Mist = 26; // Relay J : https://www.omega.ca/en/control-monitoring/relays/solid-state-relays/ssrl240-660/p/SSRL240DC25 ; Components (a heating pad and a solenoid valve): https://www.omega.ca/en/industrial-heaters/surface-heaters/flexible-heaters/srfra-srfga/p/SRFGA-508-10-P & https://www.mcmaster.com/4738K147/
const byte Chamber_Fan_Relay1 = 24; // Relay G : https://www.mcmaster.com/8262T14/ ; Fan: https://www.digikey.ca/en/products/detail/qualtek/FAA1-08025NBMT31/2599974
const byte Humidifier_Fan_Relay = 25; // Relay K : https://www.mcmaster.com/8262T14/ ; Fan: a 24 VDC fan
const byte Humidifier_Relay = 23; // Relay V : https://www.celduc-relais.com/Technical_DataSheet/FA_SOM020200.pdf ; Humidifier: https://www.vevor.ca/ultrasonic-mist-maker-c_10257/mist-maker-fogger-10-head-ultrasonic-mist-humidifier-110v-w-transformer-p_010789401317?gclid=Cj0KCQjwxtSSBhDYARIsAEn0thQsOAX_IOUpdxwomKBn3O1nD1rKbnZhvn2D2-jlxk25Wg0w4PynO5kaAsS4EALw_wcB
const byte UV_Light_Relay = 27; // Relay F : https://www.mcmaster.com/8262T14/ ; UV Lamps: two 340nm UVA lamps
const byte Chamber_Fan_Relay2 = 28; // Relay Y : https://www.mcmaster.com/8262T14/ ; Fan: https://www.digikey.ca/en/products/detail/qualtek/FMA1-08025WBHT12/10228356
const byte Heater_Relay = 29; // Relay H : https://www.digikey.com/en/products/detail/sensata-crydom/CKRD6010/1771443 ; Heater: https://www.omega.com/en-us/industrial-heaters/duct-and-enclosures-heaters/duct-heaters/ahf-heater/p/AHF-10120
//Time Constant Values
const unsigned long seconds = 1000; //number of milliseconds in a second
const unsigned long minutes = 60000; //number of milliseconds in a minute
const unsigned long hours = 3600000; //number of milliseconds in an hour
//Temperature & Humidity Variables
const float sensorTempVariance = 0.5; //variable to modify target temperature set points ******************
const float sensorHumVariance = 1.5; //variable to modify target temperature set points ******************
const float targetTemp1 = 60; //target temperature for dry cycle
const float targetTemp2 = 50; //target temperature for wet cycle
float targetTemp = 60; //system initializing temperature (This is the value that gets modified in the code with specific cycle temps)
const float targetHum = 65; //target humidity for wet cycle
const float sht3TempWeight1 = 4; //Weighting for the Right SHT3 sensor temperature value ******************
const float sht3TempWeight2 = 5; //Weighting for the Middle SHT3 sensor temperature value ******************
const float sht3TempWeight3 = 4; //Weighting for the Left SHT3 sensor temperature value ******************
const float sht3HumWeight1 = 5; //Weighting for the Right SHT3 sensor humidity value ******************
const float sht3HumWeight2 = 3; //Weighting for the Middle SHT3 sensor humidity value ******************
const float sht3HumWeight3 = 4; //Weighting for the Left SHT3 sensor humidity value ******************
const unsigned int heaterPulse = 5000; //Duration for heater to run before turning off ******************
unsigned int chamberFanPulseDuration = 1000; //Duration to turn on the chamber fan during humidity control (must be in milliseconds) ******************
unsigned int humFanPulseDuration = 1000; //Duration to turn on the humidifier fan during humidity control (must be in milliseconds) ******************
unsigned int mistLoading = 3000; //Duration to run the humidifier to load the mist chamber (must be in milliseconds) *****************
bool idealValues = false;
//Global Variables
unsigned long startTime = 0; //dummy variable that will eventually tell the arduino at which millisecond the test began
float cycleDuration = 3 ; //number of hours that each cycle will run ******************
float singleBatchTime = cycleDuration * 2 * 3600000; // [ms]
unsigned int cycleCount = 0; //initial value for cycle counter
const unsigned int totalCycleCount = 42; //number of total cycles for test
unsigned long int timeVar = 0;
//select pins used for LCD and define LCD values
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int lcd_key = 5; //Default value equivalent to pressing no button
int adc_key_in = 2000; //Arbitrary value assigned
//Values are arbitarily assigned but should not be changed as they are prolific throughout the code
#define btnDOWN 0
#define btnUP 1
#define btnLEFT 2
#define btnRIGHT 3
#define btnSELECT 4
#define btnNONE 5
//Code to initialize system before test cycle begins (will only be ran one time immediately after powering on)
void setup() {
wdt_disable();
//establish digital pins for relay control and set them all to low
pinMode(Heater_Relay, OUTPUT);
digitalWrite(Heater_Relay, LOW);
pinMode(UV_Light_Relay, OUTPUT);
digitalWrite(UV_Light_Relay, LOW);
pinMode(Chamber_Fan_Relay1, OUTPUT);
digitalWrite(Chamber_Fan_Relay1, LOW);
pinMode(Humidifier_Fan_Relay, OUTPUT);
digitalWrite(Humidifier_Fan_Relay, LOW);
pinMode(Heat_Mist, OUTPUT);
digitalWrite(Heat_Mist, LOW);
pinMode(Safety_Lights_Relay, OUTPUT);
digitalWrite(Safety_Lights_Relay, LOW);
pinMode(Humidifier_Relay, OUTPUT);
digitalWrite(Humidifier_Relay, LOW);
pinMode(Chamber_Fan_Relay2, OUTPUT);
digitalWrite(Chamber_Fan_Relay2, LOW);
//establish unactive pins in INPUT_PULLUP mode to enable their internal resistor and eliminate stray noise signals
pinMode(30, INPUT_PULLUP);
pinMode(31, INPUT_PULLUP);
pinMode(32, INPUT_PULLUP);
pinMode(33, INPUT_PULLUP);
pinMode(34, INPUT_PULLUP);
pinMode(35, INPUT_PULLUP);
pinMode(36, INPUT_PULLUP);
pinMode(37, INPUT_PULLUP);
pinMode(38, INPUT_PULLUP);
pinMode(39, INPUT_PULLUP);
pinMode(40, INPUT_PULLUP);
pinMode(41, INPUT_PULLUP);
pinMode(42, INPUT_PULLUP);
pinMode(43, INPUT_PULLUP);
pinMode(44, INPUT_PULLUP);
pinMode(45, INPUT_PULLUP);
pinMode(46, INPUT_PULLUP);
pinMode(47, INPUT_PULLUP);
pinMode(48, INPUT_PULLUP);
pinMode(49, INPUT_PULLUP);
pinMode(50, INPUT_PULLUP);
pinMode(51, INPUT_PULLUP);
pinMode(52, INPUT_PULLUP);
pinMode(53, INPUT_PULLUP);
pinMode(A8, INPUT_PULLUP);
pinMode(A9, INPUT_PULLUP);
pinMode(A10, INPUT_PULLUP);
pinMode(A11, INPUT_PULLUP);
pinMode(A12, INPUT_PULLUP);
pinMode(A13, INPUT_PULLUP);
pinMode(A14, INPUT_PULLUP);
pinMode(A15, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
pinMode(15, INPUT_PULLUP);
pinMode(17, INPUT_PULLUP);
pinMode(18, INPUT_PULLUP);
//this section is to initialize the LCD display and Serial Monitor
Serial.begin(115200); //baud rate is determined by the requirement of the UV sensors
lcd.begin(16, 2);
lcd.setCursor(0, 0);
//Initialize the temperature & Humidity sensors
sht31_1.begin();
sht31_2.begin();
sht31_3.begin();
//Troubleshooting stuff
//this section of code allows for testing of Multiplexer function and displays which of the 8 ports the sensors are connected to in the serial monitor (*please note that if physical changes were required that the corresponding values for "tcaselect" function will need to be adjusted)
while (!Serial);
delay(1000);
Wire.begin();
Serial.println(F("\nTCAScanner Ready!"));
//Setting up the multiplexer for SHT3x sensors
for (uint8_t t = 0; t < 8; t++) {
tcaselect(t);
Serial.print(F("TCA Port #"));
Serial.println(t);
for (uint8_t addr = 0; addr <= 127; addr++) {
if (addr == TCAADDR) continue;
Wire.beginTransmission(addr);
if (!Wire.endTransmission()) {
Serial.print(F("Found I2C 0x"));
Serial.println(addr, HEX);
}
}
}
Serial.println(F("\ndone"));
Serial.println(F(""));
digitalWrite(Safety_Lights_Relay, HIGH);
} //End of Setup
//main loop that controls cycles
void loop() {
//This is to reset the arduino every 8 hours
timeVar = millis() - startTime;
if (timeVar > singleBatchTime && cycleCount != 0) {
wdt_enable(WDTO_250MS);
}
//This section reads the input from the LCD panel and performs specific actions
while (cycleCount == 0 && averageTemp() < targetTemp) { //Waits for user to press SELECT while maintaining target temperature
print2Serial(averageTemp(), averageHum());
delay(1000);
displayData(lcd_key);
tempMaintenance(targetTemp);
}
if (cycleCount == 0 && averageTemp() >= targetTemp) { //Cycle count will only be 0 upon first turning on the system, this prevents a user from restarting the test by accidentally pressing select
startupProcedure();
}
else {
displayData(lcd_key);
}
//This section maintains the specified temperature and humidity (depending on cycle)
if (cycleCounter() == true) { //Only enters on even number cycles ("wet cycles")
humMaintenance(targetTemp);
} else {
digitalWrite(Humidifier_Relay, LOW);
digitalWrite(Heat_Mist, LOW);
digitalWrite(Humidifier_Fan_Relay, LOW);
print2Serial(averageTemp(), averageHum());
delay(1000);
tempMaintenance(targetTemp);
}
//This section checks to see if the cycle has been running for the specified time and the number of completed cycles (ends the program if cycle count is reached)
checkTime();
//cyclesCompleted();
} //End of Loop
//This function allows the selection of different I2C addresses on the multiplexer
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 << i);
Wire.endTransmission();
}
//This function averages the temperatures of all three sensors in a weighted manner
float averageTemp() {
tcaselect(7);
float sht3Temp1 = sht31_2.readTemperature();
tcaselect(5);
float sht3Temp2 = sht31_1.readTemperature();
tcaselect(6);
float sht3Temp3 = sht31_3.readTemperature();
//tcaselect(5);
//float sht3Temp4 = sht31_4.readTemperature();
float tempAverage = ((sht3TempWeight1 * sht3Temp1 + sht3TempWeight2 * sht3Temp2 + sht3TempWeight3 * sht3Temp3)) / (sht3TempWeight1 + sht3TempWeight2 + sht3TempWeight3);
return tempAverage;
}
//This function averages the humidity of all three sensors in a weighted manner
float averageHum() {
tcaselect(7);
float sht3Hum1 = sht31_2.readHumidity();
tcaselect(5);
float sht3Hum2 = sht31_1.readHumidity();
tcaselect(6);
float sht3Hum3 = sht31_3.readHumidity();
float humAverage = ((sht3HumWeight1 * sht3Hum1) + (sht3HumWeight2 * sht3Hum2) + (sht3HumWeight3 * sht3Hum3)) / (sht3HumWeight1 + sht3HumWeight2 + sht3HumWeight3);
return humAverage;
}
//This function reads the value of the button on the LCD Display
/*int read_LCD_buttons() {
adc_key_in = analogRead(0);
if (adc_key_in < 50) return btnRIGHT; //3
if (adc_key_in < 250) return btnUP; //1
if (adc_key_in < 450) return btnDOWN; //0
if (adc_key_in < 650) return btnLEFT; //2
if (adc_key_in < 850) return btnSELECT; //4
if (adc_key_in > 1000) return btnNONE; //5
return btnNONE;
}*/
//This function maintains the temperature of the system (for dry-cycles)
void tempMaintenance(float temperature) {
float maintenanceTargetTemp = temperature - sensorTempVariance;
if (averageTemp() <= maintenanceTargetTemp) {
//digitalWrite(Chamber_Fan_Relay1, HIGH);
digitalWrite(Chamber_Fan_Relay2, HIGH);
if (averageTemp() < maintenanceTargetTemp) {
digitalWrite(Heater_Relay, HIGH);
delay(2000);
digitalWrite(Heater_Relay, LOW);
print2Serial(averageTemp(), averageHum());
}
delay(1000); //Delay is required so that residual heat in the inline heater will be blown into the chamber
if (averageTemp() < temperature && cycleCount == 0) {
digitalWrite(Heater_Relay, HIGH);
delay(3500);
digitalWrite(Heater_Relay, LOW);
print2Serial(averageTemp(), averageHum());
}
delay(1000);
}
else {
digitalWrite(Chamber_Fan_Relay1, LOW);
digitalWrite(Chamber_Fan_Relay2, LOW);
}
}
//This function maintains the temperature of the system (for wet-cycles)
void tempRH_Maintenance(float temperature) {
float maintenance_TargetTemp = temperature - sensorTempVariance;
digitalWrite(Chamber_Fan_Relay1, LOW);
if (averageTemp() <= maintenance_TargetTemp) {
digitalWrite(Chamber_Fan_Relay2, HIGH);
digitalWrite(Heater_Relay, HIGH);
delay(mistLoading);
while (averageTemp() <= maintenance_TargetTemp && idealValues == false) {
print2Serial(averageTemp(), averageHum());
displayData(lcd_key);
if (averageHum() < targetHum - sensorHumVariance ) {
digitalWrite(Humidifier_Fan_Relay, HIGH);
delay(mistLoading);
}
else {
digitalWrite(Humidifier_Fan_Relay, LOW);
delay(mistLoading);
idealValues = true;
}
}
digitalWrite(Heater_Relay, LOW);
delay(800); //Delay is required so that residual heat in the inline heater will be blown into the chamber
digitalWrite(Chamber_Fan_Relay2, LOW);
//digitalWrite(Humidifier_Fan_Relay, LOW);
}
else {
idealValues = false;
return;
}
}
//This function prints the data to the serial monitor and lcd display
void displayData(int sensor2Display) { //Value of 1 = top sensor, value of 2 = left sensor, value of 3 = right sensor, and value of 0 or 5 = average
float temp2Print = 0;
float hum2Print = 0;
if (sensor2Display == btnUP) {
/* // tcaselect(2); //value in parenthesis corresponds to the physical sensor at the highest location in the chamber
// temp2Print = sht31_1.readTemperature();
// hum2Print = sht31_1.readHumidity();
} else if (sensor2Display == btnLEFT) {
// tcaselect(3); //value in parenthesis corresponds to the physical sensor at the left most location in the chamber
// temp2Print = sht31_2.readTemperature();
// hum2Print = sht31_2.readHumidity();
} else if (sensor2Display == btnRIGHT) {
// tcaselect(4); //value in parenthesis corresponds to the physical sensor at the right most location in the chamber
// temp2Print = sht31_3.readTemperature();
// hum2Print = sht31_3.readHumidity();*/
} else {
temp2Print = averageTemp();
hum2Print = averageHum();
}
lcd.home();
lcd.print("T:");
lcd.print(round(temp2Print));
lcd.print("C");
lcd.print(" H:");
if (hum2Print < 10) {
lcd.print("0");
}
lcd.print(round(hum2Print));
lcd.print("%");
lcd.setCursor(0, 1);
unsigned long int timeMilliseconds = timeVar;
unsigned long int timeHours = timeMilliseconds / hours;
unsigned long int timeMins = (timeMilliseconds - (timeHours * hours)) / minutes;
lcd.print("t:");
lcd.print(timeHours);
lcd.print("h");
if (timeMins < 10) {
lcd.print("0");
}
lcd.print(timeMins);
lcd.setCursor(6, 1);
lcd.print("m");
lcd.print(" Cycle:");
lcd.print(cycleCount);
}
//This function is for starting the initial test
void startupProcedure() {
lcd.clear();
lcd.print("Starting...");
delay(1000); //Delay is added just for user experience
digitalWrite(UV_Light_Relay, HIGH);
delay(500);
//unsigned int dummyVar = uvCheck(); //Added to confirm via the serial monitor that the UV is operational
startTime = millis(); //Officially begins the start of the first cycle
cycleCount = 1; //Initialize the cycle counting and ensures that the requirements to trigger the startup procedure can no longer be met
}
//This function keeps count of which cycle the system is on
bool cycleCounter() {
if (cycleCount % 2 == 0) { //Even numbered cycles (wet cycles) will return true
return true;
}
else {
return false;
}
}
//This function removes the excess moisture if the target RH is passed. Also, by momentarily turning on the humidifier fan it tries to keep all sensors in the same RH range.
void excess_Humidity() {
float adjustedHumTarget = targetHum - (2 * sensorHumVariance);
if (averageHum() > adjustedHumTarget) {
digitalWrite(Heat_Mist, LOW);
}
if (averageHum() >= targetHum) { // If RH is gone too much high, play with chamber fans to remove the excessive mist
digitalWrite(Humidifier_Fan_Relay, LOW);
digitalWrite(Chamber_Fan_Relay1, HIGH);
delay(800);
digitalWrite(Chamber_Fan_Relay1, LOW);
delay(mistLoading);
}
else {
return;
/* tcaselect(6);
float T_Last = sht31_3.readTemperature();
float RH_Last = sht31_3.readHumidity();
tcaselect(7);
float T_First = sht31_2.readTemperature();
float RH_First = sht31_2.readHumidity();
if (T_First != T_Last || RH_First != RH_Last) {
digitalWrite(Chamber_Fan_Relay2, HIGH);
delay(250);
digitalWrite(Chamber_Fan_Relay2, LOW);
print2Serial(averageTemp(), averageHum());
delay(2000);
}*/
}
}
//This function maintains the humidity of the system
void humMaintenance(float temperature) {
float adjustedHumTarget = targetHum - sensorHumVariance;
if (averageHum() > targetHum + mistLoading * sensorHumVariance) {
digitalWrite(Humidifier_Relay, LOW);
digitalWrite(Heat_Mist, LOW);
}
else {
digitalWrite(Humidifier_Relay, HIGH);
}
if (digitalRead(Humidifier_Fan_Relay) == HIGH) { // If target RH is reached, turn the fogger OFF.
if (averageHum() >= adjustedHumTarget) { // First see if RH is in the desired range
digitalWrite(Humidifier_Fan_Relay, LOW);
delay(mistLoading);
if (averageHum() < targetHum) { //Going a little bit higher than the RH setpoint
digitalWrite(Humidifier_Fan_Relay, HIGH);
print2Serial(averageTemp(), averageHum());
delay(mistLoading / 2);
digitalWrite(Humidifier_Fan_Relay, LOW);
}
tempRH_Maintenance(temperature);
}
excess_Humidity();
}
if (averageHum() < targetHum) {
digitalWrite(Humidifier_Fan_Relay, HIGH);
if (averageHum() > targetHum / 2 && averageHum() < (adjustedHumTarget - 2 * sensorHumVariance)) {
digitalWrite(Heat_Mist, HIGH);
}
print2Serial(averageTemp(), averageHum());
delay(mistLoading);
tempRH_Maintenance(temperature);
}
else {
excess_Humidity();
}
}
//This function checks to see if the current cycle has been running for more than the specified cycle time and increases the cycle count
void checkTime() {
//int convertedTime = (int) cycleDuration * hours; //convert cycle duration to milliseconds (casting to int drops the fractions of the millisecond if any and makes it possible to convert to long)
unsigned long cycleDurationMills = cycleDuration * hours;
//long timeCheckVar = timeVar;
if (timeVar >= cycleDurationMills) {
//lcd.clear();
cycleCount = 2;
toggleUV();
toggleTargetTemp();
}
else {
cycleCount = 1;
}
}
//This functions turns the UV light on/off depending on the cycle
void toggleUV() {
if (cycleCounter() == true) {
digitalWrite(UV_Light_Relay, LOW);
delay(500); //Delay is required so that the sensors have adequate time to determine if the UV light is off
//unsigned int dummyVar = uvCheck();
}
else if (cycleCounter() == false && cycleCount > 0) {
digitalWrite(UV_Light_Relay, HIGH);
delay(500); //Delay is required so that the sensors have adequate time to determine if the UV light is on
//unsigned int dummyVar = uvCheck();
//startTime = millis(); //Starts the timer for the current cycle as soon as the UV light is on
}
}
//This function sets the target temperature depending on the cycle
void toggleTargetTemp() {
if (cycleCounter() == true) {
targetTemp = targetTemp2;
//print2Serial(averageTemp(), averageHum());
humMaintenance(targetTemp); //Brings system to the specified operating conditions for wet cycle
//startTime = millis(); //Timer for the wet cycle begins when target humidity is reached
}
else {
targetTemp = targetTemp1;
//print2Serial(averageTemp(), averageHum());
}
}
//This function prints the necessary data to the serial monitor
void print2Serial(float temperatureValue, float humidityValue) {
float temp2Print = 0;
float hum2Print = 0;
Serial.println(F("THE ORDER OF SENSORS IS ACCORDING TO THE AIR FLOW DIRECTION"));
Serial.println(F(""));
Serial.print(F("Target Temperature: "));
Serial.println(targetTemp);
Serial.print(F("Current Avg. Temperature: "));
Serial.print(temperatureValue);
Serial.println(F(" °C"));
Serial.println(F(""));
Serial.print(F("RIGHT (1st sensor): "));
tcaselect(7);
temp2Print = sht31_2.readTemperature();
Serial.print(temp2Print);
Serial.println(F(" °C"));
Serial.print(F("MIDDLE (2nd sensor): "));
tcaselect(5);
temp2Print = sht31_1.readTemperature();
Serial.print(temp2Print);
Serial.println(F(" °C"));
Serial.print(F("LEFT (3rd sensor): "));
tcaselect(6);
temp2Print = sht31_3.readTemperature();
Serial.print(temp2Print);
Serial.println(F(" °C"));
Serial.println(F(""));
Serial.print(F("Current Avg. RH: "));
Serial.print(humidityValue);
Serial.println(F(" %"));
Serial.println(F(""));
Serial.print(F("RIGHT Humidity: "));
tcaselect(7);
hum2Print = sht31_2.readHumidity();
Serial.print(hum2Print);
Serial.println(F(" %"));
Serial.print(F("MIDDLE Humidity: "));
tcaselect(5);
hum2Print = sht31_1.readHumidity();
Serial.print(hum2Print);
Serial.println(F(" %"));
Serial.print(F("LEFT Humidity: "));
tcaselect(6);
hum2Print = sht31_3.readHumidity();
Serial.print(hum2Print);
Serial.println(F(" %"));
Serial.println(F(""));
Serial.print(F("Cycle Count: "));
Serial.println(cycleCount);
Serial.print(F("Current Time Elapsed Since Start of the Batch: "));
unsigned long int timeVarHrs = timeVar / hours;
unsigned long int timeVar2 = (timeVar - (timeVarHrs * hours));
unsigned long int timeVarMins = timeVar2 / minutes;
unsigned long int timeVarSecs = (timeVar2 - (timeVarMins * minutes)) / seconds;
Serial.print(timeVarHrs);
Serial.print(F(" Hrs "));
Serial.print(timeVarMins);
Serial.print(F(" Mins "));
Serial.print(timeVarSecs);
Serial.println(F(" Secs"));
Serial.println(F("*****************************************************************"));
Serial.println(F(""));