#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
// WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = ""; // Wokwi doesn't require a password
// Broker settings
const char* mqtt_server = "broker.hivemq.com";
const int mqtt_port = 1883;
// MQTT Topics
const char* topic_humidity = "greenhouse/humidity";
const char* topic_temperature = "greenhouse/temperature";
const char* topic_soilMoisture = "greenhouse/soilMoisture";
const char* topic_lightIntensity = "greenhouse/lightIntensity"; // light intensity topic
const char* topic_ph = "greenhouse/phLevel"; // pH topic
const char* topic_control = "greenhouse/control"; // control topic
// DHT Sensor Configuration
#define DHTPIN 15 // GPIO for DHT22
#define DHTTYPE DHT22 // Define sensor type
DHT dht(DHTPIN, DHTTYPE);
// Sensor Pins
const int soilMoisturePin = A0;
const int photoresistorPin = A4; // photoresistor pin
const int phSensorPin =A5; // pH sensor pin at A2
// Actuator Pins
const int sprinklerPin = 13;
const int fanPin = 14;
const int heaterPin = 12;
const int lightsPin = 27; // lights actuator pin
// WiFi and MQTT Client
WiFiClient espClient;
PubSubClient client(espClient);
// Callback function for incoming MQTT messages
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
// Convert payload to string
String message = "";
for (unsigned int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.println(message);
// handling control messages
if (String(topic) == topic_control) {
if (message == "sprinkler_on") {
digitalWrite(sprinklerPin, HIGH);
Serial.println("Sprinkler turned ON");
}
else if (message == "sprinkler_off") {
digitalWrite(sprinklerPin, LOW);
Serial.println("Sprinkler turned OFF");
}
// control logic
}
}
// Function to read pH from the sensor
float readPHSensor() {
int sensorValue = analogRead(phSensorPin);
// Convert analog reading to pH
// This is a simplified conversion. You might need to calibrate based on your specific sensor
// Typical pH sensor uses a voltage-based conversion
float voltage = sensorValue * (5.0 / 1023.0);
float pH = 7.0 + ((2.5 - voltage) / 0.18);
return pH;
}
void setup() {
// Initialize Serial communication
Serial.begin(115200);
// Initialize DHT sensor
dht.begin();
// Setup WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// Configure MQTT client
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback); // Set the message callback function
// Connect to MQTT Broker
connectToMQTT();
// Initialize actuator pins
pinMode(sprinklerPin, OUTPUT);
pinMode(fanPin, OUTPUT);
pinMode(heaterPin, OUTPUT);
pinMode(lightsPin, OUTPUT); // Initialize lights actuator pin
}
void loop() {
// Ensure MQTT connection
if (!client.connected()) {
connectToMQTT();
}
client.loop(); // Handle MQTT communication
// Read sensors
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
int soilMoisture = analogRead(soilMoisturePin);
int lightIntensity = analogRead(photoresistorPin); // Read photoresistor value
float phLevel = readPHSensor(); // Read pH level
// Check if sensor readings are valid
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
delay(5000);
return;
}
// Publish sensor data to MQTT topics
client.publish(topic_humidity, String(humidity).c_str());
client.publish(topic_temperature, String(temperature).c_str());
client.publish(topic_soilMoisture, String(soilMoisture).c_str());
client.publish(topic_lightIntensity, String(lightIntensity).c_str()); // Publish light intensity
client.publish(topic_ph, String(phLevel).c_str()); // Publish pH level
// Debugging: Print sensor data to Serial Monitor
Serial.println("Sensor Data Published:");
Serial.print("Humidity: ");
Serial.println(humidity);
Serial.print("Temperature: ");
Serial.println(temperature);
Serial.print("Soil Moisture: ");
Serial.println(soilMoisture);
Serial.print("Light Intensity: ");
Serial.println(lightIntensity);
Serial.print("pH Level: ");
Serial.println(phLevel);
// Automatic Actuator Control Logic
digitalWrite(sprinklerPin, soilMoisture < 500 ? HIGH : LOW);
digitalWrite(fanPin, temperature > 20 ? HIGH : LOW);
digitalWrite(heaterPin, temperature > 30 ? HIGH : LOW);
digitalWrite(lightsPin, lightIntensity < 500 ? HIGH : LOW); // Control lights based on light intensity
delay(5000); // Wait before next reading
}
// Function to connect to MQTT Broker
void connectToMQTT() {
while (!client.connected()) {
Serial.println("Connecting to HiveMQ MQTT...");
// Generate a unique client ID
String clientId = "ESP32Client-" + String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("Connected to HiveMQ Broker");
// Subscribe to control topic
client.subscribe(topic_control);
}
else {
Serial.print("MQTT Connection failed. Error code: ");
Serial.println(client.state());
delay(5000); // Retry after delay
}
}
}