#include #include #include #include #include #include // Inisialisasi LCD dengan alamat I2C 0x27, 16 kolom dan 2 baris LiquidCrystal_I2C lcd(0x27, 16, 2); // Data wire pin (D4 pada ESP8266) const int ONE_WIRE_BUS = 2; // Pin sensor pH (D6 pada ESP8266) const int PH_SENSOR_PIN = 12; // Pin relay untuk mengendalikan pompa (D5 pada ESP8266) const int RELAY_PIN = 14; // Pin sensor TDS (A0 pada ESP8266) const int TdsSensorPin = A0; // Pin sensor DHT (D0 pada ESP8266) #define DHTPIN 13 #define DHTTYPE DHT11 #define VREF 3.3 // Tegangan referensi pada ADC #define SCOUNT 30 // Jumlah sampel int analogBuffer[SCOUNT]; // Menyimpan nilai analog dalam array, dibaca dari ADC int analogBufferTemp[SCOUNT]; int analogBufferIndex = 0; int copyIndex = 0; float averageVoltage = 0; float tdsValue = 0; float temperatureDS18B20 = 25; // Nilai suhu asumsi, bisa diganti dengan pembacaan sensor suhu aktual // Batas pH yang dianggap kurang nutrisi (sesuaikan dengan kebutuhan tanaman) const float PH_THRESHOLD = 5.5; // Setup oneWire instance untuk berkomunikasi dengan sensor OneWire oneWire(ONE_WIRE_BUS); // Setup DallasTemperature library DallasTemperature sensors(&oneWire); // Setup DHT sensor DHT dht(DHTPIN, DHTTYPE); unsigned long previousMillis = 0; const long interval = 2000; // Interval waktu antar tampilan (2 detik) bool showFirstScreen = true; // Penanda untuk tampilan pertama void setup() { // Inisialisasi Serial Monitor Serial.begin(115200); // Inisialisasi LCD lcd.init(); lcd.backlight(); // Menampilkan pesan awal di LCD lcd.setCursor(0, 0); lcd.print("Inisialisasi..."); delay(2000); // Tampilkan pesan awal selama 2 detik lcd.clear(); // Inisialisasi sensor suhu DS18B20 sensors.begin(); // Inisialisasi sensor DHT dht.begin(); // Inisialisasi pin relay sebagai output pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, LOW); // Matikan relay (pompa) saat memulai // Inisialisasi pin sensor pH sebagai input pinMode(PH_SENSOR_PIN, INPUT); } void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; showFirstScreen = !showFirstScreen; // Ganti tampilan setiap 2 detik } // Membaca suhu dari sensor DS18B20 sensors.requestTemperatures(); float temperatureDS18B20 = sensors.getTempCByIndex(0); // Membaca nilai dari sensor pH int phValue = digitalRead(PH_SENSOR_PIN); float pH = (phValue == HIGH) ? 7.0 : 4.0; // Konversi sederhana nilai digitalRead ke pH // Membaca nilai dari sensor TDS static unsigned long analogSampleTimepoint = millis(); if (millis() - analogSampleTimepoint > 10U) { analogSampleTimepoint = millis(); analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin); analogBufferIndex++; if (analogBufferIndex == SCOUNT) { analogBufferIndex = 0; } } static unsigned long printTimepoint = millis(); if (millis() - printTimepoint > 10U) { printTimepoint = millis(); for (copyIndex = 0; copyIndex < SCOUNT; copyIndex++) { analogBufferTemp[copyIndex] = analogBuffer[copyIndex]; } averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0; tdsValue = (133.42 * averageVoltage * averageVoltage * averageVoltage - 255.86 * averageVoltage * averageVoltage + 857.39 * averageVoltage) * 0.5; // Rumus nilai TDS // Logika untuk mengendalikan relay berdasarkan nilai TDS if (tdsValue < 100) { // TDS rendah, hidupkan relay (pompa) untuk menambahkan nutrisi digitalWrite(RELAY_PIN, LOW); Serial.println("Pompa ON - Menambahkan nutrisi"); } else { // TDS dalam rentang ideal atau tinggi, matikan relay (pompa) digitalWrite(RELAY_PIN, HIGH); Serial.println("Pompa OFF - Nutrisi cukup atau TDS tinggi"); } } // Membaca nilai dari sensor DHT float temperatureDHT = dht.readTemperature(); float humidityDHT = dht.readHumidity(); // Menampilkan informasi di LCD berdasarkan tampilan yang dipilih lcd.clear(); if (showFirstScreen) { // Tampilan pertama: pH dan TDS lcd.setCursor(0, 0); lcd.print("pH: "); lcd.print(pH); lcd.setCursor(0, 1); lcd.print("TDS: "); lcd.print(tdsValue); lcd.print("ppm"); } else { // Tampilan kedua: suhu DS18B20, suhu DHT, dan kelembapan DHT lcd.setCursor(0, 0); lcd.print("Suhu Air: "); lcd.print(temperatureDS18B20); lcd.print("C"); lcd.setCursor(0, 1); lcd.print("DHT: "); lcd.print(temperatureDHT); lcd.print("C "); lcd.print(humidityDHT); lcd.print("%"); } // Menampilkan informasi pada Serial Monitor Serial.print("Suhu DS18B20: "); Serial.print(temperatureDS18B20); Serial.println(" C"); Serial.print("Suhu DHT: "); Serial.print(temperatureDHT); Serial.println(" C"); Serial.print("Kelembapan DHT: "); Serial.print(humidityDHT); Serial.println(" %"); Serial.print("pH: "); Serial.println(pH); Serial.print("TDS Value: "); Serial.print(tdsValue); Serial.println(" ppm"); delay(1000); // Delay untuk pembacaan sensor } int getMedianNum(int bArray[], int iFilterLen) { int bTab[iFilterLen]; for (byte i = 0; i < iFilterLen; i++) bTab[i] = bArray[i]; int i, j, bTemp; for (j = 0; j < iFilterLen - 1; j++) { for (i = 0; i < iFilterLen - j - 1; i++) { if (bTab[i] > bTab[i + 1]) { bTemp = bTab[i]; bTab[i] = bTab[i + 1]; bTab[i + 1] = bTemp; } } } if ((iFilterLen & 1) > 0) { bTemp = bTab[(iFilterLen - 1) / 2]; } else { bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2; } return bTemp; }