#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
// 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
// DHT setup
#define DHTTYPE DHT11
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);
// Thresholds
const int temperatureThresholds[] = {80, 85, 95}; // Example thresholds, replace as needed
const int MQ2Threshold = 500;
// Variables
int currentPage = 1;
bool buzzerActive = false;
bool buzzerMQ2Active = false;
unsigned long buzzerStartTime = 0;
int currentThresholdIndex = 0;
// Function declarations
void updateDisplay(float temperature = NAN, float humidity = NAN, int mq2Value = -1);
void togglePage();
void manageBuzzer(float temperature, int mq2Value);
void scrollPresets();
bool detectSensor(int pin);
bool checkAndUpdate(float& cache, float newValue);
bool checkAndUpdate(int& cache, int newValue);
void setup() {
// Initialize the LCD
lcd.init(); // Initialize the LCD
lcd.backlight(); // Turn on the backlight
// Initialize the DHT sensor
dht.begin();
// Set pin modes
pinMode(MQ2PIN, INPUT);
pinMode(BUZZERPIN, OUTPUT);
pinMode(BUTTON1PIN, INPUT_PULLUP);
pinMode(BUTTON2PIN, INPUT_PULLUP);
pinMode(BUTTON3PIN, INPUT_PULLUP);
// Display initial page
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Welcome to your");
lcd.setCursor(0, 1);
lcd.print("Smart 3D Enclosure");
lcd.setCursor(0, 2);
lcd.print("v1.0.1");
delay(3000); // Show welcome message for 3 seconds
updateDisplay();
}
void loop() {
// Read button states
if (digitalRead(BUTTON1PIN) == LOW) {
delay(200); // Debounce delay
if (digitalRead(BUTTON1PIN) == LOW) {
tone(BUZZERPIN, 500); // Sound buzzer for 0.5 seconds
delay(500);
noTone(BUZZERPIN);
togglePage();
}
}
if (digitalRead(BUTTON2PIN) == LOW) {
delay(200); // Debounce delay
if (digitalRead(BUTTON2PIN) == LOW) {
tone(BUZZERPIN, 500); // Sound buzzer for 0.5 seconds
delay(500);
noTone(BUZZERPIN);
lcd.clear(); // Clear the display
}
}
if (digitalRead(BUTTON3PIN) == LOW) {
delay(200); // Debounce delay
if (digitalRead(BUTTON3PIN) == LOW) {
tone(BUZZERPIN, 500); // Sound buzzer for 0.5 seconds
delay(500);
noTone(BUZZERPIN);
scrollPresets(); // Scroll through presets
}
}
// Read sensors
float temperature = dht.readTemperature(true); // Temperature in Fahrenheit
float humidity = dht.readHumidity();
int mq2Value = analogRead(MQ2PIN);
// Update display based on button interactions
updateDisplay(temperature, humidity, mq2Value);
// Check thresholds and manage buzzer
manageBuzzer(temperature, mq2Value);
delay(500); // Update every 0.5 seconds
}
void togglePage() {
currentPage = (currentPage == 1) ? 2 : (currentPage == 2) ? 3 : 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();
if (temperature > temperatureThresholds[currentThresholdIndex]) {
if (!buzzerActive) {
buzzerActive = true;
buzzerStartTime = currentTime;
}
if (buzzerActive && (currentTime - buzzerStartTime >= 1000)) {
tone(BUZZERPIN, 1000); // 1 kHz frequency
delay(1000); // Buzzer on for 1 second
noTone(BUZZERPIN);
delay(4000); // Wait for 4 seconds
buzzerStartTime = millis(); // Reset buzzer start time
}
} else {
noTone(BUZZERPIN);
buzzerActive = false;
}
if (mq2Value > MQ2Threshold) {
if (!buzzerMQ2Active) {
buzzerMQ2Active = true;
buzzerStartTime = currentTime;
}
if (buzzerMQ2Active && (currentTime - buzzerStartTime >= 1500)) {
tone(BUZZERPIN, 1000); // 1 kHz frequency
delay(1500); // Buzzer on for 1.5 seconds
noTone(BUZZERPIN);
delay(3500); // Wait for 3.5 seconds
buzzerStartTime = millis(); // Reset buzzer start time
}
} else {
noTone(BUZZERPIN);
buzzerMQ2Active = false;
}
}
void updateDisplay(float temperature, float humidity, int mq2Value) {
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 Value: ");
if (mq2Value == -1) {
lcd.print("NA");
} else {
lcd.print(mq2Value);
lcd.print(" ");
}
lcd.setCursor(0, 3);
lcd.print("Page 1");
} else if (currentPage == 2) {
lcd.setCursor(0, 0);
lcd.print("Page 2");
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 ");
}
} else if (currentPage == 3) {
lcd.setCursor(0, 0);
lcd.print("Uptime: ");
long uptime = millis() / 1000;
long hours = uptime / 3600;
long minutes = (uptime % 3600) / 60;
long seconds = uptime % 60;
lcd.print(hours);
lcd.print("h ");
lcd.print(minutes);
lcd.print("m ");
lcd.print(seconds);
lcd.print("s");
lcd.setCursor(0, 1);
lcd.print("Version: 1.2.1");
lcd.setCursor(0, 3);
lcd.print("Page 3");
}
}
void scrollPresets() {
currentThresholdIndex = (currentThresholdIndex + 1) % (sizeof(temperatureThresholds) / sizeof(temperatureThresholds[0]));
updateDisplay();
}
bool detectSensor(int pin) {
return digitalRead(pin) != LOW; // Adjust according to your sensor's logic
}
bool checkAndUpdate(float& cache, float newValue) {
if (cache != newValue) {
cache = newValue;
return true;
}
return false;
}
bool checkAndUpdate(int& cache, int newValue) {
if (cache != newValue) {
cache = newValue;
return true;
}
return false;
}