#define BLYNK_TEMPLATE_ID "TMPL6lEP-ZNZ0"
#define BLYNK_TEMPLATE_NAME "Smart Home""
#define BLYNK_AUTH_TOKEN "SUREV-QvAOjmf-UtRqOUThlrwCKEsW9o"
#define BLYNK_PRINT Serial
#include <WiFi.h>
>
// WiFi credentials (gunakan Wokwi-GUEST untuk simulator)
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// Pin definitions untuk Wokwi
#define DHT_PIN 4
#define PIR_PIN 2
#define BUTTON_PIN 15
#define LAMP_PIN 5
#define PUMP_PIN 18
#define BEEPER_PIN 19
#define TRIG_PIN 12
#define ECHO_PIN 13
#define LED_MOTION 25
#define LED_LAMP 26
#define LED_PUMP 27
#define LED_BEEPER 14
// Virtual pins Blynk
#define V_TEMP 0
#define V_HUMIDITY 1
#define V_WATER_LEVEL 2
#define V_MOTION 3
#define V_LAMP 4
#define V_PUMP 5
#define V_BEEPER 6
// Variables
bool lampState = false;
bool pumpState = false;
bool beeperState = false;
bool motionDetected = false;
bool lastButtonState = false;
unsigned long lastMotionTime = 0;
unsigned long lastSensorRead = 0;
float temperature = 25.0; // Simulasi suhu
float humidity = 60.0; // Simulasi kelembaban
float waterLevel = 150.0; // Simulasi level air
const unsigned long MOTION_TIMEOUT = 20000; // 20 detik
const unsigned long SENSOR_INTERVAL = 2000; // 2 detik
BlynkTimer timer;
// Fungsi simulasi sensor DHT
void readDHTSensor() {
// Simulasi pembacaan sensor dengan variasi random
temperature = 25.0 + random(-50, 150) / 10.0; // 20-40°C
humidity = 60.0 + random(-200, 200) / 10.0; // 40-80%
// Batasi nilai dalam range normal
if (temperature < 15.0) temperature = 15.0;
if (temperature > 45.0) temperature = 45.0;
if (humidity < 30.0) humidity = 30.0;
if (humidity > 90.0) humidity = 90.0;
}
// Fungsi simulasi sensor ultrasonik
void readWaterLevel() {
// Simulasi level air yang berubah secara gradual
static float targetLevel = 150.0;
static unsigned long lastChange = 0;
if (millis() - lastChange > 10000) { // Ubah target setiap 10 detik
targetLevel = random(50, 250);
lastChange = millis();
}
// Gradual change towards target
if (waterLevel < targetLevel) {
waterLevel += 2.0;
} else if (waterLevel > targetLevel) {
waterLevel -= 2.0;
}
// Simulasi efek pompa
if (pumpState) {
waterLevel += 1.5; // Pompa menambah air
}
}
void setup() {
Serial.begin(115200);
// Initialize pins
pinMode(PIR_PIN, INPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LAMP_PIN, OUTPUT);
pinMode(PUMP_PIN, OUTPUT);
pinMode(BEEPER_PIN, OUTPUT);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
// LED indicators
pinMode(LED_MOTION, OUTPUT);
pinMode(LED_LAMP, OUTPUT);
pinMode(LED_PUMP, OUTPUT);
pinMode(LED_BEEPER, OUTPUT);
// Connect to Blynk
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// Set timers
timer.setInterval(SENSOR_INTERVAL, readSensors);
timer.setInterval(1000L, updateBlynk);
timer.setInterval(100L, checkButton);
timer.setInterval(100L, checkMotion);
timer.setInterval(1000L, controlSystems);
timer.setInterval(500L, updateLEDs);
Serial.println("=== SMART HOME SYSTEM STARTED ===");
Serial.println("Wokwi Simulator Ready!");
}
void loop() {
Blynk.run();
timer.run();
}
void readSensors() {
readDHTSensor();
readWaterLevel();
Serial.println("=== SENSOR READINGS ===");
Serial.printf("Temperature: %.1f°C\n", temperature);
Serial.printf("Humidity: %.1f%%\n", humidity);
Serial.printf("Water Level: %.1fcm\n", waterLevel);
Serial.printf("Motion: %s\n", motionDetected ? "DETECTED" : "NO MOTION");
Serial.println("========================");
}
void updateBlynk() {
// Update sensor values
Blynk.virtualWrite(V_TEMP, temperature);
Blynk.virtualWrite(V_HUMIDITY, humidity);
Blynk.virtualWrite(V_WATER_LEVEL, waterLevel);
// Update status
Blynk.virtualWrite(V_MOTION, motionDetected ? 1 : 0);
Blynk.virtualWrite(V_LAMP, lampState ? 1 : 0);
Blynk.virtualWrite(V_PUMP, pumpState ? 1 : 0);
Blynk.virtualWrite(V_BEEPER, beeperState ? 1 : 0);
}
void checkButton() {
bool currentButtonState = !digitalRead(BUTTON_PIN);
if (currentButtonState && !lastButtonState) {
// Button pressed - toggle lamp
lampState = !lampState;
digitalWrite(LAMP_PIN, lampState ? HIGH : LOW);
lastMotionTime = millis(); // Reset motion timer
Serial.println("=== BUTTON PRESSED ===");
Serial.printf("Lamp: %s\n", lampState ? "ON" : "OFF");
Serial.println("====================");
}
lastButtonState = currentButtonState;
}
void checkMotion() {
bool currentMotion = digitalRead(PIR_PIN);
if (currentMotion && !motionDetected) {
motionDetected = true;
lastMotionTime = millis();
if (!lampState) {
lampState = true;
digitalWrite(LAMP_PIN, HIGH);
Serial.println("=== MOTION DETECTED ===");
Serial.println("Lamp: ON (Auto)");
Serial.println("====================");
}
} else if (!currentMotion) {
motionDetected = false;
}
// Auto turn off lamp after 20 seconds of no motion
if (lampState && !currentMotion && (millis() - lastMotionTime > MOTION_TIMEOUT)) {
lampState = false;
digitalWrite(LAMP_PIN, LOW);
Serial.println("=== AUTO LAMP OFF ===");
Serial.println("No motion for 20 seconds");
Serial.println("===================");
}
}
void controlSystems() {
// Water pump control dengan hysteresis
bool newPumpState = pumpState;
if (waterLevel < 100) {
newPumpState = true;
} else if (waterLevel > 200) {
newPumpState = false;
}
if (newPumpState != pumpState) {
pumpState = newPumpState;
digitalWrite(PUMP_PIN, pumpState ? HIGH : LOW);
Serial.println("=== PUMP CONTROL ===");
Serial.printf("Water Level: %.1fcm\n", waterLevel);
Serial.printf("Pump: %s\n", pumpState ? "ON" : "OFF");
Serial.println("==================");
}
// Beeper/Alarm control
bool newBeeperState = (waterLevel > 200 && temperature > 30);
if (newBeeperState != beeperState) {
beeperState = newBeeperState;
digitalWrite(BEEPER_PIN, beeperState ? HIGH : LOW);
if (beeperState) {
Serial.println("=== ALARM ACTIVATED ===");
Serial.printf("Water Level: %.1fcm (>200)\n", waterLevel);
Serial.printf("Temperature: %.1f°C (>30)\n", temperature);
Serial.println("====================");
} else {
Serial.println("=== ALARM DEACTIVATED ===");
Serial.println("=======================");
}
}
}
void updateLEDs() {
// Update LED indicators
digitalWrite(LED_MOTION, motionDetected ? HIGH : LOW);
digitalWrite(LED_LAMP, lampState ? HIGH : LOW);
digitalWrite(LED_PUMP, pumpState ? HIGH : LOW);
digitalWrite(LED_BEEPER, beeperState ? HIGH : LOW);
}
// Blynk virtual pin handlers
BLYNK_WRITE(V_LAMP) {
int pinValue = param.asInt();
if (pinValue == 1 && !lampState) {
lampState = true;
digitalWrite(LAMP_PIN, HIGH);
lastMotionTime = millis();
Serial.println("=== LAMP ON (DASHBOARD) ===");
} else if (pinValue == 0 && lampState) {
lampState = false;
digitalWrite(LAMP_PIN, LOW);
Serial.println("=== LAMP OFF (DASHBOARD) ===");
}
}
BLYNK_CONNECTED() {
Serial.println("=== BLYNK CONNECTED ===");
Blynk.syncVirtual(V_LAMP);
}
BLYNK_DISCONNECTED() {
Serial.println("=== BLYNK DISCONNECTED ===");
}