#define BLYNK_TEMPLATE_ID "TMPL6MLdO5QpM"
#define BLYNK_TEMPLATE_NAME "Smart Garden"
#define BLYNK_AUTH_TOKEN "StGoVOeFgKfjBp3HF89p16uyhzZOAHll"
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <ESP32Servo.h>
#include <LiquidCrystal_I2C.h>
#include <DHTesp.h>
#include <PubSubClient.h>
// Define WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// MQTT Broker
const char* mqtt_server = "broker.mqtthq.com"; // Change to MQTTHQ broker URL
const int mqtt_port = 1883; // Default port
const char* mqtt_user = ""; // Leave empty if not required by the broker
const char* mqtt_password = ""; // Leave empty if not required by the broker
// MQTT Topics
const char* temp_topic = "smartgarden/temperature";
const char* humidity_topic = "smartgarden/humidity";
const char* light_topic = "smartgarden/light";
// Pins
LiquidCrystal_I2C LCD(0x27, 16, 2);
const int redLedPin = 2;
const int greenLedPin = 4;
const int servoPin = 18;
const int DHT_pin = 15;
const int photoresistor_pin = 32;
// Components
Servo myServo;
DHTesp dhtSensor;
WiFiClient espClient;
PubSubClient client(espClient);
// Constants
const float GAMMA = 0.7;
const float RL10 = 50.0;
void setup() {
Serial.begin(115200);
pinMode(redLedPin, OUTPUT);
pinMode(greenLedPin, OUTPUT);
pinMode(photoresistor_pin, INPUT);
myServo.attach(servoPin);
dhtSensor.setup(DHT_pin, DHTesp::DHT22);
LCD.init();
LCD.setCursor(2, 0);
LCD.print("SMART GARDEN");
delay(5000);
LCD.clear();
// Connect to Wi-Fi and Blynk
LCD.setCursor(0, 0);
LCD.print("WIFI: ");
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
LCD.print(".");
}
LCD.setCursor(5, 0);
LCD.println(" Connected!");
delay(2000);
LCD.clear();
LCD.setCursor(0, 1);
LCD.print("BLYNK: ");
while (!Blynk.connected()) {
delay(500);
LCD.print(".");
}
LCD.setCursor(5, 1);
LCD.println(" Connected!");
delay(2000);
LCD.clear();
// Set up MQTT
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
connectToMQTT();
}
void connectToMQTT() {
while (!client.connected()) {
Serial.print("Connecting to MQTT...");
if (client.connect("ESP32Client", mqtt_user, mqtt_password)) {
Serial.println("connected");
// Subscribe to topics if needed
// client.subscribe("inTopic");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void callback(char* topic, byte* message, unsigned int length) {
// Handle incoming messages here
}
void publishData(const char* topic, float data) {
char msg[50];
dtostrf(data, 1, 2, msg);
client.publish(topic, msg);
}
// Blynk virtual pin handlers
BLYNK_WRITE(V1) { // V1 adalah pin virtual untuk mengontrol servo
int value = param.asInt();
if (value == 1) {
Serial.println("servo");
for (int pos = 0; pos <= 180; pos += 1) {
myServo.write(pos);
delay(15);
}
}
}
BLYNK_WRITE(V2) { // V2 adalah pin virtual untuk mengontrol LED
int value = param.asInt();
if (value == 1) {
digitalWrite(greenLedPin, HIGH);
digitalWrite(redLedPin, LOW);
} else if (value == 0) {
digitalWrite(redLedPin, HIGH);
digitalWrite(greenLedPin, LOW);
}
}
void loop() {
Blynk.run();
client.loop();
if (!client.connected()) {
connectToMQTT();
}
// Membaca data dari sensor DHT22
TempAndHumidity data = dhtSensor.getTempAndHumidity();
float humidity = data.humidity; // Kelembaban dalam persen
// Membaca intensitas cahaya dari fotoresistor
int analogValue = analogRead(photoresistor_pin) / 4;
float voltage = analogValue / 1024.0 * 5;
float resistance = 2000 * voltage / (1 - voltage / 5);
float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
// Tampilkan data pada LCD
LCD.setCursor(0, 0);
LCD.print("Humidity: " + String(humidity, 1) + "%");
LCD.setCursor(0, 1);
LCD.print("Light: " + String(lux, 1) + " lux");
// Kirim data ke Blynk dan MQTT
Blynk.virtualWrite(V4, humidity); // V4 untuk kelembaban
Blynk.virtualWrite(V5, lux); // V5 untuk intensitas cahaya
publishData(humidity_topic, humidity);
publishData(light_topic, lux);
// Logika kontrol servo berdasarkan kelembaban
if (humidity > 60.0) { // Threshold kelembaban > 60%
myServo.write(0); // Servo ke posisi 0° (tutup penutup)
Serial.println("Keran Ditutup: Kelembaban Tinggi.");
} else if (humidity < 40.0) { // Threshold kelembaban < 40%
myServo.write(90); // Servo ke posisi 90° (buka penutup)
Serial.println("Keran Dibuka: Kelembaban Rendah.");
}
// Logika kontrol LED berdasarkan intensitas cahaya
if (lux < 100) { // Threshold intensitas cahaya rendah (< 100 lux)
digitalWrite(greenLedPin, HIGH); // LED hijau menyala
Serial.println("Lampu Menyala: Gelap.");
} else { // Intensitas cahaya tinggi
digitalWrite(greenLedPin, LOW); // LED hijau mati
Serial.println("Lampu Mati: Terang.");
}
delay(2000); // Tunggu 2 detik sebelum iterasi berikutnya
}