#define BLYNK_TEMPLATE_ID "TMPL6fK9UBCNl"
#define BLYNK_TEMPLATE_NAME "Uas Smart ROOM IOT"
#define BLYNK_AUTH_TOKEN "tLNQmxqEVlFevXSpK12wxuG83GxZ9ORr"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
#include <Keypad.h>
#include <ESP32Servo.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <time.h>
#include <BlynkSimpleEsp32.h>
// Konfigurasi LCD 20x4
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Konfigurasi DHT22
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// Konfigurasi LED (Kipas)
#define FAN_LED_PIN 16
// Konfigurasi LDR
#define LDR_PIN 34
// Pin untuk Lampu
#define LIGHT_PIN 0
// Servo untuk pintu
Servo servo;
#define SERVO_PIN 12
// Konfigurasi Keypad
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {23, 22, 21, 18};
byte colPins[COLS] = {5, 17, 4, 14};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
String inputCode = "";
const String password = "1234";
// Wi-Fi credentials
const char* ssid = "Wokwi-GUEST";
const char* passwordWifi = "";
// ThingSpeak API
const char* server = "http://api.thingspeak.com";
const char* apiKeyWrite = "V9BHTTAQJYTXGI8X";
const char* apiKeyRead = "XDCMPRXNI7HR5P79";
const String channelID = "2780234";
char auth[] = BLYNK_AUTH_TOKEN;
// Variabel untuk waktu NTP
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 8 * 3600;
const int daylightOffset_sec = 0;
// Variabel status perangkat
bool pintuTerbuka = false;
bool kipasMenyala = false;
bool lampuMenyala = false;
// Histeresis
float suhuThreshold = 30.0;
int ldrThreshold = 1000;
unsigned long lastMillis = 0;
// Blynk Configuration
BlynkTimer timer;
// Fungsi untuk membuka pintu melalui Blynk
BLYNK_WRITE(V2) {
int value = param.asInt();
if (value == 1) { // Tombol ditekan di aplikasi Blynk
Serial.println("Perintah membuka pintu diterima dari Blynk.");
bukaPintu();
}
}
void setup() {
Serial.begin(115200);
Wire.begin(19, 2);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Masukkan Kata Sandi");
dht.begin();
pinMode(FAN_LED_PIN, OUTPUT);
pinMode(LIGHT_PIN, OUTPUT);
servo.attach(SERVO_PIN);
servo.write(0);
Serial.print("Menghubungkan ke Wi-Fi ");
Serial.println(ssid);
WiFi.begin(ssid, passwordWifi);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi Tersambung!");
Blynk.begin(auth, ssid, passwordWifi);
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
keypad.setDebounceTime(50);
timer.setInterval(10000L, sendSensorDataToBlynk); // Kirim data sensor setiap 10 detik
}
void loop() {
Blynk.run();
timer.run();
char key = keypad.getKey();
if (key) {
handleKeyInput(key);
}
if (millis() - lastMillis >= 10000) {
lastMillis += 10000;
bacaSensorDanKirim();
kirimDataKeThingSpeak(); // Kirim data suhu dan kelembapan ke ThingSpeak setiap 10 detik
}
}
void handleKeyInput(char key) {
Serial.print("Keypad ditekan: ");
Serial.println(key);
if (key == '#') {
if (inputCode == password) {
Serial.println("Kode benar, membuka pintu.");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Pintu Terbuka!");
float suhu = dht.readTemperature();
float kelembapan = dht.readHumidity();
lcd.setCursor(0, 1);
if (!isnan(suhu)) {
lcd.print("Suhu: ");
lcd.print(suhu, 1);
lcd.print(" C");
} else {
lcd.print("Suhu: Error");
}
lcd.setCursor(0, 2);
if (!isnan(kelembapan)) {
lcd.print("Kelembapan: ");
lcd.print(kelembapan, 1);
lcd.print(" %");
} else {
lcd.print("Kelembapan: Error");
}
bukaPintu();
} else {
Serial.println("Kode salah.");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Kode Salah!");
delay(2000);
}
inputCode = "";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Masukkan Kata Sandi");
} else if (key == '*') {
inputCode = "";
lcd.setCursor(0, 1);
lcd.print("Kode: ");
} else {
inputCode += key;
lcd.setCursor(0, 1);
lcd.print("Kode: ");
lcd.print(inputCode);
}
}
void bacaSensorDanKirim() {
float suhu = dht.readTemperature();
float kelembapan = dht.readHumidity();
int ldrValue = analogRead(LDR_PIN);
if (!isnan(suhu) && !isnan(kelembapan)) {
Serial.println("<====================>");
Serial.println("Membaca data sensor:");
Serial.print(" Suhu: "); Serial.println(suhu);
Serial.print(" Kelembapan: "); Serial.println(kelembapan);
Serial.print(" LDR Value: "); Serial.println(ldrValue);
kipasMenyala = suhu > suhuThreshold;
lampuMenyala = ldrValue > ldrThreshold;
digitalWrite(FAN_LED_PIN, kipasMenyala ? HIGH : LOW);
digitalWrite(LIGHT_PIN, lampuMenyala ? HIGH : LOW);
Serial.print(" Kipas: ");
Serial.println(kipasMenyala ? "ON" : "OFF");
Serial.print(" Lampu: ");
Serial.println(lampuMenyala ? "ON" : "OFF");
Serial.println("<====================>");
sendSensorDataToBlynk(); // Perbarui data sensor dan status perangkat ke Blynk
} else {
Serial.println("<====================>");
Serial.println("Gagal membaca data sensor.");
Serial.println("<====================>");
}
}
void sendSensorDataToBlynk() {
float suhu = dht.readTemperature();
float kelembapan = dht.readHumidity();
int ldrValue = analogRead(LDR_PIN);
if (!isnan(suhu) && !isnan(kelembapan)) {
Serial.println("<====================>");
Serial.println("Mengirim data ke Blynk:");
Serial.print(" Suhu: "); Serial.println(suhu);
Serial.print(" Kelembapan: "); Serial.println(kelembapan);
Serial.print(" LDR Value: "); Serial.println(ldrValue);
Serial.print(" Kipas: "); Serial.println(kipasMenyala ? "ON" : "OFF");
Serial.print(" Lampu: "); Serial.println(lampuMenyala ? "ON" : "OFF");
Serial.println("<====================>");
Blynk.virtualWrite(V0, suhu); // Kirim suhu ke Virtual Pin V0
Blynk.virtualWrite(V1, kelembapan); // Kirim kelembapan ke Virtual Pin V1
Blynk.virtualWrite(V5, ldrValue); // Kirim nilai LDR ke Virtual Pin V5
Blynk.virtualWrite(V3, kipasMenyala ? 1 : 0);
Blynk.virtualWrite(V4, lampuMenyala ? 1 : 0);
} else {
Serial.println("<====================>");
Serial.println("Gagal membaca data sensor untuk Blynk!");
Serial.println("<====================>");
}
}
void kirimDataKeThingSpeak() {
float suhu = dht.readTemperature();
float kelembapan = dht.readHumidity();
if (!isnan(suhu) && !isnan(kelembapan)) {
// Format URL untuk ThingSpeak
String url = String("/update?api_key=") + apiKeyWrite +
"&field1=" + String(suhu) +
"&field2=" + String(kelembapan);
HTTPClient http;
http.begin(String(server) + url);
Serial.println("<====================>");
Serial.println("Mengirim data suhu dan kelembapan ke ThingSpeak:");
Serial.print(" URL: "); Serial.println(String(server) + url);
int httpResponseCode = http.GET();
if (httpResponseCode > 0) {
Serial.print(" Response: ");
Serial.println(httpResponseCode);
Serial.println(http.getString());
} else {
Serial.print(" Error: ");
Serial.println(httpResponseCode);
}
http.end();
Serial.println("<====================>");
} else {
Serial.println("<====================>");
Serial.println("Gagal membaca data suhu atau kelembapan untuk ThingSpeak!");
Serial.println("<====================>");
}
}
void bukaPintu() {
Serial.println("Membuka pintu...");
pintuTerbuka = true;
servo.write(90);
delay(5000);
servo.write(0);
pintuTerbuka = false;
Serial.println("Pintu ditutup kembali.");
}