#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <Encoder.h>
#include <Servo.h>
// LCD setup
LiquidCrystal_I2C lcd(0x27, 20, 4);
// DHT Sensor setup (using DHT22)
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// Rotary Encoder Pins
#define ENCODER_CLK 5
#define ENCODER_DT 6
#define ENCODER_SW 7
// Sensor Pins
const int mq2Pin = A0;
const int dcMotorPin = 9; // DC motor control pin (PWM)
// Button Pins
const int button1 = 3; // Page switch button
const int button2 = 4; // Refresh/clear button
int currentPage = 1;
bool buzzerMuted = false;
unsigned long lastChangeTime = 0;
unsigned long debounceDelay = 250; // Time between page changes (in milliseconds)
unsigned long lastUpdateTime = 0; // Tracks last update time for auto-refresh
const unsigned long updateInterval = 2000; // Refresh interval (2 seconds)
// Temperature Thresholds (Preset values)
float temperatureThresholds[] = {75.0, 80.0, 85.0, 90.0}; // Thresholds for fan to activate
int currentThresholdIndex = 0;
// MQ2 Threshold Presets (Low, Medium, High)
int mq2Thresholds[] = {200, 400, 600}; // Adjust these based on your sensor's output range
int currentMq2ThresholdIndex = 0;
// Create Encoder instance
Encoder enc(ENCODER_CLK, ENCODER_DT);
// DC motor speed control
int motorSpeed = 0; // Motor speed from 0 to 255
void setup() {
lcd.init();
lcd.backlight();
pinMode(mq2Pin, INPUT);
pinMode(dcMotorPin, OUTPUT);
pinMode(button1, INPUT_PULLUP);
pinMode(button2, INPUT_PULLUP);
pinMode(ENCODER_SW, INPUT_PULLUP); // SW button for Rotary Encoder
dht.begin();
}
void loop() {
unsigned long currentMillis = millis();
// Read temperature, humidity, and MQ2 sensor values
float temperature = dht.readTemperature(true);
float humidity = dht.readHumidity();
int mq2Value = analogRead(mq2Pin);
// Handle button presses for page navigation
if (digitalRead(button1) == LOW) {
currentPage++;
if (currentPage > 4) currentPage = 1;
delay(200); // Debounce delay
}
// Manual refresh with Button 2
if (digitalRead(button2) == LOW) {
lcd.clear(); // Clear the display for manual refresh
updateDisplay(temperature, humidity, mq2Value); // Force update
delay(200); // Debounce delay
}
// Read rotary encoder values for controlling parameters
long newPosition = enc.read();
if (newPosition != 0 && (currentMillis - lastChangeTime >= debounceDelay)) {
if (currentPage == 2) {
// Adjust temperature threshold
currentThresholdIndex += (newPosition > 0) ? 1 : -1;
if (currentThresholdIndex > 3) currentThresholdIndex = 0;
if (currentThresholdIndex < 0) currentThresholdIndex = 3;
} else if (currentPage == 3) {
// Adjust MQ2 threshold
currentMq2ThresholdIndex += (newPosition > 0) ? 1 : -1;
if (currentMq2ThresholdIndex > 2) currentMq2ThresholdIndex = 0;
if (currentMq2ThresholdIndex < 0) currentMq2ThresholdIndex = 2;
} else if (currentPage == 4) {
// Control DC motor speed
motorSpeed += (newPosition > 0) ? 10 : -10;
if (motorSpeed > 255) motorSpeed = 255;
if (motorSpeed < 0) motorSpeed = 0;
}
enc.write(0); // Reset encoder position after change
lastChangeTime = currentMillis; // Update last change time
}
// **Automatic display refresh every 2 seconds**
if (currentMillis - lastUpdateTime >= updateInterval) {
updateDisplay(temperature, humidity, mq2Value);
lastUpdateTime = currentMillis; // Reset update timer
}
// Control fan based on temperature
if (temperature > temperatureThresholds[currentThresholdIndex]) {
analogWrite(dcMotorPin, motorSpeed);
} else {
analogWrite(dcMotorPin, 0);
}
}
void updateDisplay(float temperature, float humidity, int mq2Value) {
static int previousPage = -1;
if (currentPage != previousPage) {
lcd.clear();
previousPage = currentPage;
}
lcd.setCursor(0, 3);
lcd.print("Page ");
lcd.print(currentPage);
// Page 1: Sensor Data
if (currentPage == 1) {
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(isnan(temperature) ? "NA" : String(temperature) + " F");
lcd.setCursor(0, 1);
lcd.print("Hum: ");
lcd.print(isnan(humidity) ? "NA" : String(humidity) + " %");
lcd.setCursor(0, 2);
lcd.print("MQ2 Value: ");
lcd.print(mq2Value);
}
// Page 2: Uptime & Threshold
else if (currentPage == 2) {
unsigned long uptimeSeconds = millis() / 1000;
unsigned long uptimeMinutes = uptimeSeconds / 60;
unsigned long uptimeHours = uptimeMinutes / 60;
lcd.setCursor(0, 0);
lcd.print("Uptime: ");
lcd.print(uptimeHours);
lcd.print("h ");
lcd.print(uptimeMinutes % 60);
lcd.print("m ");
lcd.print(uptimeSeconds % 60);
lcd.print("s");
lcd.setCursor(0, 1);
lcd.print("Preset Temp: ");
lcd.print(temperatureThresholds[currentThresholdIndex]);
lcd.setCursor(0, 2);
lcd.print("Temp: ");
lcd.print(isnan(temperature) ? "NA" : String(temperature) + " F");
}
// Page 3: Buzzer control and MQ2 threshold
else if (currentPage == 3) {
lcd.setCursor(0, 0);
lcd.print("Buzzer: ");
lcd.print(buzzerMuted ? "Muted" : "Active");
lcd.setCursor(0, 1);
lcd.print("MQ2 Threshold: ");
lcd.print(mq2Thresholds[currentMq2ThresholdIndex]);
if (mq2Value > mq2Thresholds[currentMq2ThresholdIndex] && !buzzerMuted) {
// Activate buzzer (add your buzzer control logic here)
}
}
// Page 4: DC Motor Speed Control
else if (currentPage == 4) {
lcd.setCursor(0, 0);
lcd.print("DC Motor Speed:");
lcd.setCursor(0, 1);
lcd.print(motorSpeed);
}
}