#include <DHT.h>
#include <BlynkSimpleEsp32.h>
#define RAIN_ANALOG 34
#define RAIN_DIGITAL 35
#define STEP_PIN 23 // Pin STEP untuk motor jendela
#define DIR_PIN 22 // Pin DIR untuk motor jendela
#define RELAY_PIN 12 // Pin untuk relay
// Motor Gorden Pins
#define GORDEN_STEP_PIN 21 // Pin STEP untuk motor gorden
#define GORDEN_DIR_PIN 19 // Pin DIR untuk motor gorden
// Pin untuk sensor DHT22
#define DHT_PIN 32 // Pin data untuk DHT22
#define DHT_TYPE DHT22 // Tipe sensor DHT
// Variabel untuk motor gorden
int gordenStepsToMove = 1000; // Jumlah langkah yang akan ditempuh motor gorden
bool gordenButtonHeld = false; // Status tombol motor gorden
// Variabel untuk motor jendela
const int maxSteps = 1000; // Jumlah langkah maksimum untuk motor jendela
int currentSteps = 0; // Jumlah langkah yang telah ditempuh oleh motor jendela
bool motorRunning = false; // Status motor jendela sedang berjalan
bool isRaining = false; // Status hujan
// Inisialisasi sensor DHT
DHT dht(DHT_PIN, DHT_TYPE);
// Blynk Auth Token
char auth[] = "8kN0Di4Fl_vm3SbbGxUToF48v9NAahw0";
// Variabel scrolling
unsigned long lastScrollTime = 0; // Waktu terakhir teks di-scroll
int scrollInterval = 10; // Interval waktu scroll dalam milidetik
int scrollPos = 0; // Posisi scroll teks
void setup() {
pinMode(RAIN_ANALOG, INPUT);
pinMode(RAIN_DIGITAL, INPUT);
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(GORDEN_STEP_PIN, OUTPUT);
pinMode(GORDEN_DIR_PIN, OUTPUT);
digitalWrite(DIR_PIN, LOW); // Default arah motor jendela ke CCW
digitalWrite(RELAY_PIN, LOW); // Relay mati awalnya
Serial.begin(9600);
dht.begin();
// Blynk connection
Blynk.begin(auth, "Wokwi-GUEST", "", "iot.serangkota.go.id", 8080);
// Set teks statis "Check Rain Status" di V6
Blynk.virtualWrite(V6, " Welcome Back! ");
Blynk.virtualWrite(V7, " Ilham Dana ");
delay(5000);
Blynk.virtualWrite(V6, "Chk_Rain_Status");
}
void loop() {
Blynk.run();
// Monitoring sensor hujan
bool rainDetected = digitalRead(RAIN_DIGITAL);
if (rainDetected != isRaining) {
isRaining = rainDetected;
Serial.println(isRaining ? "It's raining!" : "The rain has stopped.");
}
// Kirim status hujan ke Blynk dengan teks bergulir
String rainStatus = isRaining ? "It's raining!" : "The rain has stopped.";
sendScrollingText(rainStatus);
// Jalankan motor untuk menutup jendela jika hujan terdeteksi dan belum mencapai langkah maksimum
if (isRaining && !motorRunning && currentSteps < maxSteps) {
Serial.println("Starting motor to close window...");
motorRunning = true;
rotateMotor(STEP_PIN, DIR_PIN, LOW, maxSteps - currentSteps); // Menutup jendela ke CCW
currentSteps = maxSteps; // Set langkah saat ini ke maksimum
motorRunning = false; // Motor selesai berjalan
Serial.println("Window closed.");
}
// Monitoring DHT
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
if (!isnan(temperature) && !isnan(humidity)) {
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.print(" °C\t");
Serial.print("Humidity: ");
Serial.print(humidity);
Serial.println(" %");
// Kirim data ke Blynk
Blynk.virtualWrite(V4, temperature); // V4 untuk monitoring suhu
Blynk.virtualWrite(V5, humidity); // V5 untuk monitoring kelembapan
} else {
Serial.println("Failed to read from DHT sensor!");
}
delay(200); // Sesuai permintaan, delay tetap dipertahankan
}
// Fungsi untuk mengirim teks bergulir
void sendScrollingText(String text) {
String scrolledText = text;
int textLength = scrolledText.length();
// Jika panjang teks lebih besar dari panjang layar (misal, 16 karakter), scroll teks
if (textLength > 16) {
unsigned long currentMillis = millis();
if (currentMillis - lastScrollTime >= scrollInterval) {
lastScrollTime = currentMillis; // Update waktu terakhir scroll
scrolledText = scrolledText.substring(scrollPos) + scrolledText.substring(0, scrollPos);
scrollPos++; // Update posisi scroll
// Reset posisi scroll jika sudah mencapai akhir teks
if (scrollPos >= textLength) {
scrollPos = 0;
}
// Kirim teks yang digulir ke widget Label (V6) di Blynk
Blynk.virtualWrite(V7, scrolledText);
}
} else {
// Tampilkan teks tanpa scroll jika panjang <= 16
Blynk.virtualWrite(V7, text);
}
}
// Fungsi untuk menggerakkan motor
void rotateMotor(int stepPin, int dirPin, int direction, int steps) {
digitalWrite(dirPin, direction);
for (int i = 0; i < steps; i++) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(1000);
digitalWrite(stepPin, LOW);
delayMicroseconds(1000);
}
}
// Fungsi untuk kontrol relay
BLYNK_WRITE(V0) { // V0 untuk kontrol relay
int value = param.asInt();
if (value == 1 && !isRaining) {
digitalWrite(RELAY_PIN, HIGH); // Aktifkan relay
rotateMotor(STEP_PIN, DIR_PIN, LOW, maxSteps - currentSteps);
currentSteps = maxSteps;
} else {
digitalWrite(RELAY_PIN, LOW); // Matikan relay
}
}
// Fungsi untuk kontrol motor jendela lewat Blynk
BLYNK_WRITE(V1) { // V1 untuk buka jendela (arah motor CW)
int value = param.asInt();
if (value == 1 && !isRaining) {
rotateMotor(STEP_PIN, DIR_PIN, HIGH, currentSteps);
currentSteps = 0;
}
}
BLYNK_WRITE(V2) { // V2 untuk tutup jendela (arah motor CCW)
int value = param.asInt();
if (value == 1 && !isRaining) {
rotateMotor(STEP_PIN, DIR_PIN, LOW, maxSteps - currentSteps);
currentSteps = maxSteps;
}
}
BLYNK_WRITE(V3) { // V3 untuk kontrol gorden buka/tutup
int value = param.asInt();
if (value == 1) {
rotateMotor(GORDEN_STEP_PIN, GORDEN_DIR_PIN, LOW, gordenStepsToMove);
} else {
rotateMotor(GORDEN_STEP_PIN, GORDEN_DIR_PIN, HIGH, gordenStepsToMove);
}
}