/*
As of 23/01/2024, the modified code is functioning as intended. It features a temperature
control with hysteresis; "somehow flip-flop"
A fundamental digital circuit element with two stable states used to store state information.
Flip-flops are essential building blocks in digital circuits, especially in sequential logic,
where the output depends on both the current and past inputs and states. In this logic circuit,
the flip-flop monitors the initial freezer temperature as it cools down from room temperature to
subzero levels. Once the desired temperature is reached, it stops the compressor and keeps it off
until the freezer temperature rises to a preset threshold, triggering the compressor to restart.
This process repeats, while also accounting for the scheduled forced defrost period.All variables
—such as high/low temperature, start/stop defrost, on-screen text, alarm triggers, and more— can
be adjusted as needed for convenience.
*/


#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#include <TimerOne.h>
#include <TimerThree.h>

// Define one-wire communication for temperature sensors
OneWire oneWire1(52);  // room temperature sensor
DallasTemperature sensors1(&oneWire1);

OneWire oneWire2(24);  // fridge temperature sensor
DallasTemperature sensors2(&oneWire2);

OneWire oneWire3(22);  // freezer temperature sensor
DallasTemperature sensors3(&oneWire3);

// Define relay pins and LCD pins
const int compressorRelay = 25;
const int compressorLed = 27;
const int defrostRelay = 30;
const int defrostLed = 31;
const int coolfailRelay = 41;

const int pin_RS = 8;
const int pin_EN = 9;
const int pin_d4 = 4;
const int pin_d5 = 5;
const int pin_d6 = 6;
const int pin_d7 = 7;
const int pin_BL = 10;
LiquidCrystal lcd(pin_RS, pin_EN, pin_d4, pin_d5, pin_d6, pin_d7);

// Define LCD display parameters
int totalColumns = 16;
int totalRows = 2;

// Define timing variables
unsigned long startTime=0;
unsigned long elapsedTime=0;
unsigned long lastScrollTime = 0;
unsigned long totalRunningHours;
unsigned long lastDefrostTime = 0;
const unsigned long defrostInterval = 3010000;  /* Defrost interval in milliseconds (60 seconds)
must be >300000 msec to avoid looping & preventing cooling to restart*/ 

const int defrostDuration = 15000;
const int secondsThreshold = 10;
const int monitorTempThreshold = -10;  // Added threshold for monitoring temperature

// Define the interval for blinking pin 27 compressor led when conditions are met
const unsigned long blinkCompressorLedInterval = 200;  // Blink interval for compressor LED in milliseconds

/*
const int blinkredInterval = 500;  // Blink interval for compressor LED in milliseconds
unsigned long lastBlinkTime = 0;
bool isCompressorLedOn = false;
*/

// Define the states of the control cycle
enum CycleState
{
  COOLING,
  DEFROST,
  MONITOR_TEMP,
};

CycleState currentCycleState = COOLING;
unsigned long cycleStartTime = 0;

/* Define the interval for automatic reset of the entire code in milliseconds (40 days =
40 day x 24 hour x 60 minute x 60 second x 1000 milli second) to avoid code glitches & the 49 days
millis rollover */
const unsigned long resetInterval = 3456000;

unsigned long lastResetTime = 0;

// Global variable to track the time the freezer temperature goes above 5°C
static unsigned long aboveThresholdStartTime = 0;

// Define scrolling message for LCD
String scrollingMessage = "Three temperature sensors 10/10/2023;room, fridge, freezer & total operating time controller...";

// Define the blinking interval for pin 41 cool fail in milliseconds
const unsigned long blinkInterval = 500;

// Function to scroll a message on the LCD
void scrollMessage(int row, String message, int delayTime, int totalColumns)
{
  // Padding message with spaces for scrolling effect
  for (int i = 0; i < totalColumns; i++)
  {
    message = " " + message;
  }
  message = message + " ";

  // Scroll the message on the LCD
  for (int position = 0; position < message.length(); position++)
  {
    lcd.setCursor(0, row);
    lcd.print(message.substring(position, position + totalColumns));
    delay(delayTime);
  }
}

