#define BLYNK_TEMPLATE_ID "TMPL6iTkUkJ8x"
#define BLYNK_TEMPLATE_NAME "Damper control"
#define BLYNK_AUTH_TOKEN "6GMrOwd-AONOd0l-alz3abEJf2v1GMsn"
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <ESP32Servo.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <DHT.h>
#include <LiquidCrystal.h>
#include <PID_v1.h>
// Your WiFi credentials.
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
const int servo1Pin = 16;
const int servo2Pin = 22;
const int servo3Pin = 25;
const int servo4Pin = 27;
#define DHTpin 13
int pos1=0;
int pos2=0;
int pos3=0;
int pos4=0;
int sensorpin = 34; // Define sensorpin (e.g., A0 for analog pin)
DHT dht22(DHTpin, DHT22);
Servo servo1, servo2, servo3, servo4;
LiquidCrystal lcd(19, 23, 18, 21, 5, 15); // RS, E, D4, D5, D6, D7
// Setpoints for temperature and humidity
const float tempSetpoint = 45.0;
const float humiditySetpoint = 60.0;
// PID parameters
double tempInput, tempOutput, tempSet = tempSetpoint;
double humidityInput, humidityOutput, humiditySet = humiditySetpoint;
// PID tunings (Adjust as necessary)
double Kp = 2.0, Ki = 5.0, Kd = 1.0;
// Create PID controllers for temperature and humidity
PID tempPID(&tempInput, &tempOutput, &tempSet, Kp, Ki, Kd, DIRECT);
PID humidityPID(&humidityInput, &humidityOutput, &humiditySet, Kp, Ki, Kd, DIRECT);
// Variables to track if user manually adjusts the dampers
bool manualControl1 = false;
bool manualControl2 = false;
bool manualControl3 = false;
bool manualControl4 = false;
BLYNK_WRITE(V0) // User controlling damper 1
{
int pos1 = param.asInt();
servo1.write(pos1 * 18);
manualControl1 = true; // Disable PID control for damper 1
}
BLYNK_WRITE(V1)
{
int pos2 = param.asInt();
servo2.write(pos2 * 18);
manualControl2 = true; // Disable PID control for damper 2
}
BLYNK_WRITE(V2)
{
int pos3 = param.asInt();
servo3.write(pos3 * 18);
manualControl3 = true; // Disable PID control for damper 3
}
BLYNK_WRITE(V3)
{
int pos4 = param.asInt();
servo4.write(pos4 * 18);
manualControl4 = true; // Disable PID control for damper 4
}
void setup()
{
// Debug console
Serial.begin(115200);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// Attach servos to pins with PWM limits
servo1.attach(servo1Pin, 500, 2400);
servo2.attach(servo2Pin, 500, 2400);
servo3.attach(servo3Pin, 500, 2400);
servo4.attach(servo4Pin, 500, 2400);
// Initialize servos to 0 position
servo1.write(0);
servo2.write(0);
servo3.write(0);
servo4.write(0);
dht22.begin();
delay(2000); // Allow sensor to stabilize
lcd.begin(16, 2); // Initialize LCD with 16 columns and 2 rows
lcd.print("TEMP: "); // Print static part
lcd.setCursor(0, 1); // Move cursor to print humidity
lcd.print("HUMID: ");
// Initialize PID controllers
tempPID.SetMode(AUTOMATIC);
humidityPID.SetMode(AUTOMATIC);
}
void loop()
{
// Read temperature and humidity values
tempInput = dht22.readTemperature(); // Read temperature in Celsius
humidityInput = dht22.readHumidity(); // Read humidity
// Update LCD with current readings
lcd.setCursor(6, 0);
lcd.print(tempInput);
lcd.setCursor(6, 1);
lcd.print(humidityInput);
// Check if the sensor readings are valid
if (isnan(tempInput) || isnan(humidityInput)) {
Serial.println("Failed to read from DHT22 sensor!");
return;
}
// If the user hasn't manually adjusted, run PID control
if (!manualControl1) {
tempPID.Compute();
humidityPID.Compute();
// Control dampers based on PID outputs (PID outputs range from 0 to 180 degrees)
servo1.write(map(tempOutput, 0, 180, 0, 180));
servo2.write(map(humidityOutput, 0, 180, 0, 180));
}
if (!manualControl2) {
// PID control for servo2 based on temperature
tempPID.Compute();
servo2.write(map(tempOutput, 0, 180, 0, 180));
}
if (!manualControl3) {
// PID control for servo3 based on humidity
humidityPID.Compute();
servo3.write(map(humidityOutput, 0, 180, 0, 180));
}
if (!manualControl4) {
// PID control for servo4 based on both temperature and humidity
tempPID.Compute();
humidityPID.Compute();
servo4.write(map((tempOutput + humidityOutput) / 2, 0, 180, 0, 180));
}
Blynk.run(); // Run Blynk code
}