#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
// ===============================
// Hardware Pin Configurations
// ===============================
#define DHTPIN 15
#define DHTTYPE DHT22
#define SOIL_PIN 34
#define RELAY_PIN 2
// ===============================
// Wi-Fi Credentials
// ===============================
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASSWORD = "";
// ===============================
// MQTT Configuration
// ===============================
const char* MQTT_BROKER = "broker.hivemq.com";
const int MQTT_PORT = 1883;
// MQTT Topics
const char* TOPIC_TELEMETRY = "farm/telemetry";
const char* TOPIC_COMMAND = "farm/irrigation/cmd";
// ===============================
// Global Objects
// ===============================
DHT dht(DHTPIN, DHTTYPE);
WiFiClient espClient;
PubSubClient mqttClient(espClient);
// ===============================
// Telemetry Timing
// ===============================
unsigned long lastTelemetryTime = 0;
const unsigned long telemetryInterval = 2000;
// ===============================
// Wi-Fi Connection Setup
// ===============================
void setupWiFi() {
delay(10);
Serial.println();
Serial.print("Connecting to WiFi: ");
Serial.println(WIFI_SSID);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi Connected Successfully!");
Serial.print("ESP32 IP Address: ");
Serial.println(WiFi.localIP());
}
// ===============================
// MQTT Callback Function
// ===============================
void mqttCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message received on topic: ");
Serial.println(topic);
String commandMessage = "";
for (unsigned int i = 0; i < length; i++) {
commandMessage += (char)payload[i];
}
Serial.print("Command: ");
Serial.println(commandMessage);
// Pump Control Logic
if (String(topic) == TOPIC_COMMAND) {
if (commandMessage == "ON") {
digitalWrite(RELAY_PIN, HIGH);
Serial.println("Pump Activated");
}
else if (commandMessage == "OFF") {
digitalWrite(RELAY_PIN, LOW);
Serial.println("Pump Deactivated");
}
}
}
// ===============================
// MQTT Reconnection
// ===============================
void reconnectBroker() {
while (!mqttClient.connected()) {
Serial.print("Connecting to MQTT Broker...");
String clientId = "ESP32-SmartFarm-";
clientId += String(random(0xffff), HEX);
if (mqttClient.connect(clientId.c_str())) {
Serial.println("Connected!");
mqttClient.subscribe(TOPIC_COMMAND);
Serial.print("Subscribed to: ");
Serial.println(TOPIC_COMMAND);
} else {
Serial.print("Failed. Error Code: ");
Serial.print(mqttClient.state());
Serial.println(" Retry in 5 seconds...");
delay(5000);
}
}
}
// ===============================
// Setup Function
// ===============================
void setup() {
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
// Pump OFF initially
digitalWrite(RELAY_PIN, LOW);
dht.begin();
setupWiFi();
mqttClient.setServer(MQTT_BROKER, MQTT_PORT);
mqttClient.setCallback(mqttCallback);
}
// ===============================
// Main Loop
// ===============================
void loop() {
// Ensure MQTT Connection
if (!mqttClient.connected()) {
reconnectBroker();
}
mqttClient.loop();
unsigned long currentTime = millis();
if (currentTime - lastTelemetryTime >= telemetryInterval) {
lastTelemetryTime = currentTime;
// ===========================
// Sensor Readings
// ===========================
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
int rawSoilValue = analogRead(SOIL_PIN);
// Convert to percentage
float soilMoisture =
(4095 - rawSoilValue) * 100.0 / 4095.0;
// ===========================
// Sensor Validation
// ===========================
if (isnan(temperature) || isnan(humidity)) {
Serial.println("Sensor Reading Failed!");
return;
}
// ===========================
// Current Pump State
// ===========================
int pumpState = digitalRead(RELAY_PIN);
// ===========================
// Create JSON Payload
// ===========================
String payload = "{";
payload += "\"temperature\":";
payload += String(temperature, 2);
payload += ",";
payload += "\"humidity\":";
payload += String(humidity, 2);
payload += ",";
payload += "\"soilMoisture\":";
payload += String(soilMoisture, 2);
payload += ",";
payload += "\"pumpState\":";
payload += String(pumpState);
payload += "}";
// ===========================
// Publish MQTT Message
// ===========================
char messageBuffer[256];
payload.toCharArray(messageBuffer, 256);
if (mqttClient.publish(TOPIC_TELEMETRY, messageBuffer)) {
Serial.println("Telemetry Published:");
Serial.println(messageBuffer);
} else {
Serial.println("Failed to Publish MQTT Message");
}
// ===========================
// Serial Monitor Output
// ===========================
Serial.println("===============");
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.println(" °C");
Serial.print("Humidity: ");
Serial.print(humidity);
Serial.println(" %");
Serial.print("Soil Moisture: ");
Serial.print(soilMoisture);
Serial.println(" %");
Serial.print("Pump State: ");
if (pumpState == 1) {
Serial.println("ON");
} else {
Serial.println("OFF");
}
Serial.println("===============");
}
}