#include #include #include #include "DHT.h" // --------------------------- تنظیمات --------------------------- #define DHTPIN A0 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); #define SOIL_PIN A1 #define MQ7_PIN A2 #define VREF 5.0 // ولتاژ مرجع ADC #define ADC_MAX 4095.0 // برای STM32 (۱۲ بیتی) #define SDA_PIN PB9 #define SCL_PIN PB8 BH1750 lightMeter; // UART EC200U HardwareSerial EC200U(1); #define PWRKEY_PIN PB5 // ارسال هر n دقیقه #define UPLOAD_INTERVAL_MIN 1 // ذخیره ساعت شبکه String networkTime = ""; // --------------------------- توابع --------------------------- // روشن کردن ماژول EC200U void powerEC200U() { pinMode(PWRKEY_PIN, OUTPUT); digitalWrite(PWRKEY_PIN, HIGH); delay(1000); // نگه داشتن HIGH حدود 1 ثانیه برای روشن کردن digitalWrite(PWRKEY_PIN, LOW); delay(2000); // کمی صبر قبل از AT } // ارسال دستور AT و نمایش پاسخ void sendAT(String cmd, uint16_t wait = 1000) { Serial.print(">> "); Serial.println(cmd); EC200U.println(cmd); unsigned long start = millis(); while (millis() - start < wait) { while (EC200U.available()) Serial.write(EC200U.read()); } Serial.println(); } // آماده‌سازی ماژول و اینترنت void initEC200U() { Serial.println("🚀 Initializing EC200U..."); sendAT("AT",1000); sendAT("ATI",1000); sendAT("AT+CPIN?",1000); sendAT("AT+CSQ",1000); sendAT("AT+CREG?",1000); sendAT("AT+CGATT=1",2000); sendAT("AT+CGDCONT=1,\"IP\",\"mcinet\"",1000); sendAT("AT+QIACT=1",5000); sendAT("AT+QIACT?",2000); Serial.println("✅ EC200U Ready"); } // خواندن ساعت شبکه void getNetworkTime() { sendAT("AT+QLTS=2", 3000); networkTime = ""; unsigned long t = millis(); while (millis()-t < 3000) { while(EC200U.available()) { char c = EC200U.read(); Serial.write(c); networkTime += c; } } } // خواندن سنسورها float readDHT22() { return dht.readTemperature(); } float readHumidity() { return dht.readHumidity(); } // رطوبت خاک به درصد int readSoilPercent() { int val = analogRead(SOIL_PIN); // 0-4095 int perc = map(val, 3000, 1500, 0, 100); // خشک: 3000, خیس:1500 (تنظیم شود) if(perc>100) perc=100; if(perc<0) perc=0; return perc; } float readMQ7ppm() { // --- 1. میانگین‌گیری چند قرائت برای پایداری --- long sum = 0; for (int i = 0; i < 10; i++) { sum += analogRead(MQ7_PIN); delay(5); } float adcValue = sum / 10.0; // --- 2. محاسبه ولتاژ خروجی --- float voltage = (adcValue / ADC_MAX) * VREF; // --- 3. تبدیل تقریبی به ppm --- // منحنی تجربی بر اساس تست ماژول‌های MQ7 آماده (ولتاژ به ppm CO) // این ضرایب با ولتاژ 0.1V ~ 1V برای ppm=50~5000 کالیبره شده‌اند. // اگر مقدار خروجی بیش از 4V باشد، سنسور اشباع است. float ppm; if (voltage < 0.1) ppm = 0; // خیلی پاک else if (voltage < 0.2) ppm = 10 * (voltage / 0.2); // محدوده پایین else if (voltage < 0.5) ppm = 50 + (voltage - 0.2) * 300; // 50–140ppm else if (voltage < 1.0) ppm = 140 + (voltage - 0.5) * 800; // تا حدود 500ppm else if (voltage < 2.0) ppm = 500 + (voltage - 1.0) * 1500; // تا حدود 2000ppm else ppm = 2000 + (voltage - 2.0) * 2000; // تا ~4000ppm // --- 4. محدود کردن مقدار --- if (ppm < 0) ppm = 0; if (ppm > 10000) ppm = 10000; // --- 5. نمایش برای دیباگ --- Serial.print("MQ7 voltage: "); Serial.print(voltage, 3); Serial.print(" V, CO ≈ "); Serial.print(ppm, 1); Serial.println(" ppm"); return ppm; } float readLight() { return lightMeter.readLightLevel(); } // ارسال داده HTTP GET void sendData(float temp, float hum, int soilPerc, float mq7ppm, float lux, String timeStr) { String dataStr = String(temp,1) + "," + String(hum,1) + "," + String(soilPerc) + "," + String(mq7ppm,0) + "," + String(lux,1) + "," + timeStr; // 'http://localhost:5064/api/Telemetry/AddData?deviceName=dr110&temperatureC=24.5&humidityPercent=26.3&soilPercent=12&gasPPM=2&lux=103' String url = "http://nabaksoft.ir/api/Telemetry/AddData?deviceName=dr110&temperatureC="+String(temp,1) +"&humidityPercent="+String(hum,1)+"&soilPercent="+String(soilPerc)+"&gasPPM="+String(mq7ppm,0)+"&lux="+String(lux,1); Serial.println("🌐 Sending data: " + dataStr); sendAT("AT+QHTTPURL=" + String(url.length()) + ",80", 500); delay(500); EC200U.print(url); delay(1000); sendAT("AT+QHTTPGET=80", 5000); sendAT("AT+QHTTPREAD=80", 5000); } // --------------------------- راه‌اندازی --------------------------- void setup() { Serial.begin(115200); delay(1000); Serial.println("🚀 STM32 + EC200U + Sensors"); // روشن کردن ماژول EC200U powerEC200U(); // UART EC200U EC200U.setRx(PA10); EC200U.setTx(PA9); EC200U.begin(115200); delay(1000); // سنسورها dht.begin(); Wire.setSDA(SDA_PIN); Wire.setSCL(SCL_PIN); Wire.begin(); if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) { Serial.println("BH1750 Initialized successfully!"); } else { Serial.println("Error initializing BH1750!"); } // آماده سازی ماژول و اینترنت initEC200U(); // خواندن ساعت شبکه getNetworkTime(); } // --------------------------- حلقه اصلی --------------------------- unsigned long lastUpload = 0; void loop() { unsigned long now = millis(); if (now - lastUpload > UPLOAD_INTERVAL_MIN*60UL*1000UL || lastUpload==0) { // خواندن سنسورها float temp = readDHT22(); float hum = readHumidity(); int soil = readSoilPercent(); float mq7 = readMQ7ppm(); float lux = readLight(); // دریافت ساعت شبکه getNetworkTime(); // ارسال به سرور sendData(temp, hum, soil, mq7, lux, networkTime); lastUpload = now; } delay(500); }