Upload files to "/"
This commit is contained in:
parent
d8ea084579
commit
5ced8b2381
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue