#include <WiFi.h>
#include <HTTPClient.h>
#include <LiquidCrystal_I2C.h>
/* --- إعدادات المكونات والمنافذ (Pins) --- */
#define DHT_PIN 27 // منفذ حساس الحرارة والرطوبة
#define DHT_TYPE DHT22 // نوع الحساس المستخدم
#define SOIL_ANALOG_PIN 3 // منفذ حساس الرطوبة (Potentiometer في الدياغرام)
#define BUZZER_PIN 14 // منفذ الجرس (Buzzer)
#define LED_RED_PIN 13 // الضوء الأحمر: خطر / جفاف حاد
#define LED_YELLOW_PIN 12 // الضوء الأصفر: حالة معتدلة
#define LED_GREEN_PIN 26 // الضوء الأخضر: سقي نشط
/* --- إعدادات الشاشة LCD (I2C) --- */
// العنوان الافتراضي غالباً هو 0x27 لـ 16x2
LiquidCrystal_I2C lcdDisplay(0x27, 16, 2);
DHT dhtSensor(DHT_PIN, DHT_TYPE);
/* --- إعدادات الويفي والموقع --- */
const char* wifiSsid = "Wokwi-GUEST"; // اسم الويفي الخاص بك
const char* wifiPassword = ""; // كلمة السر
const String serverUrl = "http://massiratech.byethost7.com/display.php?msg=";
/* --- متغيرات التحكم في الوقت (بدون استخدام delay) --- */
unsigned long lastUpdateMillis = 0;
const long updateInterval = 2000; // تحديث كل ثانيتين (أفضل للحساسات)
unsigned long lastSmsMillis = 0;
const long smsCooldown = 30000; // منع تكرار الإرسال قبل 30 ثانية
int systemCurrentStatus = -1;
void setup() {
Serial.begin(115200); // سرعة عالية تتناسب مع ESP32
// إعداد المنافذ
pinMode(LED_RED_PIN, OUTPUT);
pinMode(LED_YELLOW_PIN, OUTPUT);
pinMode(LED_GREEN_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
// تشغيل الحساس والشاشة
dhtSensor.begin();
lcdDisplay.init();
lcdDisplay.backlight();
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("SYSTEM STARTING");
// الاتصال بالويفي
connectToWifi();
lcdDisplay.clear();
}
void loop() {
unsigned long currentMillis = millis();
// تحديث البيانات بشكل دوري
if (currentMillis - lastUpdateMillis >= updateInterval) {
lastUpdateMillis = currentMillis;
// قراءة البيانات من الحساسات
float temperatureC = dhtSensor.readTemperature();
int soilMoisture = analogRead(SOIL_ANALOG_PIN);
// التحقق من سلامة قراءة الحساس
if (isnan(temperatureC)) {
Serial.println("Error: Failed to read from DHT sensor!");
return;
}
/* --- منطق التحكم (Logic Control) --- */
// الحالة 1: حرارة معتدلة (الضوء الأصفر)
if (temperatureC >= 15.0 && temperatureC <= 25.0) {
updateSystemUI(LOW, HIGH, LOW, "ARROSAGE STOP", 1, 500);
}
// الحالة 2: التربة تحتاج سقي (الضوء الأخضر)
else if (soilMoisture < 1500) { // قيمة تقريبية لـ ESP32 (4095 max)
updateSystemUI(LOW, LOW, HIGH, "ARROSAGE ACTIF", 2, 1000);
sendDataToServer("System_Active");
}
// الحالة 3: خطر - جفاف حاد (الضوء الأحمر)
else {
updateSystemUI(HIGH, LOW, LOW, "SOL: TRES SEC", 3, 2000);
sendDataToServer("Soil_Very_Dry");
}
// عرض الحرارة في السطر الأول دائماً
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("TEMP: ");
lcdDisplay.print(temperatureC, 1);
lcdDisplay.print("C ");
}
}
/**
* دالة لتحديث واجهة النظام (أضواء، شاشة، صوت)
*/
void updateSystemUI(int red, int yellow, int green, String message, int statusID, int beepFreq) {
digitalWrite(LED_RED_PIN, red);
digitalWrite(LED_YELLOW_PIN, yellow);
digitalWrite(LED_GREEN_PIN, green);
lcdDisplay.setCursor(0, 1);
lcdDisplay.print(message + " ");
// تنبيه صوتي عند تغيير الحالة فقط
if (systemCurrentStatus != statusID) {
tone(BUZZER_PIN, beepFreq, 200);
systemCurrentStatus = statusID;
Serial.println("STATUS CHANGED: " + message);
}
}
/**
* دالة للاتصال بشبكة الويفي
*/
void connectToWifi() {
Serial.print("Connecting to WiFi...");
WiFi.begin(wifiSsid, wifiPassword);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected!");
}
/**
* دالة إرسال البيانات للموقع (HTTP GET)
*/
void sendDataToServer(String statusMsg) {
if (millis() - lastSmsMillis > smsCooldown) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String fullUrl = serverUrl + statusMsg;
http.begin(fullUrl);
int httpResponseCode = http.GET();
if (httpResponseCode > 0) {
Serial.print("Data sent! Response code: ");
Serial.println(httpResponseCode);
} else {
Serial.print("Error sending data: ");
Serial.println(httpResponseCode);
}
http.end();
lastSmsMillis = millis();
}
}
}