#define BLYNK_TEMPLATE_ID "TMPL6lEP-ZNZ0"
#define BLYNK_DEVICE_NAME "Smart Home"
#define BLYNK_AUTH_TOKEN "SUREV-QvAOjmf-UtRqOUThlrwCKEsW9o"
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <DHT.h>
#include <NewPing.h>
// WiFi credentials
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// Auth Token untuk Blynk
char auth[] = SUREV-QvAOjmf-UtRqOUThlrwCKEsW9o;
// Pin definitions
#define DHT_PIN 4
#define DHT_TYPE DHT22
#define PIR_PIN 2
#define BUTTON_PIN 15
#define LED_PIN 12
#define PUMP_PIN 13
#define BUZZER_PIN 14
#define TRIGGER_PIN 5
#define ECHO_PIN 18
// Sensor objects
DHT dht(DHT_PIN, DHT_TYPE);
NewPing sonar(TRIGGER_PIN, ECHO_PIN, 300);
// Variables
float temperature = 0;
float humidity = 0;
int waterLevel = 0;
bool motionDetected = false;
bool ledState = false;
bool pumpState = false;
bool alarmState = false;
bool buttonPressed = false;
bool lastButtonState = false;
unsigned long lastMotionTime = 0;
unsigned long lastSensorRead = 0;
unsigned long lastBlynkUpdate = 0;
const unsigned long MOTION_TIMEOUT = 20000; // 20 seconds
const unsigned long SENSOR_INTERVAL = 2000; // 2 seconds
const unsigned long BLYNK_INTERVAL = 1000; // 1 second
// Blynk Virtual Pins
#define V_TEMP V0
#define V_HUMIDITY V1
#define V_WATER_LEVEL V2
#define V_MOTION V3
#define V_LED V4
#define V_PUMP V5
#define V_ALARM V6
#define V_LED_CONTROL V7
void setup() {
Serial.begin(115200);
// Initialize pins
pinMode(PIR_PIN, INPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
pinMode(PUMP_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
// Initialize sensors
dht.begin();
// Initialize Blynk
Blynk.begin(auth, ssid, pass);
Serial.println("Smart Home System Started");
}
void loop() {
Blynk.run();
unsigned long currentTime = millis();
// Read sensors every 2 seconds
if (currentTime - lastSensorRead >= SENSOR_INTERVAL) {
readSensors();
lastSensorRead = currentTime;
}
// Check button state
checkButton();
// Check motion and auto LED control
checkMotion(currentTime);
// Control pump based on water level
controlPump();
// Control alarm
controlAlarm();
// Update Blynk every second
if (currentTime - lastBlynkUpdate >= BLYNK_INTERVAL) {
updateBlynk();
lastBlynkUpdate = currentTime;
}
delay(100);
}
void readSensors() {
// Read DHT22
temperature = dht.readTemperature();
humidity = dht.readHumidity();
// Check if readings are valid
if (isnan(temperature) || isnan(humidity)) {
Serial.println("Failed to read from DHT sensor!");
temperature = 0;
humidity = 0;
}
// Read ultrasonic sensor for water level
unsigned int distance = sonar.ping_cm();
if (distance > 0) {
waterLevel = 300 - distance; // Assuming tank height is 300cm
if (waterLevel < 0) waterLevel = 0;
if (waterLevel > 300) waterLevel = 300;
}
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.print("°C, Humidity: ");
Serial.print(humidity);
Serial.print("%, Water Level: ");
Serial.print(waterLevel);
Serial.println("cm");
}
void checkButton() {
bool currentButtonState = !digitalRead(BUTTON_PIN);
if (currentButtonState && !lastButtonState) {
// Button pressed (rising edge)
ledState = !ledState;
digitalWrite(LED_PIN, ledState);
Serial.println("Button pressed - LED toggled");
}
lastButtonState = currentButtonState;
}
void checkMotion(unsigned long currentTime) {
bool currentMotion = digitalRead(PIR_PIN);
if (currentMotion) {
motionDetected = true;
lastMotionTime = currentTime;
Serial.println("Motion detected!");
} else {
motionDetected = false;
}
// Auto turn off LED if no motion for 20 seconds
if (ledState && (currentTime - lastMotionTime >= MOTION_TIMEOUT)) {
ledState = false;
digitalWrite(LED_PIN, ledState);
Serial.println("No motion for 20s - LED auto OFF");
}
}
void controlPump() {
bool newPumpState = pumpState;
if (waterLevel < 100) {
newPumpState = true;
} else if (waterLevel > 200) {
newPumpState = false;
}
// If between 100-200cm, pump state doesn't change
if (newPumpState != pumpState) {
pumpState = newPumpState;
digitalWrite(PUMP_PIN, pumpState);
Serial.print("Pump ");
Serial.println(pumpState ? "ON" : "OFF");
}
}
void controlAlarm() {
bool newAlarmState = (waterLevel > 200 && temperature > 30);
if (newAlarmState != alarmState) {
alarmState = newAlarmState;
if (alarmState) {
digitalWrite(BUZZER_PIN, HIGH);
Serial.println("ALARM ON - High water level and temperature!");
} else {
digitalWrite(BUZZER_PIN, LOW);
Serial.println("Alarm OFF");
}
}
}
void updateBlynk() {
Blynk.virtualWrite(V_TEMP, temperature);
Blynk.virtualWrite(V_HUMIDITY, humidity);
Blynk.virtualWrite(V_WATER_LEVEL, waterLevel);
Blynk.virtualWrite(V_MOTION, motionDetected ? 1 : 0);
Blynk.virtualWrite(V_LED, ledState ? 1 : 0);
Blynk.virtualWrite(V_PUMP, pumpState ? 1 : 0);
Blynk.virtualWrite(V_ALARM, alarmState ? 1 : 0);
}
// Blynk function to control LED from dashboard
BLYNK_WRITE(V_LED_CONTROL) {
int value = param.asInt();
if (value == 1) {
ledState = !ledState;
digitalWrite(LED_PIN, ledState);
Serial.println("LED toggled from Blynk");
}
}