/*Overall, the code orchestrates a control cycle for a refrigeration system,
incorporating temperature monitoring, cooling, defrosting, and various indicators for system status.
The LCD provides real-time information, and the code includes mechanisms to handle potential issues like
cooling failures.
Further analytic explanation can be found in the doc file within the same folder*/
//==========================================================================
//==========================================================================
//===========================================================================
/*Before real operation adjust the following;
1- pins
2- const unsigned long defrostInterval = 600000; // Defrost interval in milliseconds (60 seconds)
3- const int defrostDuration = 3000; // defrost duration
4- const int secondsThreshold = 10; // threshold time elapseed for monitoring temperature
5- const int monitorTempThreshold = -10; // Added threshold for monitoring temperature
6- const unsigned long blinkInterval = 500;// Define the blinking interval for pin 41 in milliseconds
7- const unsigned long resetInterval = 20*24*60*60*1000; // Define the interval for global automatic reset in milliseconds (2 minutes)
8- if (freezerTemperatureAboveThreshold(5, 10000)); // time & seconds
9- scrollMessage(1, scrollingMessage, 600, totalColumns); // Scroll speed the predefined message on the LCD
10-delays()
11-units of time
12-for (int countdown = 300; countdown > 0; countdown--) // startup count down
*/
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#include <TimerOne.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 defrostRelay = 30;
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 lastDefrostTime = 0;
const unsigned long defrostInterval = 301000; /* 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 states of the control cycle
enum CycleState
{
COOLING,
DEFROST,
MONITOR_TEMP,
};
CycleState currentCycleState = COOLING;
unsigned long cycleStartTime = 0;
// Define the interval for automatic reset in milliseconds (2 minutes)
const unsigned long resetInterval = 240000;
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 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)
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);
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 = 3 ; 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(5, 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
}
digitalWrite(defrostRelay, LOW);
// Set up relay pins
pinMode(compressorRelay, OUTPUT);
pinMode(defrostRelay, 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
}
//==========================================================================
//==========================================================================
//===========================================================================
// Main loop function
void loop(void)
{
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);
// Check if it's time to reset every 2 minutes
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();
// if total running hours <one hour, then print min, then sec, else print hours
if (totalRunningHours < 1.0 / 60.0) {
lcd.setCursor(0, 0);
lcd.print("Time= sec");
lcd.setCursor(5, 0);
lcd.print(totalRunningHours * 3600, 2); // Convert totalRunningHours to seconds
} else if (totalRunningHours < 1.0) {
lcd.setCursor(0, 0);
lcd.print("Time= min");
lcd.setCursor(5, 0);
lcd.print(totalRunningHours * 60, 2); // Convert totalRunningHours to minutes
} else {
lcd.setCursor(0, 0);
lcd.print("Time= Hr");
lcd.setCursor(5, 0);
lcd.print(totalRunningHours, 2); // Display totalRunningHours in hours
}
// Scroll the predefined message on the LCD
scrollMessage(1, scrollingMessage, 600, totalColumns);
// 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(1000);
// 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
// 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);
if (totalRunningHours < 1.0 / 60.0) {
lcd.setCursor(0, 1);
lcd.print("Time= sec");
lcd.setCursor(5, 1);
lcd.print(totalRunningHours * 3600, 2); // Convert totalRunningHours to seconds
} else if (totalRunningHours < 1.0) {
lcd.setCursor(0, 1);
lcd.print("Time= min");
lcd.setCursor(5, 1);
lcd.print(totalRunningHours * 60, 2); // Convert totalRunningHours to minutes
} else {
lcd.setCursor(0, 1);
lcd.print("Time= Hr");
lcd.setCursor(5, 1);
lcd.print(totalRunningHours, 2); // Display totalRunningHours in hours
}
// 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);
delay(1500);
digitalWrite(defrostRelay, HIGH);
// Display countdown during startup
for (int countdown = 30; countdown > 0; countdown--)
{
lcd.setCursor(5, 1);
lcd.print("" + String(countdown) + " min ");
delay(1000); //counddown speed
digitalWrite(compressorRelay, LOW);
//delay(2000);
}
startDefrostCycle();
lcd.clear();
// delay(1000);
lastDefrostTime = currentMillis;
}
// Perform cooling, defrost, or monitor temperature cycle actions
if (currentCycleState == COOLING)
{
performCoolingCycle();
}
else if (currentCycleState == DEFROST)
{
performDefrostCycle();
}
else if (currentCycleState == MONITOR_TEMP)
{
monitorFreezerTemperature();
}
// Print total running hours to serial monitor
Serial.print("Total Running Hours: ");
Serial.println(totalRunningHours);
// Print total running hours to LCD
if (totalRunningHours < 1.0 / 60.0) {
lcd.setCursor(0, 1);
lcd.print("Time= sec");
lcd.setCursor(5, 1);
lcd.print(totalRunningHours * 3600, 2); // Convert totalRunningHours to seconds, decimal points
} else if (totalRunningHours < 1.0) {
lcd.setCursor(0, 1);
lcd.print("Time= min");
lcd.setCursor(5, 1);
lcd.print(totalRunningHours * 60, 2); // Convert totalRunningHours to minutes, decimal points
} else {
lcd.setCursor(0, 1);
lcd.print("Time= Hr");
lcd.setCursor(5, 1);
lcd.print(totalRunningHours, 2); // Display totalRunningHours in hours,decimal points
}
delay(3000);
// Check if the freezer temperature is above (threshold, for more than interval)
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
void performCoolingCycle()
{
sensors1.requestTemperatures();
sensors2.requestTemperatures();
sensors3.requestTemperatures();
float freezer = sensors3.getTempCByIndex(0);
updateFreezerRelayState(freezer);
}
// Function to update the state of the freezer relay based on temperature
void updateFreezerRelayState(float freezerTemp)
{
if (freezerTemp >= 0 && freezerTemp >= monitorTempThreshold)
{
if (millis() - cycleStartTime >= secondsThreshold * 1000)
{
digitalWrite(compressorRelay, HIGH);
lcd.setCursor(0, 1);
lcd.print(" COMPRESSOR RUN ");
delay(5000);
lcd.setCursor(0, 1);
lcd.print("TEMPERATURE DROP");
delay(5000);
cycleStartTime = millis();
}
}
else
{
digitalWrite(compressorRelay, LOW);
currentCycleState = MONITOR_TEMP; // Set state to monitor temperature when below the threshold
}
}
// Function to start the defrost cycle
void startDefrostCycle()
{
digitalWrite(compressorRelay, 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 monitor freezer temperature and transition to cooling state
void monitorFreezerTemperature()
{
sensors1.requestTemperatures();
sensors2.requestTemperatures();
sensors3.requestTemperatures();
float freezer = sensors3.getTempCByIndex(0);
if (freezer >= 0 && (millis() - cycleStartTime >= secondsThreshold * 1000))
{
digitalWrite(compressorRelay, LOW);
currentCycleState = COOLING;
cycleStartTime = millis(); // Update cycle start time
}
}
// 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
ds18b20
Loading
ds18b20
ds18b20
Loading
ds18b20
ds18b20
freezer
fridge
room
cooling
(-10°C~0°C)
defrosting
(3sec/1min )
alarm
(>5°C)
(-55°C to +125°C)