#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <ArduinoJson.h>
// WiFi credentials
const char* ssid = "SCE"; // Replace with your WiFi SSID
const char* password = "samishamoon?!"; // Replace with your WiFi password
// MQTT Broker settings
const char* mqtt_server = "broker.hivemq.com"; // Public MQTT broker
const int mqtt_port = 1883;
const char* mqtt_client_id = "SmartGreenhouseDevice";
const char* mqtt_username = ""; // Leave empty if not required
const char* mqtt_password = ""; // Leave empty if not required
// MQTT Topics
const char* topic_temperature = "greenhouse/sensors/temperature";
const char* topic_humidity = "greenhouse/sensors/humidity";
const char* topic_light = "greenhouse/sensors/light";
const char* topic_status = "greenhouse/system/status";
const char* topic_fan_control = "greenhouse/actuators/fan";
const char* topic_light_control = "greenhouse/actuators/light";
// Pin definitions
#define DHTPIN 4 // DHT22 connected to pin 4
#define DHTTYPE DHT22 // DHT22 sensor type
#define LDR_PIN 34 // Photoresistor connected to pin 34
#define FAN_PIN 5 // Fan (blue LED) connected to pin 5
#define GROW_LIGHT_PIN 18 // Grow light (yellow LED) connected to pin 18
// Threshold values for actuators
const float TEMP_HIGH_THRESHOLD = 28.0; // Turn on fan if temperature exceeds this value (°C)
const float TEMP_LOW_THRESHOLD = 24.0; // Turn off fan if temperature drops below this value (°C)
const int LIGHT_LOW_THRESHOLD = 300; // Turn on grow light if light level drops below this value
const int LIGHT_HIGH_THRESHOLD = 600; // Turn off grow light if light level exceeds this value
// Variables for sensor values
float temperature = 0.0;
float humidity = 0.0;
int lightLevel = 0;
// Variables for actuator states
bool fanOn = false;
bool growLightOn = false;
// Automatic control mode (true = automatic, false = manual via MQTT)
bool autoFanControl = true;
bool autoLightControl = true;
// Initialize the DHT sensor
DHT dht(DHTPIN, DHTTYPE);
// Initialize WiFi and MQTT clients
WiFiClient espClient;
PubSubClient client(espClient);
// Timestamp variables
unsigned long lastSensorReadTime = 0;
unsigned long lastMqttPublishTime = 0;
const long sensorReadInterval = 2000; // Read sensors every 2 seconds
const long mqttPublishInterval = 10000; // Publish data every 10 seconds
void setup() {
// Initialize serial communication
Serial.begin(115200);
// Initialize pins
pinMode(FAN_PIN, OUTPUT);
pinMode(GROW_LIGHT_PIN, OUTPUT);
// Initial state for actuators
digitalWrite(FAN_PIN, LOW);
digitalWrite(GROW_LIGHT_PIN, LOW);
// Initialize DHT sensor
dht.begin();
// Connect to WiFi
setupWiFi();
// Configure MQTT broker connection
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
Serial.println("Smart Greenhouse System initialized.");
}
void loop() {
// Ensure WiFi and MQTT connections are active
if (!client.connected()) {
reconnectMQTT();
}
client.loop();
// Read sensors on interval
unsigned long currentMillis = millis();
if (currentMillis - lastSensorReadTime >= sensorReadInterval) {
lastSensorReadTime = currentMillis;
readSensors();
controlActuators();
}
// Publish data to MQTT on interval
if (currentMillis - lastMqttPublishTime >= mqttPublishInterval) {
lastMqttPublishTime = currentMillis;
publishSensorData();
}
}
void setupWiFi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnectMQTT() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(mqtt_client_id, mqtt_username, mqtt_password)) {
Serial.println("connected");
// Subscribe to topics for remote control
client.subscribe(topic_fan_control);
client.subscribe(topic_light_control);
// Publish system status message
client.publish(topic_status, "ONLINE", true);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void callback(char* topic, byte* payload, unsigned int length) {
// Convert payload to string
payload[length] = '\0';
String message = String((char*)payload);
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
Serial.println(message);
// Process incoming commands
if (strcmp(topic, topic_fan_control) == 0) {
if (message == "ON") {
fanOn = true;
digitalWrite(FAN_PIN, HIGH);
autoFanControl = false;
Serial.println("Fan turned ON by remote command");
} else if (message == "OFF") {
fanOn = false;
digitalWrite(FAN_PIN, LOW);
autoFanControl = false;
Serial.println("Fan turned OFF by remote command");
} else if (message == "AUTO") {
autoFanControl = true;
Serial.println("Fan control set to AUTO mode");
}
}
if (strcmp(topic, topic_light_control) == 0) {
if (message == "ON") {
growLightOn = true;
digitalWrite(GROW_LIGHT_PIN, HIGH);
autoLightControl = false;
Serial.println("Grow light turned ON by remote command");
} else if (message == "OFF") {
growLightOn = false;
digitalWrite(GROW_LIGHT_PIN, LOW);
autoLightControl = false;
Serial.println("Grow light turned OFF by remote command");
} else if (message == "AUTO") {
autoLightControl = true;
Serial.println("Grow light control set to AUTO mode");
}
}
}
void readSensors() {
// Read temperature and humidity from DHT22
humidity = dht.readHumidity();
temperature = dht.readTemperature();
// Check if DHT reading failed
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// Read light level from photoresistor
lightLevel = analogRead(LDR_PIN);
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.print("°C, Humidity: ");
Serial.print(humidity);
Serial.print("%, Light Level: ");
Serial.println(lightLevel);
}
void controlActuators() {
// Automatic fan control based on temperature
if (autoFanControl) {
if (temperature > TEMP_HIGH_THRESHOLD && !fanOn) {
fanOn = true;
digitalWrite(FAN_PIN, HIGH);
Serial.println("Fan turned ON automatically");
// Publish fan status change
client.publish(topic_fan_control, "ON", true);
} else if (temperature < TEMP_LOW_THRESHOLD && fanOn) {
fanOn = false;
digitalWrite(FAN_PIN, LOW);
Serial.println("Fan turned OFF automatically");
// Publish fan status change
client.publish(topic_fan_control, "OFF", true);
}
}
// Automatic grow light control based on light level
if (autoLightControl) {
if (lightLevel < LIGHT_LOW_THRESHOLD && !growLightOn) {
growLightOn = true;
digitalWrite(GROW_LIGHT_PIN, HIGH);
Serial.println("Grow light turned ON automatically");
// Publish grow light status change
client.publish(topic_light_control, "ON", true);
} else if (lightLevel > LIGHT_HIGH_THRESHOLD && growLightOn) {
growLightOn = false;
digitalWrite(GROW_LIGHT_PIN, LOW);
Serial.println("Grow light turned OFF automatically");
// Publish grow light status change
client.publish(topic_light_control, "OFF", true);
}
}
}
void publishSensorData() {
// Create JSON document for sensor data
StaticJsonDocument<200> doc;
char buffer[200];
// Publish temperature
doc["value"] = temperature;
doc["unit"] = "celsius";
doc["timestamp"] = millis();
serializeJson(doc, buffer);
client.publish(topic_temperature, buffer);
// Publish humidity
doc["value"] = humidity;
doc["unit"] = "percent";
doc["timestamp"] = millis();
serializeJson(doc, buffer);
client.publish(topic_humidity, buffer);
// Publish light level
doc["value"] = lightLevel;
doc["unit"] = "analog";
doc["timestamp"] = millis();
serializeJson(doc, buffer);
client.publish(topic_light, buffer);
Serial.println("Sensor data published to MQTT");
}