// Timer1 callback function for blinking (blinking independent of code)cool fail
void timer1Callback()
{
  // Check if the setup phase is completed
  if(millis() > 14000) {  // to prevent coolfailRelay pin 41 from unnecessary instantaneous toggling LOW/HIGH during startup
    // Toggle the state of the coolfail relay
    if (digitalRead(coolfailRelay) == HIGH)
    {
      digitalWrite(coolfailRelay, LOW);
    }
    else
    {
      digitalWrite(coolfailRelay, HIGH);

    }
  }
}

//===============================================================================
//===============================================================================
//================================================================================

// Setup function
void setup(void)
{
  Serial.begin(9600);
  lcd.begin(16, 2); //column, row
  lcd.setCursor(0, 0);

  lcd.print("SETUP CONTROLLER");

  delay(1000);

  lcd.setCursor(0, 1);

  lcd.print("Wait for Defrost");
  delay(1000);

for (int i = 0; i < 37; i++) {
    digitalWrite(defrostLed, HIGH);
    delay(400);  // Adjust the delay for the blinking speed
    digitalWrite(defrostLed, LOW);
    delay(200);  // Adjust the delay for the blinking speed
  }

digitalWrite(defrostLed, HIGH);
delay(15000);

   digitalWrite(defrostRelay, HIGH);/*to defrost before cooling, this is to avoid 
   missing defrosting cycle if frequent power failures occur*/
   
 

     lcd.clear();
  lcd.setCursor(0, 0);

 lcd.print("(..DEFROSTING..)");

   // Display countdown during startup
for (int countdown = 70 ; countdown > 0; countdown--)
{
  // Calculate hours, minutes, and seconds
  int hours = countdown / 3600;
  int minutes = (countdown % 3600) / 60;
  int seconds = countdown % 60;

  // Set the cursor position on the LCD screen
  lcd.setCursor(4, 1);

  // Print the countdown in the format "hh:mm:ss"
  lcd.print(String(hours) + "h " + String(minutes) + "m " + String(seconds) + "s ");
  
  // Introduce a delay of 1000 milliseconds (1 second)
  delay(1000); // Countdown speed
  
//

}

for (int i = 0; i < 80; i++) {
    digitalWrite(defrostLed, HIGH);
    delay(50);  // Adjust the delay for the blinking speed
    digitalWrite(defrostLed, LOW);
    delay(900);  // Adjust the delay for the blinking speed
  }


digitalWrite(defrostRelay, LOW);

delay(4000);

digitalWrite(defrostLed, LOW);

// Initialize Timer3 with the blinkCompressorLedCallback function and the desired interval
Timer3.initialize(blinkCompressorLedInterval * 1000);  // Timer interval is in microseconds
Timer3.attachInterrupt(blinkCompressorLedCallback);
Timer3.stop();  // Stop the timer initially


  //startTime = millis();  // Record the start time

  // Set up relay pins
  pinMode(compressorRelay, OUTPUT);
  pinMode(compressorLed, OUTPUT);
  pinMode(defrostRelay, OUTPUT);
  pinMode(defrostLed, OUTPUT);
  pinMode(coolfailRelay, OUTPUT);
  digitalWrite(coolfailRelay, LOW);

  // Initialize temperature sensors
  sensors1.begin();
  sensors2.begin();
  sensors3.begin();

  // Set initial timing variables
  startTime = millis();
  lastDefrostTime = millis();
  cycleStartTime = millis();

  // Initialize Timer1 with the timer1Callback function and the desired interval
  Timer1.initialize(blinkInterval * 1000);  // Timer interval is in microseconds
  Timer1.attachInterrupt(timer1Callback);
  Timer1.stop();  // Stop the timer initially

  // Set the initial state of pin 41 to LOW
  digitalWrite(coolfailRelay, LOW);
 // delay(10000); // waiting time to prevent frequent startups after power failure back

}

