#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
// Bagian pin pada sensor
const int sensor_suhu = 13;
// Inisialisasi DS18B20
OneWire oneWire(sensor_suhu);
DallasTemperature sensors(&oneWire);
const int sensor_ph = 32;
const int sensor_salinitas = 33;
const int sensor_tds = 34;
// Variabel nilai sensor
float val_sensor_suhu = 0;
float val_sensor_ph = 0; // ubah ke float
int val_sensor_salinitas = 0;
int val_sensor_tds = 0;
// Rentang nilai sensor yang diizinkan
const float suhu_min = 27.0;
const float suhu_max = 34.0;
const float ph_min = 6.0; // ubah ke float
const float ph_max = 9.0; // ubah ke float
const int salinitas_min = 27;
const int salinitas_max = 35;
const int tds_min = 800;
const int tds_max = 1000;
// Bagian pin button
const int power = 12;
// Inisialisasi button
bool power_state = false;
bool last_power_state = LOW; // Ubah dari HIGH ke LOW untuk logika aktif high
const int pelampung_bawah = 4;
const int pelampung_atas = 2;
// Bagian Output
const int supply_pump = 15;
const int filter_pump = 23;
const int bottom_valve = 25;
const int supply_valve = 26;
const int drain_valve = 27;
// Bagian LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
String lcdMessage = "";
String lcdDisplay = "";
int scrollPosition = 0;
// Bagian millis
const unsigned long readInterval = 1000; // Baca serial monitor
unsigned long previousMillisRead = 0;
unsigned long powerOnTime = 0; // Untuk toggle power
const unsigned long relayDelay1 = 10000; // 10 detik
const unsigned long relayDelay2 = 5000; // 5 detik
// Variabel untuk menghitung siklus
int cycleCount = 0;
const int maxCycles = 4;
bool completedCycles = false;
void setup() {
Serial.begin(115200);
sensors.begin();
// Bagian input
pinMode(power, INPUT_PULLUP);
pinMode(pelampung_bawah, INPUT_PULLUP);
pinMode(pelampung_atas, INPUT_PULLUP);
pinMode(sensor_suhu, INPUT);
pinMode(sensor_ph, INPUT);
pinMode(sensor_salinitas, INPUT);
pinMode(sensor_tds, INPUT);
// Bagian output, ubah ke HIGH (aktif high)
pinMode(supply_pump, OUTPUT);
pinMode(filter_pump, OUTPUT);
pinMode(bottom_valve, OUTPUT);
pinMode(drain_valve, OUTPUT);
pinMode(supply_valve, OUTPUT);
// Set output to HIGH (inactive state)
digitalWrite(supply_pump, HIGH);
digitalWrite(filter_pump, HIGH);
digitalWrite(bottom_valve, HIGH);
digitalWrite(drain_valve, HIGH);
digitalWrite(supply_valve, HIGH);
// Bagian LCD awal
lcd.init();
lcd.backlight();
lcd.setCursor(1, 0);
lcd.print("Embeded System");
lcd.setCursor(3, 1);
lcd.print("AzizSyah");
delay(2000);
lcd.clear();
}
void saklar_power() {
bool current_power_state = digitalRead(power);
if (current_power_state == HIGH && last_power_state == LOW) { // Ubah dari LOW ke HIGH untuk logika aktif high
power_state = !power_state;
delay(50);
powerOnTime = millis();
cycleCount = 0;
completedCycles = false;
}
last_power_state = current_power_state;
}
int baca_analog(int pin) {
const int numReadings = 10;
int total = 0;
for (int i = 0; i < numReadings; i++) {
total += analogRead(pin);
delay(10); // Jeda 10ms antara setiap pembacaan
}
return total / numReadings;
}
void baca_sensor() {
// Bagian sensor suhu:
sensors.requestTemperatures(); // Request temperature from DS18B20
val_sensor_suhu = sensors.getTempCByIndex(0);
// Tambahkan jeda antara pembacaan sensor
delay(100);
// Bagian sensor ph
int adc_ph = baca_analog(sensor_ph);
val_sensor_ph = map(adc_ph, 0, 4095, 0, 14);
// Tambahkan jeda antara pembacaan sensor
delay(100);
// Bagian sensor salinitas
val_sensor_salinitas = baca_analog(sensor_salinitas);
val_sensor_salinitas = map(val_sensor_salinitas, 0, 4095, 0, 100);
// Tambahkan jeda antara pembacaan sensor
delay(100);
// Bagian sensor tds
val_sensor_tds = baca_analog(sensor_tds);
val_sensor_tds = map(val_sensor_tds, 0, 4095, 0, 1000);
}
bool cek_rentang_sensor() {
return (val_sensor_suhu >= suhu_min && val_sensor_suhu <= suhu_max) &&
(val_sensor_ph >= ph_min && val_sensor_ph <= ph_max) &&
(val_sensor_salinitas >= salinitas_min && val_sensor_salinitas <= salinitas_max) &&
(val_sensor_tds >= tds_min && val_sensor_tds <= tds_max);
}
void update_lcd() {
if (power_state) {
// Menggeser teks jika panjang pesan lebih dari panjang layar LCD
int messageLength = lcdMessage.length();
if (messageLength > 16) {
scrollPosition++;
if (scrollPosition >= messageLength) {
scrollPosition = 0;
}
lcdDisplay = lcdMessage.substring(scrollPosition);
if (lcdDisplay.length() < 16) {
lcdDisplay += lcdMessage.substring(0, 16 - lcdDisplay.length());
}
lcd.setCursor(0, 0);
lcd.print(lcdDisplay);
} else {
lcd.setCursor(0, 0);
lcd.print(lcdMessage);
}
} else {
lcd.setCursor(0, 0);
lcd.print("Depurasi Standby ");
}
}
void relayControl() {
unsigned long currentMillis = millis();
if (power_state && !completedCycles) {
if (cycleCount < maxCycles) {
if (currentMillis - powerOnTime < relayDelay1) {
// Langkah 1: Matikan pompa dan katup (aktif high)
digitalWrite(supply_pump, HIGH);
digitalWrite(filter_pump, HIGH);
digitalWrite(bottom_valve, HIGH);
digitalWrite(drain_valve, LOW);
digitalWrite(supply_valve, LOW);
} else if (currentMillis - powerOnTime < relayDelay1 + relayDelay2) {
// Langkah 2: Aktifkan drain valve selama 5 detik
digitalWrite(supply_pump, HIGH);
digitalWrite(filter_pump, HIGH);
digitalWrite(bottom_valve, HIGH);
digitalWrite(drain_valve, HIGH);
digitalWrite(supply_valve, HIGH);
} else if (currentMillis - powerOnTime < relayDelay1 + 2 * relayDelay2) {
// Langkah 3: Matikan supply valve dan supply pump, aktifkan drain valve selama 5 detik
digitalWrite(supply_pump, HIGH);
digitalWrite(filter_pump, HIGH);
digitalWrite(bottom_valve, HIGH);
digitalWrite(drain_valve, HIGH);
digitalWrite(supply_valve, HIGH);
} else {
// Langkah 4: Aktifkan supply valve, matikan drain valve, aktifkan pompa dan katup lainnya
digitalWrite(supply_pump, LOW);
digitalWrite(filter_pump, HIGH);
digitalWrite(bottom_valve, HIGH);
digitalWrite(drain_valve, HIGH);
digitalWrite(supply_valve, LOW);
powerOnTime = currentMillis; // Reset waktu siklus
cycleCount++;
}
} else {
// Matikan semua output kecuali drain valve jika siklus telah tercapai
digitalWrite(supply_pump, HIGH);
digitalWrite(filter_pump, HIGH);
digitalWrite(bottom_valve, HIGH);
digitalWrite(drain_valve, HIGH);
digitalWrite(supply_valve, HIGH);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Depurasi Selesai");
completedCycles = true;
}
} else {
// Pastikan semua output dalam keadaan nonaktif (aktif high)
digitalWrite(supply_pump, HIGH);
digitalWrite(filter_pump, HIGH);
digitalWrite(bottom_valve, HIGH);
digitalWrite(drain_valve, HIGH);
digitalWrite(supply_valve, HIGH);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Depurasi Standby");
}
}
void loop() {
unsigned long currentMillis = millis();
saklar_power();
if (power_state && cycleCount < maxCycles) {
if (currentMillis - previousMillisRead >= readInterval) {
previousMillisRead = currentMillis;
baca_sensor();
// Siapkan pesan untuk LCD dan serial monitor
lcdMessage = "T:" + String(val_sensor_suhu) + "C pH:" + String(val_sensor_ph) + " Sal:" + String(val_sensor_salinitas) + " TDS:" + String(val_sensor_tds) + " ";
// Tampilkan pada serial monitor
Serial.print("Temp :");
Serial.print(val_sensor_suhu);
Serial.print(" pH :");
Serial.print(val_sensor_ph);
Serial.print(" Sal :");
Serial.print(val_sensor_salinitas);
Serial.print(" Tds :");
Serial.print(val_sensor_tds);
Serial.println("");
delay(500); // Tambahkan delay agar data pada serial monitor terbaca dengan jelas
}
// Tampilkan pesan sensor ke LCD
update_lcd();
// Cek rentang sensor
if (!cek_rentang_sensor()) {
// Matikan pompa dan katup sampai nilai sensor dalam rentang yang diizinkan
digitalWrite(supply_pump, HIGH);
digitalWrite(supply_valve, HIGH);
digitalWrite(drain_valve, HIGH);
digitalWrite(filter_pump, HIGH);
digitalWrite(bottom_valve, HIGH);
} else {
// Lanjutkan kontrol relay seperti biasa
relayControl();
}
} else if (!power_state) {
lcd.setCursor(0, 0);
lcd.print("Depurasi Standby");
} else if (cycleCount >= maxCycles) {
// Setelah siklus selesai
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Depurasi Selesai");
digitalWrite(supply_pump, HIGH);
digitalWrite(filter_pump, HIGH);
digitalWrite(bottom_valve, HIGH);
digitalWrite(drain_valve, HIGH);
digitalWrite(supply_valve, HIGH);
}
}