#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <RTClib.h> // Include the RTClib library for DS1307
// Pin configuration
#define DHTPIN 2
#define MQ2PIN A1 // Analog pin for MQ2 sensor
#define BUZZERPIN 3
#define BUTTON1PIN 4
#define BUTTON2PIN 5
#define BUTTON3PIN 6
#define BUTTON4PIN 7 // Mute button
// DHT setup
#define DHTTYPE DHT22 // Change to DHT22
DHT dht(DHTPIN, DHTTYPE);
// LCD setup
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
// RTC setup
RTC_DS1307 rtc; // Initialize the DS1307 RTC
// Thresholds
const int temperatureThresholds[] = {85, 95, 90, 87}; // Example thresholds, replace as needed
const int MQ2Threshold = 800; // Set MQ2 threshold for fire detection
// Variables
int currentPage = 1;
bool buzzerActive = false;
bool buzzerMQ2Active = false;
bool buzzerMuted = false;
unsigned long buzzerStartTime = 0;
int currentThresholdIndex = 0;
unsigned long lastButtonPress = 0;
const unsigned long debounceDelay = 300;
unsigned long lastDHTRead = 0;
const unsigned long DHTReadInterval = 500;
// Function declarations
void updateDisplay(float temperature = NAN, float humidity = NAN, int mq2Value = -1);
void togglePage();
void manageBuzzer(float temperature, int mq2Value);
void scrollPresets();
void muteBuzzer();
void printDateTime();
// Initialize setup()
void setup() {
lcd.init(); // Initialize the LCD
lcd.backlight(); // Turn on the backlight
dht.begin(); // Initialize the DHT sensor
rtc.begin(); // Initialize the RTC
if (!rtc.isrunning()) {
rtc.adjust(DateTime(2023, 10, 13, 0, 0, 0)); // Set the RTC to the current date and time if not running
}
pinMode(MQ2PIN, INPUT);
pinMode(BUZZERPIN, OUTPUT);
pinMode(BUTTON1PIN, INPUT_PULLUP);
pinMode(BUTTON2PIN, INPUT_PULLUP);
pinMode(BUTTON3PIN, INPUT_PULLUP);
pinMode(BUTTON4PIN, INPUT_PULLUP);
lcd.setCursor(0, 0);
lcd.print("Welcome to your");
lcd.setCursor(0, 1);
lcd.print("Smart 3D Enclosure");
lcd.setCursor(0, 2);
lcd.print("Version 4.1.0");
delay(5000); // Display for 5 seconds
lcd.clear();
updateDisplay(); // Display initial page
}
void loop() {
unsigned long currentMillis = millis();
if (digitalRead(BUTTON1PIN) == LOW && (currentMillis - lastButtonPress) > debounceDelay) {
lastButtonPress = currentMillis;
togglePage();
}
if (digitalRead(BUTTON2PIN) == LOW && (currentMillis - lastButtonPress) > debounceDelay) {
lastButtonPress = currentMillis;
lcd.clear();
}
if (digitalRead(BUTTON3PIN) == LOW && (currentMillis - lastButtonPress) > debounceDelay) {
lastButtonPress = currentMillis;
scrollPresets();
}
if (digitalRead(BUTTON4PIN) == LOW && (currentMillis - lastButtonPress) > debounceDelay) {
lastButtonPress = currentMillis;
muteBuzzer();
}
if (currentMillis - lastDHTRead >= DHTReadInterval) {
lastDHTRead = currentMillis;
float temperature = dht.readTemperature(true);
float humidity = dht.readHumidity();
int mq2Value = analogRead(MQ2PIN);
manageBuzzer(temperature, mq2Value); // Manage buzzer for fire alarm
updateDisplay(temperature, humidity, mq2Value);
}
delay(100); // Short delay for stability
}
void togglePage() {
currentPage = (currentPage == 1) ? 2 : (currentPage == 2) ? 3 : (currentPage == 3) ? 4 : 1;
lcd.clear(); // Clear the display to avoid overlapping content
updateDisplay(); // Update display based on the new page
}
void manageBuzzer(float temperature, int mq2Value) {
unsigned long currentTime = millis();
// Fire alarm conditions
if (temperature >= 121.0 && mq2Value >= MQ2Threshold) {
// Clear the display and show fire alert
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("FIRE ALERT!");
lcd.setCursor(0, 1);
lcd.print("Evacuate Now!");
// Buzzer logic for fire alert
if (!buzzerMuted) {
tone(BUZZERPIN, 1000); // Turn on buzzer
delay(1000); // Buzz for 1 second
noTone(BUZZERPIN); // Turn off buzzer
delay(500); // Wait for half a second
}
} else {
if (!buzzerMuted) {
noTone(BUZZERPIN); // Turn off buzzer if not in fire state
}
}
}
void updateDisplay(float temperature, float humidity, int mq2Value) {
DateTime now = rtc.now();
if (currentPage == 1) {
lcd.setCursor(0, 0);
lcd.print("Temp: ");
if (isnan(temperature)) {
lcd.print("NA");
} else {
lcd.print(temperature);
lcd.print(" F");
}
lcd.setCursor(0, 1);
lcd.print("Hum: ");
if (isnan(humidity)) {
lcd.print("NA");
} else {
lcd.print(humidity);
lcd.print(" %");
}
lcd.setCursor(0, 2);
lcd.print("MQ2: ");
if (mq2Value < 0) {
lcd.print("NA");
} else {
lcd.print(mq2Value);
}
lcd.setCursor(0, 3);
printDateTime(); // Print date and time
}
else if (currentPage == 2) {
unsigned long uptimeMillis = millis();
unsigned long uptimeSeconds = uptimeMillis / 1000;
unsigned long uptimeMinutes = uptimeSeconds / 60;
unsigned long uptimeHours = uptimeMinutes / 60;
unsigned long seconds = uptimeSeconds % 60;
unsigned long minutes = uptimeMinutes % 60;
unsigned long hours = uptimeHours;
lcd.setCursor(0, 0);
lcd.print("Uptime: ");
lcd.print(hours);
lcd.print("h ");
lcd.print(minutes);
lcd.print("m ");
lcd.print(seconds);
lcd.print("s");
lcd.setCursor(0, 1);
lcd.print("Preset Temp: ");
lcd.print(temperatureThresholds[currentThresholdIndex]);
lcd.setCursor(0, 2);
lcd.print("Temp: ");
if (isnan(temperature)) {
lcd.print("NA");
} else {
lcd.print(temperature);
lcd.print(" F");
}
lcd.setCursor(0, 3);
lcd.print("Page 2");
}
else if (currentPage == 3) {
lcd.setCursor(0, 0);
lcd.print("Made by Diego R");
lcd.setCursor(0, 1);
lcd.print("Jimenez");
lcd.setCursor(0, 2);
lcd.print("Buzzer: ");
lcd.print(buzzerMuted ? "Muted" : "Active");
lcd.setCursor(0, 3);
lcd.print("Page 3");
}
else if (currentPage == 4) {
lcd.setCursor(0, 0);
lcd.print("Date: ");
printDateTime(now);
lcd.setCursor(0, 1);
lcd.print("Time: ");
lcd.print(now.Hour());
lcd.print(":");
if (now.Minute() < 10) lcd.print("0");
lcd.print(now.Minute());
lcd.setCursor(0, 2);
lcd.print("v 4.1.0");
lcd.setCursor(0, 3);
lcd.print("Page 4");
}
}
// Print date and time on the LCD
void printDateTime() {
DateTime now = rtc.now();
lcd.print(now.year(), DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.day(), DEC);
lcd.print(' ');
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
}
// Scroll through preset values
void scrollPresets() {
currentThresholdIndex = (currentThresholdIndex + 1) % (sizeof(temperatureThresholds) / sizeof(temperatureThresholds[0]));
lcd.clear();
lcd.print("Current Threshold: ");
lcd.print(temperatureThresholds[currentThresholdIndex]);
}
// Mute the buzzer
void muteBuzzer() {
buzzerMuted = !buzzerMuted; // Toggle mute state
if (buzzerMuted) {
lcd.setCursor(0, 0);
lcd.print("Buzzer Muted ");
} else {
lcd.setCursor(0, 0);
lcd.print("Buzzer Unmuted ");
}
}