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