#define BLYNK_TEMPLATE_ID "TMPL22MB3aEjb"
#define BLYNK_TEMPLATE_NAME "esp"
#define BLYNK_AUTH_TOKEN "9xUlvcQe4PvenYZRlKXcdUb70grhAhty"
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <ESP32Servo.h>
#include <DHT.h>
// معلومات شبكة Wi-Fi
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// تعريف المحركات
Servo servo1;
Servo servo2;
Servo servo3;
bool autoMode = true; // الوضع الافتراضي: تلقائي
bool countdownActive = false; // حالة العد التنازلي
// الوقت التنازلي
int countdownTime = 5; // الوقت التنازلي بالثواني
// مؤقت Blynk
BlynkTimer timer;
// الفروق بين الزوايا
int offset1 = 0; // المحرك 1
int offset2 = 5; // المحرك 2
int offset3 = 10; // المحرك 3
// الحد الأقصى للزاوية
int maxAngle = 90;
// تعريف حساس DHT22
#define DHTPIN 4 // توصيل DHT إلى المنفذ 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
float humidityThreshold = 80.0; // الحد الأقصى للرطوبة لتفعيل الوضع التلقائي
// دالة لضبط الزوايا مع الحفاظ على الفرق
void adjustAngles(int baseAngle, int &angle1, int &angle2, int &angle3) {
if (baseAngle > maxAngle) baseAngle = maxAngle;
angle1 = baseAngle + offset1;
angle2 = baseAngle + offset2;
angle3 = baseAngle + offset3;
if (angle3 > maxAngle) {
int excess = angle3 - maxAngle;
angle1 -= excess;
angle2 -= excess;
angle3 -= excess;
}
}
// دالة لتحريك المحركات
void moveServos(int baseAngle) {
int angle1, angle2, angle3;
adjustAngles(baseAngle, angle1, angle2, angle3);
servo1.write(angle1);
servo2.write(angle2);
servo3.write(angle3);
Blynk.virtualWrite(V7, angle1);
Blynk.virtualWrite(V5, angle2);
Blynk.virtualWrite(V6, angle3);
Serial.print("Servo 1: ");
Serial.print(angle1);
Serial.print(", Servo 2: ");
Serial.print(angle2);
Serial.print(", Servo 3: ");
Serial.println(angle3);
}
// دالة لتحديث العد التنازلي
void updateCountdown() {
if (countdownActive) {
if (countdownTime > 0) {
countdownTime--;
Blynk.virtualWrite(V3, countdownTime);
Serial.print("Countdown: ");
Serial.println(countdownTime);
} else {
countdownActive = false;
Blynk.virtualWrite(V3, 0);
Serial.println("Countdown finished!");
moveServos(maxAngle);
delay(1000);
moveServos(0);
delay(1000);
if (autoMode) {
startCountdown();
}
}
}
}
// دالة لبدء العد التنازلي تلقائيًا
void startCountdown() {
countdownActive = true;
countdownTime = 5;
Blynk.virtualWrite(V3, countdownTime);
Serial.println("Starting new countdown...");
}
// دالة لقراءة حالة الزر (V0)
BLYNK_WRITE(V0) {
autoMode = param.asInt();
if (autoMode) {
Serial.println("Auto mode activated");
startCountdown();
} else {
Serial.println("Manual mode activated");
countdownActive = false;
}
}
// دالة للتحكم اليدوي بالمحركات عبر Slider (V2)
BLYNK_WRITE(V2) {
if (!autoMode) {
int baseAngle = param.asInt();
moveServos(baseAngle);
}
}
// دالة للتحقق من حالة الرطوبة
void checkHumidity() {
float humidity = dht.readHumidity();
if (isnan(humidity)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
Blynk.virtualWrite(V8, humidity); // إرسال قيمة الرطوبة إلى التطبيق
Serial.print("Humidity: ");
Serial.println(humidity);
// إذا تجاوزت الرطوبة الحد الأقصى، يتم إيقاف الوضع التلقائي
if (humidity > humidityThreshold && autoMode) {
Serial.println("High humidity detected! Disabling auto mode.");
autoMode = false; // تعطيل الوضع التلقائي
countdownActive = false; // إيقاف العد التنازلي
Blynk.virtualWrite(V0, 0); // تحديث التطبيق لإيقاف الوضع التلقائي
}
}
void setup() {
Serial.begin(115200);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
servo1.attach(13);
servo2.attach(12);
servo3.attach(14);
dht.begin(); // بدء حساس DHT22
timer.setInterval(1000L, updateCountdown);
timer.setInterval(2000L, checkHumidity); // التحقق من الرطوبة كل ثانيتين
}
void loop() {
Blynk.run();
timer.run();
}