//==========================================================================
//==========================================================================
//===========================================================================

void handleScrollMessage(String message, int row, int delayTime, int totalColumns) {
  static unsigned long lastDisplayTime = 0;
  
lcd.clear();
  if (millis() - lastDisplayTime > delayTime) {
    lastDisplayTime = millis();

    // Scroll the message on the LCD
    for (int position = 0; position < message.length(); position++) {
      lcd.setCursor(0, row);
      lcd.print(message.substring(position, position + totalColumns));
      delay(50);  // Adjust the delay for scrolling speed
      
lcd.clear();
    }
  }
}

// Run1 function to execute elapsed time while scrolling text when called for 30 seconds
void run1() {
  unsigned long sectionStartTime = millis();

  // Run this section for 30 seconds
  while (millis() - sectionStartTime < 30000) {
    // Your specific section code goes here

    // Update elapsed time
    elapsedTime = millis() - startTime;

    // Calculate days, hours, minutes, and seconds
    int days = elapsedTime / 86400000;
    int hours = (elapsedTime % 86400000) / 3600000;
    int minutes = (elapsedTime % 3600000) / 60000;
    int seconds = (elapsedTime % 60000) / 1000;

    // Display elapsed time in the format "xd xh xm xs"
     lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("T= ");
    if (days > 0) {
      lcd.print(days);
      lcd.print("d ");
    }
    if (hours > 0 || days > 0) {
      lcd.print(hours);
      lcd.print("h ");
    }
    if (minutes > 0 || hours > 0 || days > 0) {
      lcd.print(minutes);
      lcd.print("m ");
    }
    lcd.print(seconds);
    lcd.print("s ");

    // Display scrolling text
    lcd.setCursor(0, 1);

    // Scroll the message on the LCD
    static int position = 0;
    lcd.print(scrollingMessage.substring(position, position + totalColumns));
    position++;
    if (position > scrollingMessage.length() - totalColumns) {
      position = 0;

 float freezer = sensors3.getTempCByIndex(0);
 float room = sensors1.getTempCByIndex(0);
  float fridge = sensors2.getTempCByIndex(0);
   lcd.clear();
 lcd.setCursor(0,0);
  // Display room and fridge temperatures on the LCD
  lcd.setCursor(0, 0);
  lcd.print("Room   =       C");
  lcd.setCursor(14, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print(room);//display room temperature

  lcd.setCursor(0, 1);
  lcd.print("Fridge =       C");
  lcd.setCursor(14, 1);
  lcd.print((char)223);
  lcd.setCursor(8, 1);
  lcd.print(fridge);//display fridge temperature

  delay(4000);

  // Repeat the temperature display for fridge and freezer
  lcd.setCursor(0, 0);
  lcd.print("Fridge =       C");
  lcd.setCursor(14, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print(fridge);

  lcd.setCursor(0, 1);
  lcd.print("Freezer=       C");
  lcd.setCursor(14, 1);
  lcd.print((char)223);
  lcd.setCursor(8, 1);
  lcd.print(freezer);//display freezer temperature
 delay(4000);
  

  // Repeat the temperature display for freezer
 

   lcd.setCursor(0, 0);
  lcd.print("Freezer=       C");
  lcd.setCursor(14, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print(freezer);
 
lcd.setCursor(0, 1);
  // Display room and fridge temperatures on the LCD
  lcd.setCursor(0, 1);
  lcd.print("Room   =       C");
  lcd.setCursor(14, 1);
  lcd.print((char)223);
  lcd.setCursor(8, 1);
  lcd.print(room);//display room temperature

delay(4000);
    }

    // Your additional code can go here if needed

    // Adjust the delay for scrolling speed
    delay(500);
  }
}

// Run2 function to execute time elapsed while a text displays also when calling while looping for 25 seconds
void run2() {
  unsigned long sectionStartTime = millis();

  // Run this section for 25 seconds
  while (millis() - sectionStartTime < 25000) {
    // Your specific section code goes here

    // Update elapsed time
    elapsedTime = millis() - startTime;

    // Calculate days, hours, minutes, and seconds
    int days = elapsedTime / 86400000;
    int hours = (elapsedTime % 86400000) / 3600000;
    int minutes = (elapsedTime % 3600000) / 60000;
    int seconds = (elapsedTime % 60000) / 1000;

    // Display elapsed time in the format "xd xh xm xs"
    lcd.setCursor(0, 0);
    lcd.print("T= ");
    if (days > 0) {
      lcd.print(days);
      lcd.print("d ");
    }
    if (hours > 0 || days > 0) {
      lcd.print(hours);
      lcd.print("h ");
    }
    if (minutes > 0 || hours > 0 || days > 0) {
      lcd.print(minutes);
      lcd.print("m ");
    }
    lcd.print(seconds);
    lcd.print("s ");

     lcd.setCursor(0, 1);
      lcd.print(" COMPRESSOR RUN ");
      delay(700);
      lcd.setCursor(0, 1);
      lcd.print("TEMPERATURE DROP");
      delay(700);

      cycleStartTime = millis();
    
  }
}

void blinkCompressorLedCallback()
{
  // Check if pin 25 is HIGH and pin 30 is LOW
  if (digitalRead(25) == HIGH && digitalRead(30) == LOW)
  {
    // Toggle the state of the compressor LED (pin 27)
    if (digitalRead(compressorLed) == HIGH)
    {
      digitalWrite(compressorLed, LOW);
    }
    else
    {
      digitalWrite(compressorLed, HIGH);
    }
  }
  else
  {
    // If conditions are not met, turn off the compressor LED
    digitalWrite(compressorLed, LOW);
  }
}


//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
//====================================================================================
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//main loop function
void loop() {
  // Update elapsed time
  elapsedTime = millis() - startTime;
  lcd.clear();

//Serial.print("Current Millis: ");
//Serial.println(currentMillis);
Serial.print("Elapsed Time: ");
Serial.println(elapsedTime);


Serial.print("Total Running Minutes: ");
Serial.println(totalRunningHours);

Serial.print("Total Running Hours: ");
Serial.println(totalRunningHours/60);

//Serial.print("Elapsed Time: ");
//Serial.println(elapsedTime);
//start timer 3 blinking compressor led if compressor relay HIGH & defrost relay LOW
 Timer3.start();



// Reset the state of pin 41 (coolfailRelay)
  float freezer = sensors3.getTempCByIndex(0);

  if (freezer < 5 )
  {
  digitalWrite(coolfailRelay, LOW);  
}

// Run1 function to execute elapsed time while scrolling text when called for 30 seconds
  run1();
 lcd.clear();
lcd.setCursor(0, 0);
  lcd.print("Time:vvv ");
  delay(3000);
    lcd.clear();
   run1();
 lcd.clear();
  lcd.print("Time:تبjhkjhkلبتvvv ");
  delay(3000);
  lcd.clear();
 run1();

   lcd.clear();
  lcd.print("Time:vvvgff ");
  delay(3000);
    lcd.clear();
float room = sensors1.getTempCByIndex(0);
  float fridge = sensors2.getTempCByIndex(0);
  //float freezer = sensors3.getTempCByIndex(0);

  // Display room and fridge temperatures on the LCD
  lcd.setCursor(0, 0);
  lcd.print("Room   =       C");
  lcd.setCursor(14, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print(room);//display room temperature

  lcd.setCursor(0, 1);
  lcd.print("Fridge =       C");
  lcd.setCursor(14, 1);
  lcd.print((char)223);
  lcd.setCursor(8, 1);
  lcd.print(fridge);//display fridge temperature

  delay(4000);

  // Repeat the temperature display for fridge and freezer
  lcd.setCursor(0, 0);
  lcd.print("Fridge =       C");
  lcd.setCursor(14, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print(fridge);

  lcd.setCursor(0, 1);
  lcd.print("Freezer=       C");
  lcd.setCursor(14, 1);
  lcd.print((char)223);
  lcd.setCursor(8, 1);
  lcd.print(freezer);//display freezer temperature

   delay(4000);

  // Repeat the temperature display for freezer
 lcd.clear();

   lcd.setCursor(0, 0);
  lcd.print("Freezer=       C");
  lcd.setCursor(14, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print(freezer);
 delay(1000);

// Display room and fridge temperatures on the LCD
  lcd.setCursor(0, 1);
  lcd.print("Room   =       C");
  lcd.setCursor(14, 1);
  lcd.print((char)223);
  lcd.setCursor(8, 1);
  lcd.print(room);//display room temperature

   delay(4000);


{
  unsigned long currentMillis = millis();

  // Request temperature readings from sensors
  sensors1.requestTemperatures();
  sensors2.requestTemperatures();
  sensors3.requestTemperatures();
  float room = sensors1.getTempCByIndex(0);
  float fridge = sensors2.getTempCByIndex(0);
  float freezer = sensors3.getTempCByIndex(0);
   //unsigned long elapsedTime = currentMillis - startTime;
   //float totalRunningHours = elapsedTime / (1000.0 * 3600.0);
   totalRunningHours = elapsedTime/60000;

  // Check if it's time to reset entire code every 40 days
  if (currentMillis - lastResetTime >= resetInterval)
  {
    // Perform any cleanup or actions before resetting, if needed
    delay(1000);                      // Wait for stability (optional)
    asm volatile("  jmp 0");          // Jump to the beginning of the program, resetting it
  }

  // Display a welcome message on the LCD
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("....GOOD DAY....");
  delay(200);
  lcd.clear();
  delay(200);
  lcd.print("....GOOD DAY....");
  delay(200);
  lcd.clear();

 // float freezer = sensors3.getTempCByIndex(0);
 //float room = sensors1.getTempCByIndex(0);
  //float fridge = sensors2.getTempCByIndex(0);
   lcd.clear();
 lcd.setCursor(0,0);
  // Display room and fridge temperatures on the LCD
  lcd.setCursor(0, 0);
  lcd.print("Room   =       C");
  lcd.setCursor(14, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print(room);//display room temperature

  lcd.setCursor(0, 1);
  lcd.print("Fridge =       C");
  lcd.setCursor(14, 1);
  lcd.print((char)223);
  lcd.setCursor(8, 1);
  lcd.print(fridge);//display fridge temperature

  delay(4000);

  // Repeat the temperature display for fridge and freezer
  lcd.setCursor(0, 0);
  lcd.print("Fridge =       C");
  lcd.setCursor(14, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print(fridge);

  lcd.setCursor(0, 1);
  lcd.print("Freezer=       C");
  lcd.setCursor(14, 1);
  lcd.print((char)223);
  lcd.setCursor(8, 1);
  lcd.print(freezer);//display freezer temperature

 delay(4000);
 lcd.setCursor(0, 0);
  lcd.print("Freezer=       C");
  lcd.setCursor(14, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print(freezer);//display freezer temperature
lcd.setCursor(0,1);
  // Display room and fridge temperatures on the LCD
  lcd.setCursor(0, 1);
  lcd.print("Room   =       C");
  lcd.setCursor(14, 1);
  lcd.print((char)223);
  lcd.setCursor(8, 1);
  lcd.print(room);//display room temperature

 delay(4000);


    lcd.clear();

 // if total running hours <one hour, then print min, then sec, else print hours

 // Run1 function to execute elapsed time while scrolling text when called for 30 seconds
  lcd.clear();
  run1();
 lcd.clear();
lcd.setCursor(0, 0);

  // Display information about time and temperature range on the LCD
  lcd.setCursor(0, 0);
  lcd.print("Time in hours    ");
  lcd.setCursor(14, 1);
  lcd.setCursor(0, 1);
  lcd.print("Temp.-55to+125 C");
  lcd.setCursor(14, 1);
  lcd.print((char)223); // Degree symbol
  delay(2000);

  // Display room and fridge temperatures on the LCD
  lcd.setCursor(0, 0);
  lcd.print("Room   =       C");
  lcd.setCursor(14, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print(room);//display room temperature

  lcd.setCursor(0, 1);
  lcd.print("Fridge =       C");
  lcd.setCursor(14, 1);
  lcd.print((char)223);
  lcd.setCursor(8, 1);
  lcd.print(fridge);//display fridge temperature

  delay(4000);

  // Repeat the temperature display for fridge and freezer
  lcd.setCursor(0, 0);
  lcd.print("Fridge =       C");
  lcd.setCursor(14, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print(fridge);

  lcd.setCursor(0, 1);
  lcd.print("Freezer=       C");
  lcd.setCursor(14, 1);
  lcd.print((char)223);
  lcd.setCursor(8, 1);
  lcd.print(freezer);//display freezer temperature

    delay(4000);

  // Repeat the temperature display for freezer
 lcd.clear();

   lcd.setCursor(0, 0);
  lcd.print("Freezer=       C");
  lcd.setCursor(14, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print(freezer);
 
// Display room and fridge temperatures on the LCD
  lcd.setCursor(0, 1);
  lcd.print("Room   =       C");
  lcd.setCursor(14, 1);
  lcd.print((char)223);
  lcd.setCursor(8, 1);
  lcd.print(room);//display room temperature

  delay(4000);
// Run1 function to execute elapsed time while scrolling text when called for 30 seconds
  lcd.clear();
  run1();
 lcd.clear();
lcd.setCursor(0, 0);


  // Update the last reset time if a reset is not triggered
  lastResetTime = currentMillis;

  // Debug statements
  Serial.println("Current Millis: " + String(currentMillis));
  Serial.println("Last Defrost Time: " + String(lastDefrostTime));

  // Check for defrost cycle every 60 seconds & the 49.7 days millis rollover prevention
  if ((currentMillis - lastDefrostTime >= defrostInterval) || (currentMillis < lastDefrostTime && (4294967295UL - lastDefrostTime + currentMillis) >= defrostInterval))
  {
   lcd.setCursor(0,0);
   lcd.clear();
   lcd.print(" DEFROST START ");
 lcd.setCursor(0,1);
   lcd.print("DEFROSTING 15min");

lcd.clear();

lcd.setCursor(0,0);

lcd.print("DEFROSTING 15min");

digitalWrite(compressorRelay, LOW);
digitalWrite(compressorLed,LOW);
delay(1500);

digitalWrite(defrostLed, HIGH);
delay(5000);
 digitalWrite(defrostRelay, HIGH);
 

   // Display countdown during startup
  for (int countdown = 37; countdown > 0; countdown--)
  {
    
    lcd.setCursor(5, 1);
    lcd.print("" + String(countdown) + " min ");
    delay(1000); //countdown speed

    digitalWrite(compressorRelay, LOW);
    digitalWrite(compressorLed,LOW);
    //delay(2000);
    

  }

delay(3000);

digitalWrite(defrostRelay, LOW);  // Set defrost relay LOW

delay(3000);

digitalWrite(defrostLed, LOW);

   // startDefrostCycle();
    lcd.clear();
   // delay(1000);
    lastDefrostTime = currentMillis;
  }}

  // Perform cooling, defrost, or monitor temperature cycle actions
  if (currentCycleState == COOLING)
  {
    performCoolingCycle();
  }
  else if (currentCycleState == DEFROST)
  {
    performDefrostCycle();
  }
    

// Run1 function to execute elapsed time while scrolling text when called for 30 seconds
  run1();
 lcd.clear();
lcd.setCursor(0, 0);

  delay(3000);

  // Check if the freezer temperature is above (threshold, for more than interval) cool fail
  if (freezerTemperatureAboveThreshold(5, 10000))
  {
    // Start the blinking of pin 41

  lcd.clear();

   lcd.setCursor(0,0);
  
   lcd.print("     ALARM     ");
 lcd.setCursor(0,1);
   lcd.print("   COOL FAIL   ");
    //startDefrostCycle();
  
   // delay(1000);
    Timer1.start();
  }
  else
  {
    // Stop the blinking of pin 41
    Timer1.stop();
    // If not in the fail state, turn off the relay
    digitalWrite(coolfailRelay, LOW);
  }

  //delay(2000);
}

// Function to perform cooling cycle based on freezer temperature, flip-flop action
void performCoolingCycle()
{
  sensors1.requestTemperatures();
  sensors2.requestTemperatures();
  sensors3.requestTemperatures();

  float freezer = sensors3.getTempCByIndex(0);
  updateFreezerRelayState(freezer);
}

// Function to update the state of the compressor relay based on freezer temperature, flip-flop like
void updateFreezerRelayState(float freezerTemp)
{
  // Define a flag to track whether the compressor is allowed to run
  static bool allowCompressor = true; // Use 'static' to retain the value across function calls

  // Your temperature monitoring logic
  if (freezerTemp >= 0 && allowCompressor)
  {
    // Run the compressor (set relay HIGH)
    digitalWrite(compressorLed, HIGH);
    delay(4000);
    digitalWrite(compressorRelay, HIGH);
  }
  else if (freezerTemp < -10)
  {
    // Stop the compressor (set relay LOW) and disallow restart
    digitalWrite(compressorLed, LOW);
    delay(4000);
    digitalWrite(compressorRelay, LOW);
    allowCompressor = false;
  }
  else if (freezerTemp > 0 && !allowCompressor)
  {
    // Allow the compressor to restart when the temperature rises above 0°C
    allowCompressor = true;
  }




// Run2 function to execute time elapsed while a text displays also when calling while looping for 25 seconds

  lcd.clear();
  run2();{
 lcd.clear();
lcd.setCursor(0, 0);

     }
    }
  
 

// Function to start the defrost cycle
void startDefrostCycle()
{
  digitalWrite(compressorRelay, LOW);
  digitalWrite(compressorLed,LOW);
  digitalWrite(defrostRelay, HIGH);
  currentCycleState = DEFROST;

  unsigned long defrostEndTime = millis() + defrostDuration;
  while (millis() < defrostEndTime)
  {
    sensors1.requestTemperatures();
    sensors2.requestTemperatures();
    sensors3.requestTemperatures();
    delay(100);
  }

  digitalWrite(defrostRelay, LOW);
  //currentCycleState = MONITOR_TEMP;
}

// Function to perform actions during the defrost cycle
void performDefrostCycle()
{
  // Perform actions during defrost cycle, if needed
}


// Function to check if freezer temperature is above a threshold for a certain duration
bool freezerTemperatureAboveThreshold(float threshold, unsigned long duration)
{
  sensors1.requestTemperatures();
  sensors2.requestTemperatures();
  sensors3.requestTemperatures();

  float freezer = sensors3.getTempCByIndex(0);

  if (freezer >= threshold)
  {
    if (millis() - aboveThresholdStartTime >= duration)
    {
      aboveThresholdStartTime = millis();
      return true;
    }
  }
  else
  {
    aboveThresholdStartTime = millis();
  }

  return false;

}




Loading
ds18b20
Loading
ds18b20
Loading
ds18b20
freezer
fridge
room
cooling
relay
fridge
blinker
(-10°C~0°C)
defrosting
relay
defrost
blinker
(15sec/50min)
alarm
high temp
(>5°C)
(-55°C to +125°C)