commit 6f61202865eff70f360af864c603f37fd02ddd4e Author: ardha_pria Date: Tue Aug 5 11:05:41 2025 +0700 Upload files to "/" diff --git a/PROJECT_SMARTAMONIA.ino b/PROJECT_SMARTAMONIA.ino new file mode 100644 index 0000000..2c88027 --- /dev/null +++ b/PROJECT_SMARTAMONIA.ino @@ -0,0 +1,183 @@ +#include +#include +#include +#include +#include +#include "addons/TokenHelper.h" +#include "addons/RTDBHelper.h" +#include + +// WiFi +#define WIFI_SSID "redmii" +#define WIFI_PASSWORD "87654321" + +// Firebase +#define API_KEY "AIzaSyAEe82VtGAo4Q1zA1UPGWvLjJ0Bh_7ogdU" +#define DATABASE_URL "https://amonia-a027f-default-rtdb.asia-southeast1.firebasedatabase.app/" +#define USER_EMAIL "ardhaxiomi11@gmail.com" +#define USER_PASSWORD "Ayam.1234" + +FirebaseData fbdo; +FirebaseAuth auth; +FirebaseConfig config; + +// DHT11 +#define DHTPIN 14 +#define DHTTYPE DHT11 +DHT dht(DHTPIN, DHTTYPE); + +// MQ135 +#define MQ135_PIN 34 +const float R0 = 9.50; +const float RL = 10.0; + +// Aktuator +#define RELAY1_PIN 4 +#define RELAY2_PIN 12 +#define BUZZER_PIN 13 + +// LCD +LiquidCrystal_I2C lcd(0x27, 16, 2); + +// Interval pengiriman history (5 menit) +unsigned long lastHistorySendTime = 0; +const unsigned long historyInterval = 5 * 60 * 1000; // 5 menit + +// Tambahan: kendali manual buzzer +int buzzerOverride = -1; // -1 = otomatis, 0 = buzzer mati manual + +void setup() { + Serial.begin(115200); + dht.begin(); + lcd.init(); + lcd.backlight(); + pinMode(RELAY1_PIN, OUTPUT); + pinMode(RELAY2_PIN, OUTPUT); + pinMode(BUZZER_PIN, OUTPUT); + digitalWrite(RELAY1_PIN, LOW); + digitalWrite(RELAY2_PIN, LOW); + digitalWrite(BUZZER_PIN, LOW); + + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println("\nWiFi Connected"); + + // Sinkronisasi waktu NTP (GMT+7) + configTime(25200, 0, "pool.ntp.org", "time.nist.gov"); + struct tm timeinfo; + while (!getLocalTime(&timeinfo)) { + Serial.println("Gagal sinkronisasi waktu"); + delay(1000); + } + + // Firebase + config.api_key = API_KEY; + config.database_url = DATABASE_URL; + auth.user.email = USER_EMAIL; + auth.user.password = USER_PASSWORD; + config.token_status_callback = tokenStatusCallback; + Firebase.begin(&config, &auth); + Firebase.reconnectWiFi(true); +} + +void loop() { + // Baca waktu + struct tm timeinfo; + if (!getLocalTime(&timeinfo)) { + Serial.println("Gagal dapat waktu"); + return; + } + + time_t nowEpoch = mktime(&timeinfo); + char datetimeStr[25]; + + // ✅ Ganti separator waktu ke titik: YYYY-MM-DD-HH.MM.SS + strftime(datetimeStr, sizeof(datetimeStr), "%Y-%m-%d-%H.%M.%S", &timeinfo); + + // Baca sensor + float temp = dht.readTemperature(); + float hum = dht.readHumidity(); + int analogValue = analogRead(MQ135_PIN); + float voltage = analogValue * (3.3 / 4095.0); + float Rs = ((3.3 * RL) / voltage) - RL; + float ratio = Rs / R0; + float ppm = 116.6020682 * pow(ratio, -2.769034857); + float correctedPPM = ppm - 41.0; + if (correctedPPM < 0) correctedPPM = 0; + + // 🔔 Ambil status buzzer manual dari Firebase + if (Firebase.ready()) { + if (Firebase.RTDB.getString(&fbdo, "/amonia_monitoring_realtime/buzzer")) { + String sValue = fbdo.stringData(); + int overrideValue = sValue.toInt(); + buzzerOverride = overrideValue; + Serial.print("Buzzer Override (from Firebase): "); + Serial.println(buzzerOverride); + } + } + + // Aktuator + if (correctedPPM > 25.0) { + digitalWrite(RELAY1_PIN, HIGH); // Kipas selalu ON jika ppm tinggi + if (buzzerOverride == 0) { + digitalWrite(BUZZER_PIN, LOW); // Manual matikan buzzer + } else { + digitalWrite(BUZZER_PIN, HIGH); // Otomatis ON buzzer + } + } else { + digitalWrite(RELAY1_PIN, LOW); // Kipas OFF jika ppm aman + digitalWrite(BUZZER_PIN, LOW); // Buzzer OFF + } + + // Relay2 otomatisasi lampu + if (temp < 30.0) { + digitalWrite(RELAY2_PIN, HIGH); // Lampu ON + } else { + digitalWrite(RELAY2_PIN, LOW); // Lampu OFF + } + + // LCD realtime + lcd.clear(); + lcd.setCursor(0, 0); + lcd.print("T:"); + lcd.print(temp, 1); + lcd.print((char)223); // derajat + lcd.print("C H:"); + lcd.print(hum, 0); + lcd.print("%"); + + lcd.setCursor(0, 1); + char buffer[9]; + sprintf(buffer, "%02d:%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec); + lcd.print(buffer); + lcd.print(" "); + lcd.print((int)correctedPPM); // ✅ PPM ditampilkan sebagai bulat + lcd.print("ppm"); + + // Kirim data realtime (SETIAP DETIK) + if (Firebase.ready()) { + String realtimePath = "/amonia_monitoring_realtime"; + Firebase.RTDB.setFloat(&fbdo, realtimePath + "/temperature", temp); + Firebase.RTDB.setFloat(&fbdo, realtimePath + "/humidity", hum); + Firebase.RTDB.setFloat(&fbdo, realtimePath + "/ppm", (int)correctedPPM); // ✅ Bulatkan + Firebase.RTDB.setString(&fbdo, realtimePath + "/waktu", String(datetimeStr)); + } + + // Kirim data historis (TIAP 5 MENIT) + unsigned long currentMillis = millis(); + if (currentMillis - lastHistorySendTime >= historyInterval || lastHistorySendTime == 0) { + lastHistorySendTime = currentMillis; + String timestamp = String(nowEpoch); + String historyPath = "/amonia_monitoring_history/" + timestamp; + + Firebase.RTDB.setFloat(&fbdo, historyPath + "/temperature", temp); + Firebase.RTDB.setFloat(&fbdo, historyPath + "/humidity", hum); + Firebase.RTDB.setFloat(&fbdo, historyPath + "/ppm", (int)correctedPPM); // ✅ Bulatkan + Firebase.RTDB.setString(&fbdo, historyPath + "/waktu", String(datetimeStr)); + } + + delay(1000); // Loop delay 1 detik +}