TKK_E32222628/sketch_jul31b/sketch_jul31b.ino

219 lines
5.9 KiB
C++

#include <WiFi.h>
#include <FirebaseESP32.h> // Gunakan library "Firebase ESP32 Client" by Mobizt
#define RXD2 16 // RX pin ESP32
#define TXD2 17 // TX pin ESP32
// WiFi credentials
#define WIFI_SSID "hydrop"
#define WIFI_PASSWORD "123123123"
// Firebase config
#define FIREBASE_HOST "https://hydrop-a1e64-default-rtdb.firebaseio.com"
#define FIREBASE_AUTH "4lJpDHPo9LGh6WCYpjs1aRB6ABJZwHLOXkaCoLAV"
// Firebase objects
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;
struct SensorData {
float temperature;
float humidity;
float ph;
float tds;
bool tempValid;
bool humValid;
bool phValid;
bool tdsValid;
unsigned long lastUpdate;
} sensorData;
struct CommStats {
unsigned long totalReceived;
unsigned long validData;
unsigned long errorData;
unsigned long lastReceived;
} commStats = {0, 0, 0, 0};
const unsigned long DATA_TIMEOUT = 10000;
const unsigned long STATS_INTERVAL = 30000;
void setup() {
Serial.begin(115200);
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
// Koneksi WiFi
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("\nWiFi connected!");
// Konfigurasi Firebase
config.database_url = FIREBASE_HOST;
config.signer.tokens.legacy_token = FIREBASE_AUTH;
Firebase.begin(&config, &auth);
Firebase.reconnectWiFi(true);
Serial.println("Firebase initialized.");
sensorData = {0, 0, 0, 0, false, false, false, false, 0};
Serial.println("=== ESP32 Hydroponic Receiver ===");
Serial.println("Menunggu data dari Arduino...");
}
void loop() {
if (Serial2.available()) {
String rawData = Serial2.readStringUntil('\n');
rawData.trim();
commStats.totalReceived++;
commStats.lastReceived = millis();
if (parseAndValidateData(rawData)) {
commStats.validData++;
sensorData.lastUpdate = millis();
displaySensorData();
sendToFirebase();
} else {
commStats.errorData++;
Serial.print("ERROR: Invalid data format: ");
Serial.println(rawData);
}
}
checkDataTimeout();
displayStats();
delay(100);
}
bool parseAndValidateData(String data) {
if (data.length() < 5) return false;
int idx1 = data.indexOf(',');
int idx2 = data.indexOf(',', idx1 + 1);
int idx3 = data.indexOf(',', idx2 + 1);
if (idx1 <= 0 || idx2 <= 0 || idx3 <= 0) return false;
String tempStr = data.substring(0, idx1);
String humStr = data.substring(idx1 + 1, idx2);
String phStr = data.substring(idx2 + 1, idx3);
String tdsStr = data.substring(idx3 + 1);
float temp = tempStr.toFloat();
float hum = humStr.toFloat();
float ph = phStr.toFloat();
float tds = tdsStr.toFloat();
sensorData.temperature = temp;
sensorData.humidity = hum;
sensorData.ph = ph;
sensorData.tds = tds;
sensorData.tempValid = validateTemperature(temp);
sensorData.humValid = validateHumidity(hum);
sensorData.phValid = validatePH(ph);
sensorData.tdsValid = validateTDS(tds);
return (sensorData.tempValid || sensorData.humValid || sensorData.phValid || sensorData.tdsValid);
}
void sendToFirebase() {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi disconnected, skipping Firebase upload.");
return;
}
FirebaseJson json;
json.set("temperature", sensorData.tempValid ? sensorData.temperature : -999);
json.set("humidity", sensorData.humValid ? sensorData.humidity : -999);
json.set("ph", sensorData.phValid ? sensorData.ph : -999);
json.set("tds", sensorData.tdsValid ? sensorData.tds : -999);
json.set("timestamp", millis());
if (Firebase.updateNode(fbdo, "/sensorData", json)) {
Serial.println("Data sent to Firebase.");
} else {
Serial.print("Firebase failed: ");
Serial.println(fbdo.errorReason());
}
}
bool validateTemperature(float temp) {
return temp != -999 && temp >= -10 && temp <= 60;
}
bool validateHumidity(float hum) {
return hum != -999 && hum >= 0 && hum <= 100;
}
bool validatePH(float ph) {
return ph != -999 && ph >= 0 && ph <= 14;
}
bool validateTDS(float tds) {
return tds != -999 && tds >= 0 && tds <= 3000;
}
void displaySensorData() {
Serial.println("=== SENSOR DATA RECEIVED ===");
Serial.print("Temperature: ");
Serial.println(sensorData.tempValid ? String(sensorData.temperature, 2) + " °C" : "INVALID");
Serial.print("Humidity: ");
Serial.println(sensorData.humValid ? String(sensorData.humidity, 2) + " %" : "INVALID");
Serial.print("pH: ");
Serial.println(sensorData.phValid ? String(sensorData.ph, 2) : "INVALID");
Serial.print("TDS: ");
Serial.println(sensorData.tdsValid ? String(sensorData.tds, 0) + " ppm" : "INVALID");
Serial.println("===========================");
}
void checkDataTimeout() {
static unsigned long lastTimeoutCheck = 0;
if (millis() - lastTimeoutCheck >= 5000) {
if (sensorData.lastUpdate > 0 && (millis() - sensorData.lastUpdate) > DATA_TIMEOUT) {
Serial.println("⚠️ WARNING: No valid data for 10 seconds!");
sensorData.tempValid = false;
sensorData.humValid = false;
sensorData.phValid = false;
sensorData.tdsValid = false;
}
lastTimeoutCheck = millis();
}
}
void displayStats() {
static unsigned long lastStatsDisplay = 0;
if (millis() - lastStatsDisplay >= STATS_INTERVAL) {
Serial.println("=== STATISTIK KOMUNIKASI ===");
Serial.print("Total diterima: ");
Serial.println(commStats.totalReceived);
Serial.print("Valid: ");
Serial.println(commStats.validData);
Serial.print("Error: ");
Serial.println(commStats.errorData);
if (commStats.totalReceived > 0) {
float success = (float)commStats.validData / commStats.totalReceived * 100;
Serial.print("Success rate: ");
Serial.print(success, 1);
Serial.println(" %");
}
Serial.print("Terakhir diterima: ");
Serial.println((millis() - commStats.lastReceived) / 1000);
Serial.println("=============================");
lastStatsDisplay = millis();
}
}