#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
// Pin Definitions
#define DHTPIN 8
#define FAN_PIN_1 6
#define FAN_PIN_2 9
#define MQ_SENSOR_PIN A0 // Analog pin for the MQ sensor
#define UP_PIN 12
#define DOWN_PIN 11 // Changed DOWN_PIN to 11 to avoid conflict with FAN_PIN_1
#define ENTER_PIN 13
// DHT Sensor Type
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// LCD Configuration
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Global Variables
int currentPage = 0;
int humiditySetPoint = 62;
int autoFlushIntervalOption = 1; // Default auto flush interval option (12 hours)
int autoFlushTime = 5; // Default auto flush time
bool fansOn = false;
unsigned long fanOnTime = 0;
const unsigned long fanInterval = 300000; // 5 minutes
unsigned long systemStartTime = 0; // Track the time when the system started
unsigned long lastUpdate = 0; // Track the time of the last update
bool upPressed = false;
bool downPressed = false;
bool enterPressed = false;
bool needScreenRefresh = true;
// Debounce Variables
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50; // debounce delay in milliseconds
void updateFanStatus(float humidity); // Declaration of updateFanStatus function
void setup() {
Serial.begin(9600);
dht.begin();
lcd.init();
lcd.backlight();
// Initialize Button Pins
pinMode(UP_PIN, INPUT_PULLUP);
pinMode(DOWN_PIN, INPUT_PULLUP);
pinMode(ENTER_PIN, INPUT_PULLUP);
// Initialize Fan Pins
pinMode(FAN_PIN_1, OUTPUT);
pinMode(FAN_PIN_2, OUTPUT);
digitalWrite(FAN_PIN_1, LOW);
digitalWrite(FAN_PIN_2, LOW);
systemStartTime = millis();
lastUpdate = millis(); // Initialize last update time
// Display Initial Screen
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" ------------------");
lcd.setCursor(0, 1);
lcd.print("| CureOs |");
lcd.setCursor(0, 2);
lcd.print("| v1.5 |");
lcd.setCursor(0, 3);
lcd.print(" ------------------ ");
delay(1500); // Wait for 1.5 seconds
lcd.clear();
}
void loop() {
unsigned long currentMillis = millis();
// Update the display values every second if on the home page
if (currentPage == 0 && currentMillis - lastUpdate >= 1000) {
lastUpdate = currentMillis;
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
int co2Level = analogRead(MQ_SENSOR_PIN);
// Display updated values on the home page
lcd.setCursor(10, 0);
lcd.print(humidity, 1); // Display humidity with 1 decimal point
lcd.print("%");
lcd.setCursor(6, 1);
lcd.print(temperature, 1); // Display temperature with 1 decimal point
lcd.print("c");
lcd.setCursor(5, 2);
lcd.print(co2Level); // Display CO2 level
lcd.print(" ppm");
}
handleButtonPresses();
float humidity = dht.readHumidity();
updateFanStatus(humidity); // Update the status of fans based on humidity
unsigned long elapsedTime = currentMillis - systemStartTime;
unsigned long interval = autoFlushIntervalOption * 12 * 3600UL * 1000UL; // Convert hours to milliseconds
if (elapsedTime >= interval && !fansOn) {
digitalWrite(FAN_PIN_1, HIGH);
digitalWrite(FAN_PIN_2, HIGH);
fansOn = true;
fanOnTime = currentMillis; // Record the time when fans turned on
}
if (fansOn && (currentMillis - fanOnTime >= autoFlushTime * 60000)) {
digitalWrite(FAN_PIN_1, LOW);
digitalWrite(FAN_PIN_2, LOW);
fansOn = false;
systemStartTime = currentMillis; // Reset the system start time for the next interval
}
if (needScreenRefresh) {
if (currentPage == 0) { // Only display home page if not in menu
displayHomePage();
} else {
displayMenuPage();
}
needScreenRefresh = false;
}
}
void handleButtonPresses() {
unsigned long currentMillis = millis();
if ((currentMillis - lastDebounceTime) > debounceDelay) {
if (digitalRead(UP_PIN) == LOW && !upPressed) {
upPressed = true;
handleUpButton();
needScreenRefresh = true;
lastDebounceTime = currentMillis;
} else if (digitalRead(UP_PIN) == HIGH && upPressed) {
upPressed = false;
}
if (digitalRead(DOWN_PIN) == LOW && !downPressed) {
downPressed = true;
handleDownButton();
needScreenRefresh = true;
lastDebounceTime = currentMillis;
} else if (digitalRead(DOWN_PIN) == HIGH && downPressed) {
downPressed = false;
}
if (digitalRead(ENTER_PIN) == LOW && !enterPressed) {
enterPressed = true;
handleEnterButton();
needScreenRefresh = true;
lastDebounceTime = currentMillis;
} else if (digitalRead(ENTER_PIN) == HIGH && enterPressed) {
enterPressed = false;
}
}
}
void handleUpButton() {
switch (currentPage) {
case 1:
humiditySetPoint++;
if (humiditySetPoint > 90) humiditySetPoint = 90; // Adjusted maximum humidity set point to 90%
break;
case 2:
autoFlushIntervalOption++;
if (autoFlushIntervalOption > 3) autoFlushIntervalOption = 3; // Maximum option is 36 hours
break;
case 3:
autoFlushTime += 5; // Increment flush time by 5 minutes
if (autoFlushTime > 15) autoFlushTime = 15;
break;
}
}
void handleDownButton() {
switch (currentPage) {
case 1:
humiditySetPoint--;
if (humiditySetPoint < 55) humiditySetPoint = 55;
break;
case 2:
autoFlushIntervalOption--;
if (autoFlushIntervalOption < 1) autoFlushIntervalOption = 1; // Minimum option is 12 hours
break;
case 3:
autoFlushTime -= 5; // Decrement flush time by 5 minutes
if (autoFlushTime < 1) autoFlushTime = 1;
break;
}
}
void handleEnterButton() {
static bool menuCycled = true; // Track if the menu has cycled at least once
if (currentPage < 3) { // Change 3 to the total number of menu pages
currentPage++;
}
else {
if (menuCycled) {
currentPage = 0; // Return to home page after cycling through the menu
} else {
currentPage = 1; // Start from the first menu page
menuCycled = true; // Mark that the menu has cycled at least once
}
}
}
void displayHomePage() {
lcd.setCursor(0, 0);
lcd.print("Humidity: ");
lcd.setCursor(10, 0);
lcd.print(dht.readHumidity(), 1); // Display humidity with 1 decimal point
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print("Temp: ");
lcd.setCursor(6, 1);
lcd.print(dht.readTemperature(), 1); // Display temperature with 1 decimal point
lcd.print("c");
lcd.setCursor(0, 2);
lcd.print("CO2: ");
lcd.setCursor(5, 2);
lcd.print(analogRead(MQ_SENSOR_PIN)); // Read CO2 level from MQ sensor
lcd.print(" ppm");
lcd.setCursor(0, 3);
if (fansOn) {
lcd.print("*FANS ON*");
} else {
lcd.print(" "); // Clear the line if fans are off
}
}
void displayMenuPage() {
if (currentPage != 0) {
lcd.clear();
lcd.setCursor(0, 0);
switch (currentPage) {
case 1:
lcd.print("Humidity Set Point");
lcd.setCursor(0, 2);
lcd.print("- ");
lcd.print(humiditySetPoint);
lcd.print("%");
break;
case 2:
lcd.print("Auto Flush Interval");
lcd.setCursor(0, 2);
lcd.print("- ");
lcd.print(autoFlushIntervalOption * 12);
lcd.print(" hrs");
break;
case 3:
lcd.print("Auto Flush Time");
lcd.setCursor(0, 2);
lcd.print("- ");
lcd.print(autoFlushTime);
lcd.print(" mins");
break;
}
}
}
void updateFanStatus(float humidity) {
// Calculate the humidity thresholds for turning the fans on and off
float humidityOnThreshold = humiditySetPoint;
float humidityOffThreshold = humiditySetPoint - 3; // 3% below the set point
// Check if humidity is above the ON threshold
if (humidity >= humidityOnThreshold) {
digitalWrite(FAN_PIN_1, HIGH);
digitalWrite(FAN_PIN_2, HIGH);
fansOn = true;
}
// Check if humidity is below the OFF threshold and fans are currently on
else if (humidity < humidityOffThreshold && fansOn) {
digitalWrite(FAN_PIN_1, LOW);
digitalWrite(FAN_PIN_2, LOW);
fansOn = false;
}
// If humidity is between the ON and OFF thresholds or above the OFF threshold but fans are already off, do nothing
}