182 lines
5.2 KiB
C++
182 lines
5.2 KiB
C++
#include <WiFi.h>
|
|
#include <Firebase_ESP_Client.h>
|
|
#include <Wire.h>
|
|
#include <LiquidCrystal_I2C.h>
|
|
#include <WebServer.h>
|
|
#include <WiFiManager.h> // Tambahkan WiFiManager
|
|
|
|
#define API_KEY "AIzaSyBfSo7wVseHLUJepuOv4f0nUKSMpkdaG4c"
|
|
#define DATABASE_URL "https://femonitor-87369-default-rtdb.asia-southeast1.firebasedatabase.app/"
|
|
#define LEGACY_TOKEN "wOznU9rBFBFG5UauVrkfaVOKrc8SCBMW7pmgV7ZT"
|
|
|
|
#define LDR_SEBELUM 34
|
|
#define LDR_SESUDAH 32
|
|
#define RELAY_PIN 14
|
|
#define LED1_PIN 12
|
|
|
|
FirebaseData fbdo;
|
|
FirebaseAuth auth;
|
|
FirebaseConfig config;
|
|
LiquidCrystal_I2C lcd(0x27, 16, 2);
|
|
WebServer server(80);
|
|
|
|
unsigned long lastUpdate = 0;
|
|
unsigned long interval = 5000;
|
|
|
|
float faktorKalibrasiSebelum = 1.0;
|
|
float offsetKalibrasiSebelum = 0.0;
|
|
float faktorKalibrasiSesudah = 1.0;
|
|
float offsetKalibrasiSesudah = 0.0;
|
|
|
|
#define LDR_SMOOTH_COUNT 10
|
|
int ldrBufferSebelum[LDR_SMOOTH_COUNT] = {0};
|
|
int ldrBufferSesudah[LDR_SMOOTH_COUNT] = {0};
|
|
int bufferIndex = 0;
|
|
|
|
float lastFeSebelum = 0.0;
|
|
float lastFeSesudah = 0.0;
|
|
float deltaFeThreshold = 0.2;
|
|
int ldrSebelum = 0;
|
|
int ldrSesudah = 0;
|
|
float feSebelum = 0.0;
|
|
float feSesudah = 0.0;
|
|
|
|
void handleRoot() {
|
|
String html = "<!DOCTYPE html><html><head><meta charset='UTF-8'><title>Data Sensor</title></head><body>";
|
|
html += "<h2>Data Sensor</h2>";
|
|
html += "<p><b>LDR Sebelum:</b> " + String(ldrSebelum) + "</p>";
|
|
html += "<p><b>LDR Sesudah:</b> " + String(ldrSesudah) + "</p>";
|
|
html += "<p><b>Fe Sebelum (ppm):</b> " + String(feSebelum, 2) + "</p>";
|
|
html += "<p><b>Fe Sesudah (ppm):</b> " + String(feSesudah, 2) + "</p>";
|
|
html += "<h3>Kalibrasi Sebelum:</h3>";
|
|
html += "<p>Faktor: " + String(faktorKalibrasiSebelum, 6) + "</p>";
|
|
html += "<p>Offset: " + String(offsetKalibrasiSebelum, 6) + "</p>";
|
|
html += "<h3>Kalibrasi Sesudah:</h3>";
|
|
html += "<p>Faktor: " + String(faktorKalibrasiSesudah, 6) + "</p>";
|
|
html += "<p>Offset: " + String(offsetKalibrasiSesudah, 6) + "</p>";
|
|
html += "</body></html>";
|
|
server.send(200, "text/html", html);
|
|
}
|
|
|
|
void updateKalibrasi() {
|
|
if (Firebase.RTDB.getFloat(&fbdo, "/kalibrasi/sebelum/faktor")) {
|
|
faktorKalibrasiSebelum = fbdo.floatData();
|
|
}
|
|
if (Firebase.RTDB.getFloat(&fbdo, "/kalibrasi/sebelum/offset")) {
|
|
offsetKalibrasiSebelum = fbdo.floatData();
|
|
}
|
|
if (Firebase.RTDB.getFloat(&fbdo, "/kalibrasi/sesudah/faktor")) {
|
|
faktorKalibrasiSesudah = fbdo.floatData();
|
|
}
|
|
if (Firebase.RTDB.getFloat(&fbdo, "/kalibrasi/sesudah/offset")) {
|
|
offsetKalibrasiSesudah = fbdo.floatData();
|
|
}
|
|
}
|
|
|
|
int smoothLDR(int pin, int* buffer) {
|
|
buffer[bufferIndex] = analogRead(pin);
|
|
long total = 0;
|
|
for (int i = 0; i < LDR_SMOOTH_COUNT; i++) {
|
|
total += buffer[i];
|
|
}
|
|
return total / LDR_SMOOTH_COUNT;
|
|
}
|
|
|
|
void sendDataToFirebase() {
|
|
Firebase.RTDB.setFloat(&fbdo, "/kadar_fe/sebelum", feSebelum);
|
|
Firebase.RTDB.setFloat(&fbdo, "/kadar_fe/sesudah", feSesudah);
|
|
}
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
Wire.begin(21, 22);
|
|
lcd.init();
|
|
lcd.backlight();
|
|
|
|
pinMode(RELAY_PIN, OUTPUT);
|
|
digitalWrite(RELAY_PIN, LOW);
|
|
pinMode(LED1_PIN, OUTPUT);
|
|
digitalWrite(LED1_PIN, HIGH);
|
|
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("WiFiManager...");
|
|
|
|
WiFiManager wm;
|
|
bool res = wm.autoConnect("FeMonitorAP"); // Tanpa password
|
|
|
|
if (!res) {
|
|
Serial.println("Gagal connect WiFi. Restart...");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print("WiFi Failed");
|
|
delay(3000);
|
|
ESP.restart();
|
|
}
|
|
|
|
Serial.println("WiFi Connected!");
|
|
Serial.print("IP: ");
|
|
Serial.println(WiFi.localIP());
|
|
lcd.clear();
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("WiFi Connected!");
|
|
|
|
config.api_key = API_KEY;
|
|
config.database_url = DATABASE_URL;
|
|
config.signer.tokens.legacy_token = LEGACY_TOKEN;
|
|
Firebase.begin(&config, &auth);
|
|
Firebase.reconnectWiFi(true);
|
|
|
|
updateKalibrasi();
|
|
delay(2000);
|
|
lcd.clear();
|
|
|
|
server.on("/", handleRoot);
|
|
server.begin();
|
|
Serial.println("WebServer ready at: " + WiFi.localIP().toString());
|
|
}
|
|
|
|
void loop() {
|
|
if (millis() - lastUpdate >= interval && Firebase.ready()) {
|
|
lastUpdate = millis();
|
|
|
|
updateKalibrasi();
|
|
|
|
ldrSebelum = smoothLDR(LDR_SEBELUM, ldrBufferSebelum);
|
|
ldrSesudah = smoothLDR(LDR_SESUDAH, ldrBufferSesudah);
|
|
bufferIndex = (bufferIndex + 1) % LDR_SMOOTH_COUNT;
|
|
|
|
feSebelum = (ldrSebelum * faktorKalibrasiSebelum) + offsetKalibrasiSebelum;
|
|
feSesudah = (ldrSesudah * faktorKalibrasiSesudah) + offsetKalibrasiSesudah;
|
|
|
|
feSebelum = constrain(feSebelum, 0.0, 10.0);
|
|
feSesudah = constrain(feSesudah, 0.0, 10.0);
|
|
|
|
Serial.println("===== SENSOR =====");
|
|
Serial.print("LDR Sebelum: "); Serial.println(ldrSebelum);
|
|
Serial.print("LDR Sesudah: "); Serial.println(ldrSesudah);
|
|
Serial.print("Fe Sebelum: "); Serial.println(feSebelum, 2);
|
|
Serial.print("Fe Sesudah: "); Serial.println(feSesudah, 2);
|
|
Serial.println("==================");
|
|
|
|
lcd.clear();
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("Fe Seb: ");
|
|
lcd.print(feSebelum, 2);
|
|
lcd.setCursor(0, 1);
|
|
lcd.print("Fe Ses: ");
|
|
lcd.print(feSesudah, 2);
|
|
|
|
sendDataToFirebase();
|
|
|
|
if (Firebase.RTDB.getBool(&fbdo, "/relay/pompa")) {
|
|
if (fbdo.dataType() == "boolean") {
|
|
bool statusRelay = fbdo.boolData();
|
|
digitalWrite(RELAY_PIN, statusRelay ? HIGH : LOW);
|
|
Serial.print("Relay: ");
|
|
Serial.println(statusRelay ? "ON" : "OFF");
|
|
}
|
|
}
|
|
}
|
|
|
|
server.handleClient();
|
|
}
|