#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// ================== PIN DEFINITIONS ==================
#define DHTPIN 13
#define DHTTYPE DHT22
#define TRIG_PIN 12 // Ultrasonic Trigger
#define ECHO_PIN 14 // Ultrasonic Echo
#define RELAY_PIN 19 // Relay
#define BUZZER_PIN 27 // Buzzer
#define LDR_PIN 15 // LDR
// ================== THRESHOLDS ==================
#define TEMP_HIGH 30.0
#define TEMP_LOW 25.0
#define HUM_LOW 50.0
#define HUM_HIGH 60.0
#define DIST_MAX 20.0 // Buzzer if distance > 20 cm
#define LUX_THRESHOLD 100
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Function to make different beeps
void beep(int times, int delayTime = 150) {
for(int i = 0; i < times; i++) {
digitalWrite(BUZZER_PIN, HIGH);
delay(delayTime);
digitalWrite(BUZZER_PIN, LOW);
delay(delayTime);
}
}
float getLux() {
int raw = analogRead(LDR_PIN);
float voltage = raw * (3.3 / 4095.0);
if (voltage < 0.1) return 0;
float ldrResistance = (10.0 * (3.3 - voltage)) / voltage;
float lux = 100000.0 / (ldrResistance * 10.0);
return lux;
}
void setup() {
Serial.begin(115200);
dht.begin();
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(RELAY_PIN, HIGH); // Relay OFF
digitalWrite(BUZZER_PIN, LOW);
lcd.init();
lcd.backlight();
lcd.clear();
lcd.print("Distance Updated");
lcd.setCursor(0,1);
lcd.print("Ready...");
delay(2000);
lcd.clear();
}
void loop() {
float h = dht.readHumidity();
float t = dht.readTemperature();
// Read Ultrasonic Distance
digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
float distance = pulseIn(ECHO_PIN, HIGH) * 0.034 / 2.0;
float lux = getLux();
if (isnan(h) || isnan(t)) {
lcd.clear();
lcd.print("DHT22 Error!");
delay(1000);
return;
}
// ================== LCD DISPLAY ==================
lcd.clear();
lcd.setCursor(0,0);
lcd.print("T:");
lcd.print(t,1);
lcd.print(" H:");
lcd.print(h,1);
lcd.print("%");
lcd.setCursor(0,1);
lcd.print("D:");
lcd.print(distance,0);
lcd.print("cm L:");
lcd.print(lux,0);
Serial.printf("Temp: %.1f°C | Hum: %.1f%% | Dist: %.0fcm | Lux: %.0f\n", t, h, distance, lux);
// ================== BUZZER CONDITIONS ==================
// Temperature too hot or too cold
if (t > TEMP_HIGH || t < TEMP_LOW) {
Serial.print("→ Buzzer: Temp out of range (");
Serial.print(t,1);
Serial.println("°C)");
beep(1, 250); // Single long beep for temperature
}
// Humidity too low or too high
else if (h < HUM_LOW || h > HUM_HIGH) {
Serial.print("→ Buzzer: Humidity out of range (");
Serial.print(h,1);
Serial.println("%)");
beep(2, 150); // Double beep for humidity
}
// ================== DISTANCE CONDITION (Updated) ==================
else if (distance > DIST_MAX) {
Serial.print("→ Buzzer: Distance > 20cm (");
Serial.print(distance,0);
Serial.println(" cm)");
beep(3, 100); // Triple short beep for distance
}
// If none of the above conditions are true → Buzzer OFF
else {
digitalWrite(BUZZER_PIN, LOW);
}
// ================== RELAY (LDR) ==================
if (lux < LUX_THRESHOLD) {
digitalWrite(RELAY_PIN, LOW); // Relay ON when dark
Serial.println("→ Relay ON: Low Light (Lux < 100)");
} else {
digitalWrite(RELAY_PIN, HIGH); // Relay OFF
}
delay(1000);
}