#include "DHTesp.h"
#include <AccelStepper.h>
#include <WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include <ESP32Servo.h>
#define DHTPIN 27 // Pin connected to the DHT
#define STEPPER_DIR_PIN 2 // Pin connected to DIR on the stepper motor driver
#define STEPPER_STEP_PIN 0 // Pin connected to STEP on the stepper motor driver
#define STEPPER_ENABLE_PIN 4 // Pin connected to ENABLE on the stepper motor driver
#define SERVO_PIN 26 // Pin connected to the servo
#define SAFE_TEMP_MIN 28
#define SAFE_TEMP_MAX 80
#define SAFE_HUMIDITY_MAX 80
const float GAMMA = 0.7; // values from wokwi docs
const float RL10 = 50;
DHTesp dhtSensor;
AccelStepper stepper(AccelStepper::DRIVER, STEPPER_STEP_PIN, STEPPER_DIR_PIN);
Servo servo;
// WiFi settings
const char *ssid = "Wokwi-GUEST";
const char *password = "";
// Adafruit IO settings
#define IO_USERNAME ""
#define IO_KEY ""
WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, "io.adafruit.com", 1883, IO_USERNAME, IO_KEY);
// Adafruit IO feeds
Adafruit_MQTT_Publish temperature = Adafruit_MQTT_Publish(&mqtt, IO_USERNAME "/feeds/temperature");
Adafruit_MQTT_Publish humidity = Adafruit_MQTT_Publish(&mqtt, IO_USERNAME "/feeds/humidity");
Adafruit_MQTT_Publish irrigation_status = Adafruit_MQTT_Publish(&mqtt, IO_USERNAME "/feeds/irrigation_status");
Adafruit_MQTT_Subscribe servoFeed = Adafruit_MQTT_Subscribe(&mqtt, IO_USERNAME "/feeds/drip-irrigation");
void setup() {
Serial.begin(115200);
dhtSensor.setup(DHTPIN, DHTesp::DHT22);
stepper.setMaxSpeed(1000);
stepper.setAcceleration(500);
pinMode(STEPPER_ENABLE_PIN, OUTPUT);
digitalWrite(STEPPER_ENABLE_PIN, LOW); // enable pin "LOW" enables the driver
servo.attach(SERVO_PIN, 500, 2400);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected!");
mqtt.connect();
}
void loop() {
if (!mqtt.connected()) {
connectToAdafruitIO();
}
mqtt.processPackets(5000);
mqtt.readSubscription(); // Read any new messages
TempAndHumidity data = dhtSensor.getTempAndHumidity();
Serial.println("Temp: " + String(data.temperature, 2) + "°C");
Serial.println("Humidity: " + String(data.humidity, 2) + "%");
Serial.println(".......");
if (!temperature.publish(data.temperature) || !humidity.publish(data.humidity)) {
Serial.println("Failed to publish data to Adafruit IO!");
}
if (data.temperature > SAFE_TEMP_MIN && data.temperature < SAFE_TEMP_MAX &&
data.humidity < SAFE_HUMIDITY_MAX) {
// further conditions and calls can be added here
irrigatePlants();
if (!irrigation_status.publish("1")) {
Serial.println("Failed to publish irrigation status to Adafruit IO!");
}
} else {
if (!irrigation_status.publish("0")) {
Serial.println("Failed to publish irrigation status to Adafruit IO!");
}
}
if (servoFeed.lastread != NULL) {
Serial.print("Received value from MQTT (length ");
Serial.print(strlen((char*)servoFeed.lastread));
Serial.print("): ");
Serial.println((char*)servoFeed.lastread);
if (strcmp((char*)servoFeed.lastread, "1") == 0) {
servo.write(180);
Serial.println("Servo turned ON");
} else if (strcmp((char*)servoFeed.lastread, "0") == 0) {
servo.write(0);
Serial.println("Servo turned OFF");
} else {
Serial.println("Invalid value received from MQTT");
}
memset(servoFeed.lastread, 0, sizeof(servoFeed.lastread));
}
delay(5000);
}
void irrigatePlants() {
stepper.setCurrentPosition(0);
stepper.moveTo(200);
stepper.runToPosition();
}
void connectToAdafruitIO() {
while (!mqtt.connected()) {
Serial.println("Connecting to Adafruit IO...");
if (mqtt.connect()) {
Serial.println("Connected to Adafruit IO");
} else {
Serial.print("Failed to connect to Adafruit IO, retrying...");
delay(5000);
}
}
}