#define BLYNK_TEMPLATE_ID "TMPL3Q9Fx6F5T"
#define BLYNK_TEMPLATE_NAME "Smart Agriculture"
#define BLYNK_AUTH_TOKEN "CmKpgh_S01IS1lC7nsSltnhsJd1fkgRt"
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#define MOISTURE_PIN 34
#define NUTRIENT_PIN 35
#define RELAY_PIN 26
#define STATUS_LED 25
#define FERT_LED 27
#define BUTTON_PIN 14
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
bool autoMode = true;
int moistureThreshold = 2500;
int nutrientThreshold = 2500;
String apiKey = "NQGKD7KFMW02V3TG";
const char* server = "api.thingspeak.com";
WiFiClient client;
BlynkTimer timer;
// ---------------- BLYNK CONTROLS ----------------
BLYNK_WRITE(V2) { // Relay control (manual)
if (!autoMode) {
int state = param.asInt();
digitalWrite(RELAY_PIN, state);
}
}
BLYNK_WRITE(V3) { // Mode switch
autoMode = param.asInt() == 0 ? true : false;
}
// ---------------- SENSOR + LOGIC ----------------
void sendData() {
int moisture = analogRead(MOISTURE_PIN);
int nutrient = analogRead(NUTRIENT_PIN);
int moisturePercent = map(moisture, 0, 4095, 100, 0);
Serial.println("------ SENSOR DATA ------");
Serial.println(moisture);
Serial.println(nutrient);
// -------- AUTO MODE --------
if (autoMode) {
if (moisture < moistureThreshold) {
digitalWrite(RELAY_PIN, HIGH);
digitalWrite(STATUS_LED, HIGH);
} else {
digitalWrite(RELAY_PIN, LOW);
digitalWrite(STATUS_LED, LOW);
}
if (nutrient < nutrientThreshold) {
digitalWrite(FERT_LED, HIGH);
Blynk.virtualWrite(V4, 255);
} else {
digitalWrite(FERT_LED, LOW);
Blynk.virtualWrite(V4, 0);
}
}
// -------- BLYNK UPDATE --------
Blynk.virtualWrite(V0, moisturePercent);
Blynk.virtualWrite(V1, nutrient);
Blynk.virtualWrite(V5, digitalRead(STATUS_LED));
// -------- THINGSPEAK --------
if (client.connect(server, 80)) {
String url = "/update?api_key=" + apiKey;
url += "&field1=" + String(moisture);
url += "&field2=" + String(nutrient);
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + server + "\r\n" +
"Connection: close\r\n\r\n");
client.stop();
}
}
// ---------------- SETUP ----------------
void setup() {
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
pinMode(STATUS_LED, OUTPUT);
pinMode(FERT_LED, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
timer.setInterval(2000L, sendData); // every 2 sec
}
// ---------------- LOOP ----------------
void loop() {
Blynk.run();
timer.run();
// Physical button toggle
if (digitalRead(BUTTON_PIN) == LOW) {
autoMode = !autoMode;
delay(300);
}
}