Upload files to "/"

This commit is contained in:
diyanshintiabella 2025-07-07 09:55:53 +07:00
parent d8ea084579
commit 5ced8b2381
1 changed files with 378 additions and 0 deletions

378
smarthome.ino Normal file
View File

@ -0,0 +1,378 @@
#include <WiFi.h>
#include <HTTPClient.h>
#include <DHT.h>
#include <Adafruit_Fingerprint.h>
#include <ArduinoJson.h>
// --- Pin & Sensor ---
#define DHTPIN 32
#define DHTTYPE DHT11
#define MQ2_PIN 34
#define LDR_PIN 35
#define RELAY_SENSOR_PIN 25
#define RELAY_FINGERPRINT_PIN 13
#define LDR_CONTROL_PIN 23
#define BUZZER_PIN 4
#define BUTTON_PIN 15
DHT dht(DHTPIN, DHTTYPE);
HardwareSerial mySerial(2); // RX = 16, TX = 17
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
// --- WiFi & Firebase ---
const char* ssid = "Bellaa";
const char* password = "bella0916";
const String FIREBASE_HOST = "https://rumahoto-c7c9b-default-rtdb.firebaseio.com/";
const String FIREBASE_AUTH = "AAIzaSyDhXwFT0yCV4lAXPyKIMcfRzbNIxVVudl8";
// --- Mode Tombol ---
enum ButtonMode { MODE_NONE, MODE_UNLOCK, MODE_ENROLL, MODE_RESET };
ButtonMode currentMode = MODE_NONE;
// --- Variabel ---
unsigned long buttonPressTime = 0;
bool buttonPressed = false;
bool fiveSecondBuzzed = false;
bool tenSecondBuzzed = false;
unsigned long lastSensorSend = 0;
const unsigned long SENSOR_INTERVAL = 1000;
int threshold_ldr = 100;
int threshold_mq2 = 100;
int threshold_suhu = 30;
int mq2Baseline = 300;
bool kalibrasiSelesai = false;
int statusPintu = 0;
// --- Deklarasi Fungsi ---
void handleButton();
void modeEnrollFingerprint();
void modeResetFingerprint();
void cekFingerprint();
void bacaSensor();
void kirimStatusPintuFirebase(int status);
void bacaThresholdFirebase();
void kalibrasiMQ2();
void buzzerOnce();
uint8_t getNextAvailableID();
uint8_t getFingerprintEnroll(uint8_t id);
int bacaLDRRataRata(int jumlah = 10);
void setup() {
Serial.begin(9600);
dht.begin();
pinMode(RELAY_SENSOR_PIN, OUTPUT);
pinMode(RELAY_FINGERPRINT_PIN, OUTPUT);
pinMode(LDR_CONTROL_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
digitalWrite(RELAY_SENSOR_PIN, LOW);
digitalWrite(RELAY_FINGERPRINT_PIN, LOW);
digitalWrite(LDR_CONTROL_PIN, LOW);
digitalWrite(BUZZER_PIN, LOW);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi Terhubung");
mySerial.begin(57600, SERIAL_8N1, 16, 17);
finger.begin(57600);
if (finger.verifyPassword()) {
Serial.println("Sensor Fingerprint terdeteksi.");
} else {
Serial.println("Sensor Fingerprint TIDAK terdeteksi.");
}
kalibrasiMQ2();
}
void loop() {
handleButton();
cekFingerprint();
if (millis() - lastSensorSend >= SENSOR_INTERVAL) {
lastSensorSend = millis();
bacaThresholdFirebase();
bacaSensor();
}
}
void handleButton() {
int state = digitalRead(BUTTON_PIN);
unsigned long now = millis();
if (state == LOW && !buttonPressed) {
buttonPressed = true;
buttonPressTime = now;
fiveSecondBuzzed = false;
tenSecondBuzzed = false;
}
if (buttonPressed) {
unsigned long duration = now - buttonPressTime;
if (duration >= 5000 && !fiveSecondBuzzed && duration < 10000) {
buzzerOnce();
fiveSecondBuzzed = true;
}
if (duration >= 10000 && !tenSecondBuzzed) {
buzzerOnce();
tenSecondBuzzed = true;
}
}
if (state == HIGH && buttonPressed) {
unsigned long duration = now - buttonPressTime;
buttonPressed = false;
if (duration >= 10000) {
currentMode = MODE_RESET;
modeResetFingerprint();
} else if (duration >= 5000) {
currentMode = MODE_ENROLL;
modeEnrollFingerprint();
} else if (duration >= 50) {
currentMode = MODE_UNLOCK;
statusPintu = 1;
kirimStatusPintuFirebase(statusPintu);
digitalWrite(RELAY_FINGERPRINT_PIN, HIGH);
delay(5000);
digitalWrite(RELAY_FINGERPRINT_PIN, LOW);
statusPintu = 0;
kirimStatusPintuFirebase(statusPintu);
}
currentMode = MODE_NONE;
}
}
void modeEnrollFingerprint() {
uint8_t id = getNextAvailableID();
if (id == 0) {
Serial.println("Semua ID fingerprint sudah terpakai!");
return;
}
Serial.print("ID yang akan didaftarkan: ");
Serial.println(id);
unsigned long enrollStart = millis();
const unsigned long TIMEOUT = 30000;
bool success = false;
while (millis() - enrollStart < TIMEOUT) {
Serial.println("Menunggu jari...");
if (getFingerprintEnroll(id)) {
success = true;
break;
} else {
Serial.println("Gagal, coba lagi...");
buzzerOnce();
}
delay(1000);
}
if (success) {
Serial.println("Pendaftaran berhasil.");
buzzerOnce();
} else {
Serial.println("Pendaftaran dibatalkan (timeout).");
for (int i = 0; i < 5; i++) {
buzzerOnce();
delay(100);
}
}
}
void modeResetFingerprint() {
Serial.println("Menghapus semua fingerprint...");
for (int i = 0; i < 5; i++) {
buzzerOnce();
delay(100);
}
for (uint8_t i = 1; i <= 127; i++) {
finger.deleteModel(i);
}
Serial.println("Reset selesai.");
}
void cekFingerprint() {
if (currentMode != MODE_NONE) return;
if (finger.getImage() != FINGERPRINT_OK) return;
if (finger.image2Tz() != FINGERPRINT_OK || finger.fingerSearch() != FINGERPRINT_OK) {
buzzerOnce();
return;
}
Serial.print("Fingerprint cocok, ID: ");
Serial.println(finger.fingerID);
statusPintu = 1;
kirimStatusPintuFirebase(statusPintu);
digitalWrite(RELAY_FINGERPRINT_PIN, HIGH);
delay(5000);
digitalWrite(RELAY_FINGERPRINT_PIN, LOW);
statusPintu = 0;
kirimStatusPintuFirebase(statusPintu);
}
void bacaSensor() {
if (!kalibrasiSelesai) {
Serial.println("Kalibrasi MQ2 belum selesai.");
return;
}
float temp = dht.readTemperature();
float hum = dht.readHumidity();
int gasRaw = analogRead(MQ2_PIN);
float gasPercent = mq2Baseline != 0 ? ((float)gasRaw / mq2Baseline) * 100.0 : 0.0;
int ldrRaw = bacaLDRRataRata();
if (isnan(temp) || isnan(hum)) {
Serial.println("Sensor DHT11 error");
return;
}
Serial.printf("Suhu: %.2f °C, Hum: %.2f%%, MQ2: %.2f, LDR (avg): %d\n", temp, hum, gasPercent, ldrRaw);
digitalWrite(RELAY_SENSOR_PIN, temp >= threshold_suhu ? HIGH : LOW);
digitalWrite(BUZZER_PIN, gasPercent > threshold_mq2 ? HIGH : LOW);
digitalWrite(LDR_CONTROL_PIN, ldrRaw >= threshold_ldr ? HIGH : LOW);
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = FIREBASE_HOST + "sensor.json?auth=" + FIREBASE_AUTH;
String payload = "{\"suhu\":" + String(temp) + ",\"kelembaban\":" + String(hum) + ",\"mq2\":" + String(gasPercent) + ",\"ldr\":" + String(ldrRaw) + "}";
http.begin(url);
http.addHeader("Content-Type", "application/json");
int res = http.PATCH(payload);
Serial.println(res > 0 ? "Data sensor terkirim!" : "Gagal kirim data sensor");
http.end();
int statusLampu = digitalRead(LDR_CONTROL_PIN);
int statusBuzzer = digitalRead(BUZZER_PIN);
String statusPayload = "{\"lampu\":" + String(statusLampu) + ",\"pintu\":" + String(statusPintu) + ",\"buzzer\":" + String(statusBuzzer) + "}";
String statusUrl = FIREBASE_HOST + "status.json?auth=" + FIREBASE_AUTH;
http.begin(statusUrl);
http.addHeader("Content-Type", "application/json");
int statusRes = http.PATCH(statusPayload);
Serial.println(statusRes > 0 ? "Status terkirim!" : "Gagal kirim status");
http.end();
}
}
void kirimStatusPintuFirebase(int status) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = FIREBASE_HOST + "status.json?auth=" + FIREBASE_AUTH;
String payload = "{\"pintu\":" + String(status) + "}";
http.begin(url);
http.addHeader("Content-Type", "application/json");
int code = http.PATCH(payload);
Serial.println(code > 0 ? "Status pintu dikirim!" : "Gagal kirim status pintu");
http.end();
}
}
void bacaThresholdFirebase() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = FIREBASE_HOST + "threshold.json?auth=" + FIREBASE_AUTH;
http.begin(url);
int res = http.GET();
if (res == 200) {
String response = http.getString();
DynamicJsonDocument doc(256);
deserializeJson(doc, response);
threshold_ldr = doc["ldr"] | threshold_ldr;
threshold_mq2 = doc["mq2"] | threshold_mq2;
threshold_suhu = doc["suhu"] | threshold_suhu;
}
http.end();
}
}
void kalibrasiMQ2() {
long total = 0;
const int sampleCount = 100;
Serial.println("Kalibrasi MQ2 sedang dilakukan...");
for (int i = 0; i < sampleCount; i++) {
total += analogRead(MQ2_PIN);
delay(50);
}
mq2Baseline = total / sampleCount;
kalibrasiSelesai = true;
Serial.print("Kalibrasi selesai. Nilai baseline MQ2: ");
Serial.println(mq2Baseline);
}
void buzzerOnce() {
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
}
uint8_t getNextAvailableID() {
for (uint8_t id = 1; id <= 127; id++) {
if (finger.loadModel(id) != FINGERPRINT_OK) return id;
}
return 0;
}
uint8_t getFingerprintEnroll(uint8_t id) {
int p = -1;
Serial.println("Letakkan jari...");
unsigned long timeoutStart = millis();
while (p != FINGERPRINT_OK) {
if (millis() - timeoutStart > 30000) {
Serial.println("Timeout jari pertama.");
return false;
}
p = finger.getImage();
if (p == FINGERPRINT_NOFINGER) delay(100);
}
if (finger.image2Tz(1) != FINGERPRINT_OK) return false;
Serial.println("Angkat jari...");
delay(1000);
while (finger.getImage() != FINGERPRINT_NOFINGER) delay(100);
Serial.println("Letakkan lagi...");
timeoutStart = millis();
while (finger.getImage() != FINGERPRINT_OK) {
if (millis() - timeoutStart > 30000) {
Serial.println("Timeout jari kedua.");
return false;
}
delay(100);
}
if (finger.image2Tz(2) != FINGERPRINT_OK) return false;
if (finger.createModel() != FINGERPRINT_OK) return false;
if (finger.storeModel(id) != FINGERPRINT_OK) return false;
return true;
}
int bacaLDRRataRata(int jumlah) {
long total = 0;
for (int i = 0; i < jumlah; i++) {
total += analogRead(LDR_PIN);
delay(5);
}
return total / jumlah;
}