#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// OLED config
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Pins
#define BUTTON_PIN 32
#define ANALOG_SENSOR_PIN 34
// Global loading progress
int loading_progress = 0;
// Struct untuk fuzzy range
struct FuzzyRange {
float aman_min;
float aman_max;
float waspada_min;
float waspada_mid;
float waspada_max;
float bahaya_min;
float bahaya_max;
};
// Fungsi fuzzy
float fuzzy_aman(float x, float min, float max) {
if (x <= min) return 1.0;
if (x >= max) return 0.0;
return (max - x) / (max - min);
}
float fuzzy_waspada(float x, float min, float mid, float max) {
if (x <= min || x >= max) return 0.0;
if (x <= mid) return (x - min) / (mid - min);
return (max - x) / (max - mid);
}
float fuzzy_bahaya(float x, float min, float max) {
if (x <= min) return 0.0;
if (x >= max) return 1.0;
return (x - min) / (max - min);
}
// Fuzzy evaluation
void fuzzyStatus(String nama, float ppm, FuzzyRange range, String &outputStr) {
float u_aman = fuzzy_aman(ppm, range.aman_min, range.aman_max);
float u_waspada = fuzzy_waspada(ppm, range.waspada_min, range.waspada_mid, range.waspada_max);
float u_bahaya = fuzzy_bahaya(ppm, range.bahaya_min, range.bahaya_max);
String status;
if (u_aman >= u_waspada && u_aman >= u_bahaya) status = "AMAN";
else if (u_waspada >= u_bahaya) status = "WASPADA";
else status = "BAHAYA";
// Simpan semua ke string global
outputStr = "";
outputStr += nama + "\n";
outputStr += "PPM: " + String(ppm, 1) + "\n";
outputStr += "A:" + String(u_aman, 2);
outputStr += " W:" + String(u_waspada, 2);
outputStr += " B:" + String(u_bahaya, 2) + "\n";
outputStr += "Status: " + status;
}
void progressBar(int delayPerStep, int targetProgress) {
int start = loading_progress;
int end = targetProgress;
if (targetProgress > 0 && targetProgress <= 100 && targetProgress < start + 10) {
end = start + targetProgress;
}
if (end > 100) end = 100;
for (int i = start; i <= end; i += 5) {
loading_progress = i;
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
// Draw loading bar outline
int barX = 0;
int barY = 24;
int barWidth = 80;
int barHeight = 10;
display.drawRect(barX, barY, barWidth, barHeight, SSD1306_WHITE);
int filled = map(loading_progress, 0, 100, 0, barWidth);
display.fillRect(barX + 1, barY + 1, filled - 2, barHeight - 2, SSD1306_WHITE);
// Draw percentage text next to bar
display.setCursor(barX + barWidth + 5, barY + 1);
display.print(loading_progress);
display.print("%");
display.display();
delay(delayPerStep);
}
}
void setup() {
Serial.begin(115200);
pinMode(BUTTON_PIN, INPUT_PULLUP); // Tombol aktif LOW
pinMode(ANALOG_SENSOR_PIN, INPUT);
// OLED setup
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println("OLED gagal.");
while (1);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 20);
display.println("Siap memulai...");
display.display();
}
void loop() {
if (digitalRead(BUTTON_PIN) == LOW) {
delay(50); // Debounce
while (digitalRead(BUTTON_PIN) == LOW); // Tunggu dilepas
loading_progress = 0;
float ppm_MQ2 = 0;
String output_MQ2;
// MQ-2 Range
FuzzyRange MQ2_range = {
0, 40,
30, 60, 90,
80, 150
};
// 0–80%
progressBar(300, 80);
// Simulasi pembacaan sensor dari potensiometer
int adcVal = analogRead(ANALOG_SENSOR_PIN); // 0–4095
ppm_MQ2 = map(adcVal, 0, 4095, 0, 12000) / 100.0; // PPM: 0–120.00
// Fuzzy
fuzzyStatus("MQ-2", ppm_MQ2, MQ2_range, output_MQ2);
// 80–100%
progressBar(300, 100);
// Tampilkan hasil
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println(output_MQ2);
display.display();
Serial.println(output_MQ2);
delay(3000); // Tahan hasil
}
}