#define BLYNK_TEMPLATE_ID "TMPL6d7c9QtJl"
#define BLYNK_TEMPLATE_NAME "SMART GARDEN IOT"
#define BLYNK_AUTH_TOKEN "7QM8-2j9ijIC-iu6H5ClhL15G1U75cSV"
#define BLYNK_FIRMWARE_VERSION "0.1.0"
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// Inisialisasi Lcd 20x4 I2C With Esp32 Devkit V1
LiquidCrystal_I2C lcd(0x27, 20, 4); // Change the I2C address if needed
// Initialize the RTC DS3231 module
RTC_DS1307 rtc;
//Inisialisasi Konfirguras Koneksi Wifi dengan Ssid And Pass
const char* ssid = "Wokwi-GUEST";
const char* pass = "";
// Definisikan pin RELAY Esp32 Devkit V1
#define RELAY1_Pin 23
#define RELAY2_Pin 19
#define RELAY3_Pin 18
bool relayActive = false; // Inisialisasi Status relay Pemupukan
// Definisikan Kontrol Manual & Otomatis Esp32 Devkit V1
int Mode=0; //Variabel Mode
int RelayValue=false;
// Definisikan pin sensor Soil Moisture Esp32 Devkit V1
#define SensorMoisture1 34 // Soil Moisture 1
int soilMoisture1Value; // Declare the variable
int soilmoisture1percent; // Declare the variable
#define SensorMoisture2 35 // Soil Moisture 2
int soilMoisture2Value; // Declare the variable
int soilmoisture2percent; // Declare the variable
#define SensorMoisture3 32 // Soil Moisture 3
int soilMoisture3Value; // Declare the variable
int soilmoisture3percent; // Declare the variable
#define SensorMoisture4 33 // Soil Moisture 4
int soilMoisture4Value; // Declare the variable
int soilmoisture4percent; // Declare the variable
#define SensorMoisture5 25 // Soil Moisture 5
int soilMoisture5Value; // Declare the variable
int soilmoisture5percent; // Declare the variable
#define SensorMoisture6 26 // Soil Moisture 6
int soilMoisture6Value; // Declare the variable
int soilmoisture6percent; // Declare the variable
#define AirValue 1023 // You need to replace this value with Value_1
#define WaterValue 4095 // You need to replace this value with Value_2
// Definisikan Pin Sensor flowmeter Esp32 Devkit V1
#define Waterflow1_Pin 13 // Sensor 1 pin connected to digital pin 2
#define Waterflow2_Pin 14 // Sensor 2 pin connected to digital pin 3
#define Waterflow3_Pin 12 // Sensor 3 pin connected to digital pin 4
volatile int pulseCount1;
volatile int pulseCount2;
volatile int pulseCount3;
float flowRate1;
float flowRate2;
float flowRate3;
unsigned int flowMilliLitres1;
unsigned int flowMilliLitres2;
unsigned int flowMilliLitres3;
unsigned long totalMilliLitres1;
unsigned long totalMilliLitres2;
unsigned long totalMilliLitres3;
unsigned long oldTime;
// Definisikan Pin Sensor PH Air Esp32 Devkit V1
#define pH_Water 15
float PH_Air = 0;
float PH_step;
int nilai_analog_PH;
double TeganganPh;
// Definisikan Pin Sensor Suhu DS18B20 Esp32 Devkit V1
#define ONE_WIRE_BUS_1 2 // Pin data untuk sensor pertama
#define ONE_WIRE_BUS_2 4 // Pin data untuk sensor kedua
OneWire oneWire1(ONE_WIRE_BUS_1);
OneWire oneWire2(ONE_WIRE_BUS_2);
DallasTemperature sensor1(&oneWire1);
DallasTemperature sensor2(&oneWire2);
BlynkTimer timer;
void Read_SoilMoisture() {
// Sensor Soil Moisture 1 Kebun 1 With Esp32 Devkit V1
soilMoisture1Value = analogRead(SensorMoisture1);
Serial.print("Nilai Analog Sensor 1 = ");
Serial.println(soilMoisture1Value);
soilmoisture1percent = map(soilMoisture1Value, WaterValue, AirValue, 0, 100);
Serial.print("Presentase kelembaban tanah Sensor 1= ");
Serial.print(soilmoisture1percent);
Serial.println("%");
// Sensor Soil Moisture 2 Kebun 1 With Esp32 Devkit V1
soilMoisture2Value = analogRead(SensorMoisture2);
Serial.print("Nilai Analog Sensor 2 = ");
Serial.println(soilMoisture2Value);
soilmoisture2percent = map(soilMoisture2Value, WaterValue, AirValue, 0, 100);
Serial.print("Presentase kelembaban tanah Sensor 2= ");
Serial.print(soilmoisture2percent);
Serial.println("%");
// Sensor Soil Moisture 3 Kebun 1 With Esp32 Devkit V1
soilMoisture3Value = analogRead(SensorMoisture3);
Serial.print("Nilai Analog Sensor 3 = ");
Serial.println(soilMoisture3Value);
soilmoisture3percent = map(soilMoisture3Value, WaterValue, AirValue, 0, 100);
Serial.print("Presentase kelembaban tanah Sensor 3= ");
Serial.print(soilmoisture3percent);
Serial.println("%");
// Inisialisasi Sistem Otomatis Penyiraman Pada Kebun 1 dengan Sistem Esp32 Devkit V1
if (soilmoisture1percent < 70) {
Blynk.logEvent("kelembapan_tanah_kebun_1", String("Garden 1 Low Humidity Detected by Sensor 1: ") + soilmoisture1percent);
}
if (soilmoisture2percent < 70) {
Blynk.logEvent("kelembapan_tanah_kebun_1", String("Garden 1 Low Humidity Detected by Sensor 2: ") + soilmoisture2percent);
}
if (soilmoisture3percent < 70) {
Blynk.logEvent("kelembapan_tanah_kebun_1", String("Garden 1 Low Humidity Detected by Sensor 3: ") + soilmoisture3percent);
}
// Periksa apakah kelembapan tanah Kebun 1 kurang dari 70%
if(Mode==0){
if (soilmoisture1percent < 70 && soilmoisture2percent < 70 && soilmoisture3percent < 70) {
digitalWrite(RELAY1_Pin, LOW);
} else {
digitalWrite(RELAY1_Pin, HIGH);
}
}
//Definisikan Menampilkan Data Monitoring Kebun 2 Ke LCD 20x4 I2C Esp32 Devkit V1
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("DATA WITH GARDEN 1");
lcd.setCursor(0, 1);
lcd.print("Moisture 1: ");
lcd.println(soilmoisture1percent); lcd.print(" %");
lcd.setCursor(0, 2);
lcd.print("Moisture 2: ");
lcd.println(soilmoisture2percent); lcd.print(" %");
lcd.setCursor(0, 3);
lcd.print("Moisture 3: ");
lcd.println(soilmoisture3percent); lcd.print(" %");
delay(10000);
//Definisikan Mengirim Data Sensor Soil Moisture Ke Blynk I.O.T Esp32 Devkit V1
Blynk.virtualWrite(V1, soilmoisture1percent);
Blynk.virtualWrite(V2, soilmoisture2percent);
Blynk.virtualWrite(V3, soilmoisture3percent);
// Sensor Soil Moisture 4 Kebun 2 With Esp32 Devkit V1
soilMoisture4Value = analogRead(SensorMoisture4);
Serial.print("Nilai Analog Sensor 4 = ");
Serial.println(soilMoisture4Value);
soilmoisture4percent = map(soilMoisture4Value, WaterValue, AirValue, 0, 100);
Serial.print("Presentase kelembaban tanah Sensor 4= ");
Serial.print(soilmoisture3percent);
Serial.println("%");
// Sensor Soil Moisture 5 Kebun 2 With Esp32 Devkit V1
soilMoisture5Value = analogRead(SensorMoisture5);
Serial.print("Nilai Analog Sensor 5 = ");
Serial.println(soilMoisture5Value);
soilmoisture5percent = map(soilMoisture5Value, WaterValue, AirValue, 0, 100);
Serial.print("Presentase kelembaban tanah Sensor 5= ");
Serial.print(soilmoisture5percent);
Serial.println("%");
// Sensor Soil Moisture 6 Kebun 2 With Esp32 Devkit V1
soilMoisture6Value = analogRead(SensorMoisture6);
Serial.print("Nilai Analog Sensor 6 = ");
Serial.println(soilMoisture6Value);
soilmoisture6percent = map(soilMoisture6Value, WaterValue, AirValue, 0, 100);
Serial.print("Presentase kelembaban tanah Sensor 6= ");
Serial.print(soilmoisture6percent);
Serial.println("%");
// Inisialisasi Sistem Otomatis Penyiraman Pada Kebun 2 dengan Sistem Esp32 Devkit V1
if (soilmoisture4percent < 70) {
Blynk.logEvent("kelembapan_tanah_kebun_2", String("Garden 2 Low Humidity Detected by Sensor 4: ") + soilmoisture4percent);
}
if (soilmoisture5percent < 70) {
Blynk.logEvent("kelembapan_tanah_kebun_2", String("Garden 2 Low Humidity Detected by Sensor 5: ") + soilmoisture5percent);
}
if (soilmoisture6percent < 70) {
Blynk.logEvent("kelembapan_tanah_kebun_2", String("Garden 2 Low Humidity Detected by Sensor 6: ") + soilmoisture6percent);
}
// Periksa apakah kelembapan tanah Kebun 2 kurang dari 70%
if(Mode==0){
if (soilmoisture4percent < 70 && soilmoisture5percent < 70 && soilmoisture6percent < 70) {
digitalWrite(RELAY2_Pin, LOW);
} else {
digitalWrite(RELAY2_Pin, HIGH);
}
}
//Definisikan Menampilkan Data Monitoring Kebun 2 Ke LCD 20x4 I2C Esp32 Devkit V1
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("DATA WITH GARDEN 2");
lcd.setCursor(0, 1);
lcd.print("Moisture 4: ");
lcd.println(soilmoisture4percent); lcd.print(" %");
lcd.setCursor(0, 2);
lcd.print("Moisture 5: ");
lcd.println(soilmoisture4percent); lcd.print(" %");
lcd.setCursor(0, 3);
lcd.print("Moisture 6: ");
lcd.println(soilmoisture4percent); lcd.print(" %");
delay(10000);
//Definisikan Mengirim Data Sensor Soil Moisture Ke Blynk I.O.T Esp32 Devkit V1
Blynk.virtualWrite(V4, soilmoisture4percent);
Blynk.virtualWrite(V5, soilmoisture5percent);
Blynk.virtualWrite(V6, soilmoisture6percent);
}
void Read_WaterFlow() {
// Sensor Waterflow Kebun 1 With Esp32 Devkit V1
unsigned long currentTime = millis();
if (currentTime - oldTime > 1000) {
detachInterrupt(digitalPinToInterrupt(Waterflow1_Pin));
detachInterrupt(digitalPinToInterrupt(Waterflow2_Pin));
detachInterrupt(digitalPinToInterrupt(Waterflow3_Pin));
flowRate1 = ((1000.0 / (currentTime - oldTime)) * pulseCount1) / 5.0;
flowMilliLitres1 = (flowRate1 / 60) * 1000;
totalMilliLitres1 += flowMilliLitres1;
flowRate2 = ((1000.0 / (currentTime - oldTime)) * pulseCount2) / 5.0;
flowMilliLitres2 = (flowRate2 / 60) * 1000;
totalMilliLitres2 += flowMilliLitres2;
flowRate3 = ((1000.0 / (currentTime - oldTime)) * pulseCount3) / 5.0;
flowMilliLitres3 = (flowRate3 / 60) * 1000;
totalMilliLitres3 += flowMilliLitres3;
unsigned int totalLitres1 = totalMilliLitres1 / 1000;
unsigned int totalLitres2 = totalMilliLitres2 / 1000;
unsigned int totalLitres3 = totalMilliLitres3 / 1000;
Serial.print("FlowMeter 1: ");
Serial.print(flowMilliLitres1); Serial.print(" ml/s\tTotal1: ");
Serial.print(totalLitres1); Serial.print(" L\t");
Serial.print("FlowMeter 2: ");
Serial.print(flowMilliLitres2); Serial.print(" ml/s\tTotal2: ");
Serial.print(totalLitres2); Serial.print(" L\t");
Serial.print("FlowMeter 3: ");
Serial.print(flowMilliLitres3); Serial.print(" ml/s\tTotal3: ");
Serial.print(totalLitres3); Serial.println(" L");
pulseCount1 = 0;
pulseCount2 = 0;
pulseCount3 = 0;
attachInterrupt(digitalPinToInterrupt(Waterflow1_Pin), pulseCounter1, RISING);
attachInterrupt(digitalPinToInterrupt(Waterflow2_Pin), pulseCounter2, RISING);
attachInterrupt(digitalPinToInterrupt(Waterflow3_Pin), pulseCounter3, RISING);
oldTime = currentTime;
//Definisikan Mengirim Data Sensor Soil Moisture Ke Blynk I.O.T Esp32 Devkit V1
Blynk.virtualWrite(V7, flowMilliLitres1);
Blynk.virtualWrite(V8, flowMilliLitres2);
Blynk.virtualWrite(V9, flowMilliLitres3);
}
}
void pulseCounter1() {
pulseCount1++;
}
void pulseCounter2() {
pulseCount2++;
}
void pulseCounter3() {
pulseCount3++;
}
void Read_WaterpH () {
int nilai_analog_PH = analogRead(pH_Water);
Serial.print("Nilai ADC Ph: ");
Serial.println(nilai_analog_PH);
TeganganPh = 5 / 1024.0 * nilai_analog_PH;
Serial.print("TeganganPh: ");
Serial.println(TeganganPh, 3);
PH_step = (3.1 - 2.6) / 3;
PH_Air = 7.00 + ((2.6 - TeganganPh) / PH_step);
Serial.print("Nilai PH cairan; ");
Serial.println(PH_Air, 2);
Blynk.virtualWrite(V10, PH_Air);
}
void Read_FertilizerTime() {
DateTime now = rtc.now();
// Cek apakah saat ini adalah pukul 7 pagi untuk melakukan pemupukan
if (now.hour() == 7 && now.minute() == 0 && now.second() == 0) {
// Cek apakah saat ini adalah tanggal 1
if (now.day() == 1) {
// Aktifkan relay jika belum aktif
if (!relayActive) {
digitalWrite(RELAY3_Pin, LOW);
relayActive = false;
}
// Tunggu 10 detik
delay(10000);
// Nonaktifkan relay setelah 10 detik
digitalWrite(RELAY3_Pin, HIGH);
relayActive = true;
}
}
// Cek apakah saat ini adalah pukul 7 pagi untuk melakukan pemupukan
if (now.hour() == 7 && now.minute() == 0 && now.second() == 0) {
// Cek apakah saat ini adalah tanggal 15
if (now.day() == 15) {
// Aktifkan relay jika belum aktif
if (!relayActive) {
digitalWrite(RELAY3_Pin, LOW);
relayActive = false;
}
// Tunggu 10 detik
delay(10000);
// Nonaktifkan relay setelah 10 detik
digitalWrite(RELAY3_Pin, HIGH);
relayActive = true;
}
}
}
void Read_SuhuDS18B20() {
sensor1.setResolution(9);
sensor1.requestTemperatures();
float temperature1 = sensor1.getTempCByIndex(0);
sensor2.setResolution(9);
sensor2.requestTemperatures();
float temperature2 = sensor2.getTempCByIndex(0);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("TEMPERATURE DATA");
lcd.setCursor(0, 1);
lcd.print("Suhu 1: ");
lcd.print(temperature1);
lcd.print(" C");
lcd.setCursor(0, 2);
lcd.print("Suhu 2: ");
lcd.print(temperature2);
lcd.print(" C");
delay(10000);
Serial.println("Temperature Sensor 1: " + String(temperature1) + " °C");
Serial.println("Temperature Sensor 2: " + String(temperature2) + " °C");
Blynk.virtualWrite(V11, temperature1); // Mengirim data suhu ke Widget V1 di Blynk
Blynk.virtualWrite(V12, temperature2); // Mengirim data suhu ke Widget V2 di Blynk
}
void setup() {
Serial.begin(115200); // Inisialisasi Serial Monitor Baudrate 115200
Wire.begin();
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass); //Reguler server
rtc.begin();
rtc.adjust(DateTime(2023, 10, 17, 2, 51, 0));// kalibrasi waktu
lcd.init(); // Initialize the LCD 20x4 I2C
lcd.backlight(); // Turn on the backlight
// Connecting to WiFi Serial Blynk
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
lcd.setCursor(1, 1);
lcd.print("Connecting to WiFi");
delay(2000);
lcd.clear();
}
Serial.println("WiFi Connected");
lcd.setCursor(3, 1);
lcd.print("WiFi Connected");
delay(2000);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("SMART GARDEN IOT");
lcd.setCursor(5, 1);
lcd.print("STRAWBERRY");
lcd.setCursor(3, 2);
lcd.print("SYSTEM IRIGASI");
lcd.setCursor(6, 3);
lcd.print("OTOMATIS");
delay(3000);
//Inisialisasi Sensor Soil Moisture Esp32 Devkit V1
pinMode(SensorMoisture1, INPUT);
pinMode(SensorMoisture2, INPUT);
pinMode(SensorMoisture3, INPUT);
pinMode(SensorMoisture4, INPUT);
pinMode(SensorMoisture5, INPUT);
pinMode(SensorMoisture6, INPUT);
//Inisialisasi Ouput RELAY With Esp32 Devkit V1
pinMode (RELAY1_Pin, OUTPUT);
pinMode (RELAY2_Pin, OUTPUT);
pinMode (RELAY3_Pin, OUTPUT);
digitalWrite(RELAY1_Pin, HIGH);
digitalWrite(RELAY2_Pin, HIGH);
digitalWrite(RELAY3_Pin, HIGH);
//Inisialisasi Waterflow Sensor 1 Esp32 Devkit V1
pinMode(Waterflow1_Pin, INPUT);
digitalWrite(Waterflow1_Pin, HIGH);
pulseCount1 = 0;
flowRate1 = 0.0;
flowMilliLitres1 = 0;
totalMilliLitres1 = 0;
//Inisialisasi Waterflow Sensor 2 Esp32 Devkit V1
pinMode(Waterflow2_Pin, INPUT);
digitalWrite(Waterflow2_Pin, HIGH);
pulseCount2 = 0;
flowRate2 = 0.0;
flowMilliLitres2 = 0;
totalMilliLitres2 = 0;
//Inisialisasi Waterflow Sensor 3 Esp32 Devkit V1
pinMode(Waterflow3_Pin, INPUT);
digitalWrite(Waterflow3_Pin, HIGH);
pulseCount3 = 0;
flowRate3 = 0.0;
flowMilliLitres3 = 0;
totalMilliLitres3 = 0;
oldTime = 0;
// Kalibrasi Sensor Waterflow Esp32 Devkit V1
attachInterrupt(digitalPinToInterrupt(Waterflow1_Pin), pulseCounter1, RISING);
attachInterrupt(digitalPinToInterrupt(Waterflow2_Pin), pulseCounter2, RISING);
attachInterrupt(digitalPinToInterrupt(Waterflow3_Pin), pulseCounter3, RISING);
//Inisialisasi Sensor Suhu DS18B20 Esp32 Devkit V1
pinMode(ONE_WIRE_BUS_1, INPUT);
pinMode(ONE_WIRE_BUS_2, INPUT);
}
void loop() {
Blynk.run(); // Initialize Blynk
timer.run(); // Initiates BlynkTimer
// Fungsikan Definisi Untuk Membaca Sensor Setiap 3 Detik Sekali
Read_SoilMoisture(); // Memanggil Perintah Pada Sensor Soil Moisture Esp32 Devkit V1
Read_WaterFlow(); // Memanggil Perintah Pada Sensor Waterflow Meter Esp32 Devkit V1
Read_WaterpH (); // Memanggil Perintah Pada Sensor pH Air Meter Esp32 Devkit V1
Read_FertilizerTime(); // Memanggil Perintah Sebagai Sistem Otomatis Pemupukan Meter Esp32 Devkit V1
Read_SuhuDS18B20(); // Memanggil Perintah Pada Sensor Suhu Kelembapan Tanah Esp32 Devkit V1
delay(3000);
}
BLYNK_WRITE(V0) { // BACA MODE DARI BLYNK
int RelayValue = param.asInt(); // assigning incoming value from pin V0 to a variable
int Mode=RelayValue;
// process received value
}
BLYNK_WRITE(V13) {
int RelayValue = param.asInt(); // assigning incoming value from pin V2 to a variable
if (Mode == 1) {
// Jalankan relay jika mode bukan 1
digitalWrite(RELAY1_Pin, RelayValue);
}
// process received value
digitalWrite(RELAY1_Pin, LOW);
}
BLYNK_WRITE(V14) {
int RelayValue = param.asInt(); // assigning incoming value from pin V2 to a variable
if (Mode == 1) {
// Jalankan relay jika mode bukan 1
digitalWrite(RELAY2_Pin, RelayValue);
}
// process received value
digitalWrite(RELAY2_Pin, LOW);
}
BLYNK_WRITE(V15) {
int RelayValue = param.asInt(); // assigning incoming value from pin V2 to a variable
if (Mode == 1) {
// Jalankan relay jika mode bukan 1
digitalWrite(RELAY3_Pin, RelayValue);
}
// process received value
digitalWrite(RELAY3_Pin, LOW);
}