138 lines
3.2 KiB
C++
138 lines
3.2 KiB
C++
#include <LiquidCrystal_I2C.h>
|
|
|
|
// Konfigurasi LCD
|
|
LiquidCrystal_I2C lcd(0x27, 20, 4); // LCD 20x4
|
|
|
|
// Pin sensor
|
|
const int pHpin = A0;
|
|
|
|
// Kalibrasi berdasarkan data aktual (pH = -6.90 * V + 28.15)
|
|
const float FIXED_SLOPE = -6.90;
|
|
const float FIXED_INTERCEPT = 28.15;
|
|
|
|
#define UKURAN_FILTER 10
|
|
float pembacaanpH[UKURAN_FILTER];
|
|
int indeksPembacaan = 0;
|
|
|
|
unsigned long waktuBacaTerakhir = 0;
|
|
const int intervalBaca = 1000;
|
|
unsigned long waktuKirimTerakhir = 0;
|
|
const int intervalKirim = 2000;
|
|
|
|
void setup() {
|
|
Serial.begin(9600);
|
|
lcd.init();
|
|
lcd.backlight();
|
|
lcd.clear();
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("Monitoring pH Meter");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print(" Feeder Automatic ");
|
|
delay(2000);
|
|
lcd.clear();
|
|
}
|
|
|
|
void loop() {
|
|
float tegangan = dapatkanTeganganRataRata();
|
|
float nilaipH = dapatkanpHStabil(tegangan);
|
|
|
|
if (millis() - waktuBacaTerakhir >= intervalBaca) {
|
|
waktuBacaTerakhir = millis();
|
|
tampilkanHasil(nilaipH);
|
|
}
|
|
|
|
if (millis() - waktuKirimTerakhir >= intervalKirim) {
|
|
waktuKirimTerakhir = millis();
|
|
kirimKeESP(nilaipH, tegangan);
|
|
}
|
|
}
|
|
|
|
float dapatkanTeganganRataRata() {
|
|
float total = 0;
|
|
for (int i = 0; i < 10; i++) {
|
|
total += analogRead(pHpin);
|
|
delay(10);
|
|
}
|
|
float tegangan = (total / 10.0) * (5.0 / 1023.0); // Sesuaikan dengan Vref 5V
|
|
return constrain(tegangan, 0, 5.0);
|
|
}
|
|
|
|
float dapatkanpHStabil(float tegangan) {
|
|
float pH = (FIXED_SLOPE * tegangan) + FIXED_INTERCEPT;
|
|
pembacaanpH[indeksPembacaan] = pH;
|
|
indeksPembacaan = (indeksPembacaan + 1) % UKURAN_FILTER;
|
|
|
|
float total = 0;
|
|
int jumlahValid = 0;
|
|
for (int i = 0; i < UKURAN_FILTER; i++) {
|
|
if (!isnan(pembacaanpH[i])) {
|
|
total += pembacaanpH[i];
|
|
jumlahValid++;
|
|
}
|
|
}
|
|
|
|
if (jumlahValid == 0) return pH;
|
|
float rataRatapH = total / jumlahValid;
|
|
if (isnan(rataRatapH) || rataRatapH < 0 || rataRatapH > 14) return pH;
|
|
return rataRatapH;
|
|
}
|
|
|
|
void tampilkanHasil(float pH) {
|
|
// Baris 1: Nilai pH
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("pH: ");
|
|
if (pH <= 0 || pH >= 14) {
|
|
lcd.print("Error ");
|
|
} else {
|
|
lcd.print(pH, 2); lcd.print(" ");
|
|
}
|
|
|
|
// Baris 2: Status Pompa
|
|
lcd.setCursor(0, 1);
|
|
if (pH < 6.5) {
|
|
lcd.print("Pump1:ON Pump2:OFF");
|
|
} else if (pH > 7.5) {
|
|
lcd.print("Pump1:OFF Pump2:ON ");
|
|
} else {
|
|
lcd.print("Pump1:OFF Pump2:OFF");
|
|
}
|
|
|
|
// Baris 3: Rentang pH
|
|
lcd.setCursor(0, 2);
|
|
if (pH <= 0 || pH >= 14) {
|
|
lcd.print("Rentang: -- ");
|
|
} else if (pH < 3.0) {
|
|
lcd.print("Rentang: 0.0 - 2.9");
|
|
} else if (pH < 6.5) {
|
|
lcd.print("Rentang: 3.0 - 6.4");
|
|
} else if (pH < 7.5) {
|
|
lcd.print("Rentang: 6.5 - 7.4");
|
|
} else if (pH < 9.0) {
|
|
lcd.print("Rentang: 7.5 - 8.9");
|
|
} else {
|
|
lcd.print("Rentang: 9.0 - 14.0");
|
|
}
|
|
|
|
// Baris 4: Kategori pH
|
|
lcd.setCursor(0, 3);
|
|
if (pH <= 0 || pH >= 14) {
|
|
lcd.print("Kategori:Tidak Valid ");
|
|
} else if (pH < 3.0) {
|
|
lcd.print("Kategori:Sangat Asam ");
|
|
} else if (pH < 6.5) {
|
|
lcd.print("Kategori:Asam ");
|
|
} else if (pH < 7.5) {
|
|
lcd.print("Kategori:Netral ");
|
|
} else if (pH < 9.0) {
|
|
lcd.print("Kategori:Basa ");
|
|
} else {
|
|
lcd.print("Kategori:Sangat Basa ");
|
|
}
|
|
}
|
|
|
|
void kirimKeESP(float pH, float volt) {
|
|
Serial.print(pH, 2);
|
|
Serial.print(",");
|
|
Serial.println(volt, 3);
|
|
}
|