diff --git a/Kode Program Arduino/esp8266.ino b/Kode Program Arduino/esp8266.ino new file mode 100644 index 0000000..150f098 --- /dev/null +++ b/Kode Program Arduino/esp8266.ino @@ -0,0 +1,401 @@ +#include +#include +#include +#include + +// Konfigurasi Firebase +#define FIREBASE_HOST "airsavvy-6e5e1-default-rtdb.firebaseio.com" +#define FIREBASE_AUTH "AIzaSyDDmW_TPBKMVyrCKse2kI2Z4j-1ssUKAcc" +#define USER_EMAIL "airsavvy@gmail.com" +#define USER_PASSWORD "bismillah" + +FirebaseData fbdo; +FirebaseAuth auth; +FirebaseConfig config; + +// Konfigurasi Wifi +#define WIFI_SSID "Jalak Teras" +#define WIFI_PASSWORD "J@lakTer@s" + +// Konfigurasi MQTT +const char* mqtt_server = "192.168.0.106"; // Sesuaikan dengan IP address broker MQTT Anda +const char* mqtt_username = "airsavvy"; +const char* mqtt_password = "bismillah"; + +// Pin sensor dan lampu +#define MQ135_PIN A0 // A0 untuk MQ135 +#define MQ7_PIN 17 // GPIO17 (D3) +#define LAMPU_HIJAU_PIN 2 // GPIO2 (D4) +#define LAMPU_KUNING_PIN 3 // GPIO3 (RX0) +#define LAMPU_MERAH_PIN 4 // GPIO4 (D2) +#define BUZZER_PIN 5 // GPIO5 (D1) + +// Pin relay +#define RELAY_PIN_1 12 // GPIO12 (D6) +#define RELAY_PIN_2 13 // GPIO13 (D7) +#define RELAY_PIN_3 14 // GPIO14 (D5) +#define RELAY_PIN_4 15 // GPIO15 (D8) + +// Konfigurasi MQ135 +int Rload = 20000; +float ro; +double ppm = 414.38; +float a_mq135 = 110.7432567; +float b_mq135 = -2.856935538; +const long MAX_VALUES_NUM = 10; +AverageValue averageValue(MAX_VALUES_NUM); + +// Konfigurasi MQ7 +int RL = 10000; +float Ro = 10; +float Vcc = 3.3; + +WiFiClient espClient; +PubSubClient client(espClient); + +FirebaseData firebaseData; + +int mode = 0; // Default mode 0 + +void setup_wifi() { + delay(10); + Serial.println(); + Serial.print("Connecting to "); + Serial.println(WIFI_SSID); + + WiFi.mode(WIFI_STA); + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + + Serial.println(""); + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); +} + +void callback(char* topic, byte* payload, unsigned int length) { + if (strcmp(topic, "control/mode") == 0) { + mode = payload[0] - '0'; // Convert char to int + } else if (mode == 1) { + if (strcmp(topic, "control/relay1") == 0) { + digitalWrite(RELAY_PIN_1, payload[0] == '1' ? HIGH : LOW); + Firebase.RTDB.setString(&fbdo, "Relay1", payload[0] == '1' ? "OFF" : "ON"); + } else if (strcmp(topic, "control/relay2") == 0) { + digitalWrite(RELAY_PIN_2, payload[0] == '1' ? HIGH : LOW); + Firebase.RTDB.setString(&fbdo, "Relay2", payload[0] == '1' ? "OFF" : "ON"); + } else if (strcmp(topic, "control/relay3") == 0) { + digitalWrite(RELAY_PIN_3, payload[0] == '1' ? HIGH : LOW); + Firebase.RTDB.setString(&fbdo, "Relay3", payload[0] == '1' ? "OFF" : "ON"); + } else if (strcmp(topic, "control/relay4") == 0) { + digitalWrite(RELAY_PIN_4, payload[0] == '1' ? HIGH : LOW); + Firebase.RTDB.setString(&fbdo, "Relay4", payload[0] == '1' ? "OFF" : "ON"); + } + } +} + +int calibrateSensor() { + int readings = 0; + for (int i = 0; i < 50; i++) { + int sensorValue = analogRead(MQ7_PIN); + float Rs = (Vcc * RL / (sensorValue * (Vcc / 1023.0))) - RL; + readings += Rs; + delay(500); + } + readings /= 50; + int Ro = readings / 3.5; // Rasio Rs/Ro dalam udara bersih adalah 3.5 untuk MQ-7 + return Ro; +} + +void setup() { + Serial.begin(9600); + + // Koneksi Wifi + setup_wifi(); + + // Koneksi ke Firebase + config.api_key = FIREBASE_AUTH; + config.database_url = FIREBASE_HOST; + auth.user.email = USER_EMAIL; + auth.user.password = USER_PASSWORD; + Firebase.reconnectNetwork(true); + fbdo.setBSSLBufferSize(4096, 1024); + fbdo.setResponseSize(2048); + Firebase.begin(&config, &auth); + Firebase.setDoubleDigits(5); + config.timeout.serverResponse = 10 * 1000; + + // Setting mode pin + pinMode(LAMPU_HIJAU_PIN, OUTPUT); + pinMode(LAMPU_KUNING_PIN, OUTPUT); + pinMode(LAMPU_MERAH_PIN, OUTPUT); + pinMode(BUZZER_PIN, OUTPUT); + + pinMode(RELAY_PIN_1, OUTPUT); + pinMode(RELAY_PIN_2, OUTPUT); + pinMode(RELAY_PIN_3, OUTPUT); + pinMode(RELAY_PIN_4, OUTPUT); + + // Kalibrasi nilai Ro untuk MQ135 + int adcRaw; + float rs; + for (int i = 0; i < 10; i++) { + adcRaw = analogRead(MQ135_PIN); + rs = ((1024.0 * Rload) / adcRaw) - Rload; + ro += rs * exp(log(a_mq135 / ppm) / b_mq135); // Hitung nilai Ro + delay(2000); // Jeda 2 detik + } + ro /= 10.0; // Ambil rata-rata dari 10 pengukuran Ro + Serial.print("Ro: "); + Serial.println(ro); + + // Inisialisasi dan kalibrasi sensor MQ7 + Ro = calibrateSensor(); // Kalibrasi sensor untuk mendapatkan nilai Ro + + // Set callback dan koneksi ke broker MQTT + client.setServer(mqtt_server, 1883); + client.setCallback(callback); + + Serial.println("Setup Selesai"); +} + +void loop() { + if (!client.connected()) { + reconnect(); + } + client.loop(); + + // Membaca nilai dari sensor MQ135 untuk CO2 + int adcRaw = analogRead(MQ135_PIN); + float rs = ((1024.0 * Rload) / adcRaw) - Rload; + float rsro = rs / ro; + float co2ppm = a_mq135 * pow((float)rs / (float)ro, b_mq135); + averageValue.push(co2ppm); + + // Membaca nilai dari sensor MQ7 untuk CO + float sensorValue = analogRead(MQ7_PIN); + float Rs = (Vcc * RL / (sensorValue * (Vcc / 1023.0))) - RL; + float ratio = Rs / Ro; + float ppm_mq7 = (pow(10, ((log10(ratio) - 0.08) / -0.42))) * 100; + + // Menentukan kategori kualitas udara untuk CO2 + String kategoriCO2; + float avgCO2ppm = averageValue.average(); + if (avgCO2ppm >= 0 && avgCO2ppm <= 600) { + kategoriCO2 = "Baik"; + } else if (avgCO2ppm > 600 && avgCO2ppm <= 1000) { + kategoriCO2 = "Kurang Baik"; + } else if (avgCO2ppm > 1000) { + kategoriCO2 = "Buruk"; + } + + // Menentukan kategori kualitas udara untuk CO + String kategoriCO; + if (ppm_mq7 >= 0 && ppm_mq7 <= 9) { + kategoriCO = "Baik"; + } else if (ppm_mq7 > 9 && ppm_mq7 <= 24) { + kategoriCO = "Kurang Baik"; + } else if (ppm_mq7 > 24) { + kategoriCO = "Buruk"; + } + + // Menyalakan lampu dan relay berdasarkan kategori kualitas udara + if (mode == 0) { + // Kirim status mode ke Firebase + if (Firebase.RTDB.setInt(&fbdo, "Mode", 0)) { + Serial.println("Set Mode success"); + } else { + Serial.print("Set Mode failed: "); + Serial.println(fbdo.errorReason()); + } + + if (kategoriCO2 == "Buruk" || kategoriCO == "Buruk") { + digitalWrite(LAMPU_HIJAU_PIN, LOW); // Matikan lampu hijau + digitalWrite(LAMPU_KUNING_PIN, LOW); // Matikan lampu kuning + digitalWrite(LAMPU_MERAH_PIN, HIGH); // Hidupkan lampu merah + digitalWrite(BUZZER_PIN, HIGH); // Hidupkan buzzer + digitalWrite(RELAY_PIN_1, LOW); // Hidupkan relay 1 + digitalWrite(RELAY_PIN_2, LOW); // Hidupkan relay 2 + digitalWrite(RELAY_PIN_3, LOW); // Hidupkan relay 3 + digitalWrite(RELAY_PIN_4, LOW); // Hidupkan relay 4 + + // Kirim status relay ke Firebase + if (Firebase.RTDB.setString(&fbdo, "Relay1", "ON")) { + Serial.println("Set Relay1 success"); + } else { + Serial.print("Set Relay1 failed: "); + Serial.println(fbdo.errorReason()); + } + + if (Firebase.RTDB.setString(&fbdo, "Relay2", "ON")) { + Serial.println("Set Relay2 success"); + } else { + Serial.print("Set Relay2 failed: "); + Serial.println(fbdo.errorReason()); + } + + if (Firebase.RTDB.setString(&fbdo, "Relay3", "ON")) { + Serial.println("Set Relay3 success"); + } else { + Serial.print("Set Relay3 failed: "); + Serial.println(fbdo.errorReason()); + } + + if (Firebase.RTDB.setString(&fbdo, "Relay4", "ON")) { + Serial.println("Set Relay4 success"); + } else { + Serial.print("Set Relay4 failed: "); + Serial.println(fbdo.errorReason()); + } + + } else if (kategoriCO2 == "Kurang Baik" || kategoriCO == "Kurang Baik") { + digitalWrite(LAMPU_HIJAU_PIN, LOW); // Matikan lampu hijau + digitalWrite(LAMPU_KUNING_PIN, HIGH); // Hidupkan lampu kuning + digitalWrite(LAMPU_MERAH_PIN, LOW); // Matikan lampu merah + digitalWrite(BUZZER_PIN, LOW); // Matikan buzzer jika kualitas udara tidak buruk + digitalWrite(RELAY_PIN_1, LOW); // Hidupkan relay 1 + digitalWrite(RELAY_PIN_2, LOW); // Hidupkan relay 2 + digitalWrite(RELAY_PIN_3, LOW); // Hidupkan relay 3 + digitalWrite(RELAY_PIN_4, HIGH); // Matikan relay 4 + + // Kirim status relay ke Firebase + if (Firebase.RTDB.setString(&fbdo, "Relay1", "ON")) { + Serial.println("Set Relay1 success"); + } else { + Serial.print("Set Relay1 failed: "); + Serial.println(fbdo.errorReason()); + } + + if (Firebase.RTDB.setString(&fbdo, "Relay2", "ON")) { + Serial.println("Set Relay2 success"); + } else { + Serial.print("Set Relay2 failed: "); + Serial.println(fbdo.errorReason()); + } + + if (Firebase.RTDB.setString(&fbdo, "Relay3", "ON")) { + Serial.println("Set Relay3 success"); + } else { + Serial.print("Set Relay3 failed: "); + Serial.println(fbdo.errorReason()); + } + + if (Firebase.RTDB.setString(&fbdo, "Relay4", "OFF")) { + Serial.println("Set Relay4 success"); + } else { + Serial.print("Set Relay4 failed: "); + Serial.println(fbdo.errorReason()); + } + + } else if (kategoriCO2 == "Baik" || kategoriCO == "Baik") { + digitalWrite(LAMPU_HIJAU_PIN, HIGH); // Hidupkan lampu hijau + digitalWrite(LAMPU_KUNING_PIN, LOW); // Matikan lampu kuning + digitalWrite(LAMPU_MERAH_PIN, LOW); // Matikan lampu merah + digitalWrite(BUZZER_PIN, LOW); // Matikan buzzer jika kualitas udara tidak buruk + digitalWrite(RELAY_PIN_1, HIGH); // Matikan relay 1 + digitalWrite(RELAY_PIN_2, HIGH); // Matikan relay 2 + digitalWrite(RELAY_PIN_3, HIGH); // Matikan relay 3 + digitalWrite(RELAY_PIN_4, HIGH); // Matikan relay 4 + + // Kirim status relay ke Firebase + if (Firebase.RTDB.setString(&fbdo, "Relay1", "OFF")) { + Serial.println("Set Relay1 success"); + } else { + Serial.print("Set Relay1 failed: "); + Serial.println(fbdo.errorReason()); + } + + if (Firebase.RTDB.setString(&fbdo, "Relay2", "OFF")) { + Serial.println("Set Relay2 success"); + } else { + Serial.print("Set Relay2 failed: "); + Serial.println(fbdo.errorReason()); + } + + if (Firebase.RTDB.setString(&fbdo, "Relay3", "OFF")) { + Serial.println("Set Relay3 success"); + } else { + Serial.print("Set Relay3 failed: "); + Serial.println(fbdo.errorReason()); + } + + if (Firebase.RTDB.setString(&fbdo, "Relay4", "OFF")) { + Serial.println("Set Relay4 success"); + } else { + Serial.print("Set Relay4 failed: "); + Serial.println(fbdo.errorReason()); + } + } + } else if (mode == 1) { + // Kirim status mode ke Firebase + if (Firebase.RTDB.setInt(&fbdo, "Mode", 1)) { + Serial.println("Set Mode success"); + } else { + Serial.print("Set Mode failed: "); + Serial.println(fbdo.errorReason()); + } + + // Mode 1: Mengontrol relay manual melalui MQTT + digitalWrite(LAMPU_HIJAU_PIN, kategoriCO2 == "Baik" || kategoriCO == "Baik" ? HIGH : LOW); + digitalWrite(LAMPU_KUNING_PIN, kategoriCO2 == "Kurang Baik" || kategoriCO == "Kurang Baik" ? HIGH : LOW); + digitalWrite(LAMPU_MERAH_PIN, kategoriCO2 == "Buruk" || kategoriCO == "Buruk" ? HIGH : LOW); + digitalWrite(BUZZER_PIN, kategoriCO2 == "Buruk" || kategoriCO == "Buruk" ? HIGH : LOW); + } + + // Kirim nilai ke Firebase + if (Firebase.RTDB.setFloat(&fbdo, "CO2_ppm", (int)avgCO2ppm)) { + Serial.print("Set CO2_ppm success: "); + Serial.println(avgCO2ppm); + } else { + Serial.print("Set CO2_ppm failed: "); + Serial.println(fbdo.errorReason()); + } + + if (Firebase.RTDB.setFloat(&fbdo, "CO_ppm", (int)ppm_mq7)) { + Serial.print("Set CO_ppm success: "); + Serial.println(ppm_mq7); + } else { + Serial.print("Set CO_ppm failed: "); + Serial.println(fbdo.errorReason()); + } + + if (Firebase.RTDB.setString(&fbdo, "Kategori_CO2", kategoriCO2)) { + Serial.print("Set Kategori_CO2 success: "); + Serial.println(kategoriCO2); + } else { + Serial.print("Set Kategori_CO2 failed: "); + Serial.println(fbdo.errorReason()); + } + + if (Firebase.RTDB.setString(&fbdo, "Kategori_CO", kategoriCO)) { + Serial.print("Set Kategori_CO success: "); + Serial.println(kategoriCO); + } else { + Serial.print("Set Kategori_CO failed: "); + Serial.println(fbdo.errorReason()); + } + + delay(1000); // Memberi jeda sejenak sebelum membaca ulang sensor +} + +void reconnect() { + while (!client.connected()) { + Serial.print("Attempting MQTT connection..."); + if (client.connect("ESP8266Client", mqtt_username, mqtt_password)) { + Serial.println("connected"); + client.subscribe("control/mode"); + client.subscribe("control/relay1"); + client.subscribe("control/relay2"); + client.subscribe("control/relay3"); + client.subscribe("control/relay4"); + } else { + Serial.print("failed, rc="); + Serial.print(client.state()); + Serial.println(" try again in 5 seconds"); + delay(5000); + } + } +} \ No newline at end of file diff --git a/Kode Program Arduino/esp8266lcd.ino b/Kode Program Arduino/esp8266lcd.ino new file mode 100644 index 0000000..97e1d37 --- /dev/null +++ b/Kode Program Arduino/esp8266lcd.ino @@ -0,0 +1,107 @@ +#include +#include +#include +#include + +// WiFi credentials +#define WIFI_SSID "Jalak Teras" +#define WIFI_PASSWORD "J@lakTer@s" + +// Firebase credentials +#define FIREBASE_HOST "https://airsavvy-6e5e1-default-rtdb.firebaseio.com/" +#define FIREBASE_AUTH "P1A3xXJF66kjDms3EXTtBxRauFpsGY6b2MHhdoXr" + +// Firebase objects +FirebaseData firebaseData; +FirebaseConfig config; +FirebaseAuth auth; + +// LCD settings +LiquidCrystal_I2C lcd(0x27, 16, 2); + +// Variables to store data from Firebase +String kategori_CO2 = ""; +String kategori_CO = ""; +int CO2_ppm = 0; +int CO_ppm = 0; + +void setup() { + Serial.begin(9600); // Start serial monitor for debugging + + // Initialize LCD + lcd.begin(); + lcd.backlight(); + lcd.clear(); + + // Display initial message on LCD + lcd.setCursor(0, 0); + lcd.print(" Please Wait..."); + + // Connect to Wi-Fi + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + Serial.print("Connecting to Wi-Fi"); + while (WiFi.status() != WL_CONNECTED) { + Serial.print("."); + delay(500); + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + + // Configure Firebase + config.host = FIREBASE_HOST; + config.database_url = FIREBASE_HOST; // Make sure to add this line + config.signer.tokens.legacy_token = FIREBASE_AUTH; // Use the correct field for the legacy token + Firebase.begin(&config, &auth); + Firebase.reconnectWiFi(true); + + Serial.println("Connected to Firebase"); + lcd.clear(); // Clear the initial message +} + +void loop() { + // Retrieve string data for Kategori_CO2 from Firebase + if (Firebase.getString(firebaseData, "/Kategori_CO2")) { + kategori_CO2 = firebaseData.stringData(); + } else { + Serial.print("Error getting Kategori_CO2: "); + Serial.println(firebaseData.errorReason()); + } + + // Retrieve string data for Kategori_CO from Firebase + if (Firebase.getString(firebaseData, "/Kategori_CO")) { + kategori_CO = firebaseData.stringData(); + } else { + Serial.print("Error getting Kategori_CO: "); + Serial.println(firebaseData.errorReason()); + } + + /* + // Retrieve numeric data for CO2_ppm from Firebase + if (Firebase.getInt(firebaseData, "/CO2_ppm")) { + CO2_ppm = firebaseData.intData(); + } else { + Serial.print("Error getting CO2_ppm: "); + Serial.println(firebaseData.errorReason()); + } + + // Retrieve numeric data for CO_ppm from Firebase + if (Firebase.getInt(firebaseData, "/CO_ppm")) { + CO_ppm = firebaseData.intData(); + } else { + Serial.print("Error getting CO_ppm: "); + Serial.println(firebaseData.errorReason()); + } + */ + + // Display data on LCD + lcd.clear(); + lcd.setCursor(0, 0); + lcd.print("CO2 "); + lcd.print(kategori_CO2); + lcd.setCursor(0, 1); + lcd.print("CO "); + lcd.print(kategori_CO); + + delay(1000); // Avoiding rate limits by adding delay +}