#define BLYNK_TEMPLATE_ID "TMPL6gubuUsA2"
#define BLYNK_TEMPLATE_NAME "SMART PLANT WATERING PROJECT"
#define BLYNK_AUTH_TOKEN "v5kze5bCMFfgM1pYNdTDEKOz6IZvCFyS"
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <DHT.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// OLED Display settings
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// DHT11 Pin
#define DHTPIN D5
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
// Soil Moisture Sensor Pin
#define SOIL_MOISTURE_PIN A0
// Relay Pin for Water Pump
#define RELAY_PIN D7
// Button Pin for manual control
#define BUTTON_PIN D3
// WiFi credentials
char ssid[] = "Your_WiFi_SSID";
char pass[] = "Your_WiFi_Password";
// Blynk Auth Token
char auth[] = BLYNK_AUTH_TOKEN;
BlynkTimer timer;
bool pumpState = false; // Track pump state
bool manualOverride = false; // Track if manual control is active
// Function for Wi-Fi reconnection logic
void checkWiFi() {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Reconnecting to WiFi...");
WiFi.begin(ssid, pass);
}
}
void setup() {
// Initialize serial communication
Serial.begin(115200);
// Initialize Blynk
Blynk.begin(auth, ssid, pass);
// Initialize the DHT11 sensor
dht.begin();
// Set relay as output and button as input
pinMode(RELAY_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
digitalWrite(RELAY_PIN, LOW); // Start with the pump off
// Initialize OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Stop if display initialization fails
}
// Clear the buffer
display.clearDisplay();
display.display();
// Setup a function to be called every 5 seconds to read sensor data
timer.setInterval(5000L, sendSensorData);
// Check the button state every 100ms
timer.setInterval(100L, checkButton);
// Check Wi-Fi connection every 10 seconds
timer.setInterval(10000L, checkWiFi);
}
// Function to read and send sensor data to Blynk
void sendSensorData() {
if (!manualOverride) { // Only auto-control if manual mode is off
// Read the soil moisture value
int soilMoisture = analogRead(SOIL_MOISTURE_PIN);
soilMoisture = map(soilMoisture, 1023, 0, 0, 100); // Convert to percentage
// Read the temperature and humidity from DHT11
float temp = dht.readTemperature();
float humidity = dht.readHumidity();
// Check if readings are valid
if (isnan(temp) || isnan(humidity)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// Send the values to Blynk
Blynk.virtualWrite(V1, temp);
Blynk.virtualWrite(V2, humidity);
Blynk.virtualWrite(V3, soilMoisture);
// Auto-control water pump based on soil moisture
if (soilMoisture < 30 && !pumpState) { // If soil is dry and pump is off
digitalWrite(RELAY_PIN, HIGH); // Turn on water pump
pumpState = true;
} else if (soilMoisture >= 30 && pumpState) { // If soil is moist and pump is on
digitalWrite(RELAY_PIN, LOW); // Turn off water pump
pumpState = false;
}
}
// Display the sensor values on the OLED
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(F("Plant Watering System"));
display.setTextSize(1);
display.setCursor(0, 20);
display.print(F("Temp: "));
display.print(temp);
display.println(" *C");
display.setCursor(0, 30);
display.print(F("Humidity: "));
display.print(humidity);
display.println(" %");
display.setCursor(0, 40);
display.print(F("Soil Moisture: "));
display.print(soilMoisture);
display.println(" %");
display.setCursor(0, 50);
if (pumpState) {
display.println("Pump: ON");
} else {
display.println("Pump: OFF");
}
display.display(); // Show the data on the OLED
}
// Function to check button press for manual control of water pump
void checkButton() {
static bool lastButtonState = HIGH;
static unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50; // Debounce delay
bool buttonState = digitalRead(BUTTON_PIN);
// Check for state change and debounce
if (buttonState != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (buttonState == LOW) { // Button pressed
manualOverride = !manualOverride; // Toggle manual override
pumpState = !pumpState; // Toggle pump state
digitalWrite(RELAY_PIN, pumpState ? HIGH : LOW);
}
}
lastButtonState = buttonState;
}
// Blynk virtual write for manual control of relay from the app
BLYNK_WRITE(V4) {
int relayState = param.asInt();
pumpState = relayState; // Sync Blynk with the pump state
manualOverride = true; // Switch to manual control if Blynk sends a command
digitalWrite(RELAY_PIN, relayState);
}
void loop() {
Blynk.run();
timer.run();
}