#include // ===================================================== // ESP32 + MQ-135 + MQ-7 + OLED SSD1306 (0.96" 128x64) // Bahasa Indonesia | Stabil | Client-ready // ===================================================== #include #include #include #include // ================= OLED CONFIG ================= #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define OLED_ADDR 0x3C Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // ================= MQ CONFIG =================== #define BOARD "ESP-32" #define VOLTAGE 3.3 #define ADC_BITS 12 #define PIN_MQ135 34 #define PIN_MQ7 35 #define RATIO_CLEAN_MQ135 3.6 #define RATIO_CLEAN_MQ7 27.5 MQUnifiedsensor MQ135(BOARD, VOLTAGE, ADC_BITS, PIN_MQ135, "MQ-135"); MQUnifiedsensor MQ7(BOARD, VOLTAGE, ADC_BITS, PIN_MQ7, "MQ-7"); // ================= HELPER ====================== float readAverage(MQUnifiedsensor &sensor, int samples = 5) { float sum = 0; for (int i = 0; i < samples; i++) { sensor.update(); sum += sensor.readSensor(); delay(50); } return sum / samples; } // ===================================================== void setup() { Serial.begin(115200); delay(500); // ================= OLED INIT ================= Wire.begin(21, 22); if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) { Serial.println("❌ OLED tidak ditemukan!"); while (true) delay(1000); } display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.println("Monitoring Udara"); display.println("ESP32 + MQ"); display.println("Kalibrasi..."); display.display(); // ================= KALIBRASI ================= Serial.println("Mulai kalibrasi sensor..."); Serial.println("Pastikan udara bersih (±1-2 menit)"); // MQ135 MQ135.setRegressionMethod(1); MQ135.init(); float r0_135 = 0; for (int i = 0; i < 10; i++) { MQ135.update(); r0_135 += MQ135.calibrate(RATIO_CLEAN_MQ135); delay(600); } r0_135 /= 10; MQ135.setR0(r0_135); // MQ7 MQ7.setRegressionMethod(1); MQ7.init(); float r0_7 = 0; for (int i = 0; i < 10; i++) { MQ7.update(); r0_7 += MQ7.calibrate(RATIO_CLEAN_MQ7); delay(600); } r0_7 /= 10; MQ7.setR0(r0_7); if (r0_135 <= 0 || r0_7 <= 0) { Serial.println("❌ Kalibrasi gagal!"); display.clearDisplay(); display.setCursor(0, 0); display.println("ERROR KALIBRASI"); display.display(); while (true) delay(1000); } Serial.println("Kalibrasi selesai!"); display.clearDisplay(); display.setCursor(0, 0); display.println("Kalibrasi OK"); display.println("Mulai Monitor"); display.display(); delay(2000); } // ===================================================== void loop() { // =============== MQ135 ================= MQ135.setA(110.47); MQ135.setB(-2.862); float co2 = readAverage(MQ135); if (co2 < 0) co2 = 0; MQ135.setA(605.18); MQ135.setB(-3.937); float benzene = readAverage(MQ135); if (benzene < 0) benzene = 0; // =============== MQ7 =================== MQ7.setA(99.042); MQ7.setB(-1.518); float co = readAverage(MQ7); if (co < 0) co = 0; // ========== AIR QUALITY ESTIMATION ===== int aq = 100; if (co2 > 700) aq -= map(co2, 700, 2000, 0, 50); if (co2 > 2000) aq -= map(co2, 2000, 5000, 50, 80); if (co > 10) aq -= map(co, 10, 50, 0, 30); if (co > 50) aq -= 30; if (benzene > 5) aq -= map(benzene, 5, 50, 0, 40); aq = constrain(aq, 0, 100); String status; if (aq >= 90) status = "Sangat Baik"; else if (aq >= 70) status = "Baik"; else if (aq >= 50) status = "Sedang"; else if (aq >= 30) status = "Buruk"; else status = "Sangat Buruk"; // =============== OLED DISPLAY ========== display.clearDisplay(); display.setCursor(0, 0); display.print("CO2: "); display.print(co2, 0); display.println(" ppm"); display.print("CO : "); display.print(co, 1); display.println(" ppm"); display.print("BZ : "); display.print(benzene, 1); display.println(" ppm"); display.print("AQ : "); display.print(aq); display.print("% "); display.println(status); display.display(); // =============== SERIAL ================= Serial.println("===== STATUS UDARA ====="); Serial.print("CO2 : "); Serial.print(co2); Serial.println(" ppm"); Serial.print("CO : "); Serial.print(co); Serial.println(" ppm"); Serial.print("BZ : "); Serial.print(benzene); Serial.println(" ppm"); Serial.print("AQ : "); Serial.print(aq); Serial.print("% "); Serial.println(status); Serial.println("========================\n"); delay(5000); }