From 742d69953791af64997d71c63fdf688a7a4f6811 Mon Sep 17 00:00:00 2001 From: rahimi rahimi Date: Fri, 19 Dec 2025 11:40:10 +0330 Subject: [PATCH] first commit --- stm32f103.ino | 378 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 378 insertions(+) create mode 100644 stm32f103.ino diff --git a/stm32f103.ino b/stm32f103.ino new file mode 100644 index 0000000..bafe888 --- /dev/null +++ b/stm32f103.ino @@ -0,0 +1,378 @@ +#include +#include +#include +#include "DHT.h" + +// --------------------------- تنظیمات --------------------------- +#define DHTPIN PA0 +#define DHTTYPE DHT11 +DHT dht(DHTPIN, DHTTYPE); + +#define SOIL_PIN PA1 +#define MQ7_PIN PA2 + +#define SDA_PIN PB9 +#define SCL_PIN PB8 +BH1750 lightMeter; + +#define EC200U_TX PB10 +#define EC200U_RX PB11 + +HardwareSerial EC200U(USART3); + +#define PWRKEY_PIN PB5 + +#define UPLOAD_INTERVAL_MIN 0.2 +String networkTime = ""; +bool sslOK = false; + +// تابع بهبود یافته برای ارسال AT +bool sendAT(String cmd, uint16_t wait = 2000) { + Serial1.print(">> "); + Serial1.println(cmd); + + EC200U.println(cmd); + + String response = ""; + unsigned long start = millis(); + + while (millis() - start < wait) { + while (EC200U.available()) { + char c = EC200U.read(); + response += c; + Serial1.write(c); + } + // اگر پاسخ کامل دریافت شد، خارج شو + if (response.indexOf("OK") != -1 || response.indexOf("ERROR") != -1) { + break; + } + } + + Serial1.println(); + + // بررسی موفقیت یا خطا + if (response.indexOf("OK") != -1) { + return true; + } else if (response.indexOf("ERROR") != -1 || response.indexOf("FAIL") != -1) { + return false; + } else { + Serial1.println("⚠️ No response11"); + return false; + } +} + +// تابع برای منتظر ماندن پاسخ خاص +bool waitForResponse(String expected, unsigned long timeout = 10000) { + unsigned long startTime = millis(); + String response = ""; + + while (millis() - startTime < timeout) { + while (EC200U.available()) { + char c = EC200U.read(); + response += c; + Serial1.write(c); + + if (response.indexOf(expected) != -1) { + return true; + } + if (response.indexOf("ERROR") != -1) { + return false; + } + } + } + Serial1.println("⏰ Timeout waiting for: " + expected); + return false; +} + +void initEC200U() { + Serial1.println("🚀1 Starting EC200U..."); + + // روشن کردن ماژول + digitalWrite(PWRKEY_PIN, HIGH); + delay(2000); + digitalWrite(PWRKEY_PIN, LOW); + delay(5000); // افزایش زمان انتظار + + // بررسی ارتباط + if (!sendAT("AT", 3000)) { + Serial1.println("❌ EC200U not responding!"); + return; + } + + sendAT("ATI", 2000); + sendAT("AT+CPIN?", 2000); + sendAT("AT+CSQ", 2000); + sendAT("AT+CREG?", 2000); + sendAT("AT+CGREG?", 2000); + + // فعال کردن GPRS + sendAT("AT+CGATT=1", 5000); + sendAT("AT+CGDCONT=1,\"IP\",\"mcinet\"", 2000); + + // فعال کردن PDP context + if (sendAT("AT+QIACT=1", 15000)) { + Serial1.println("✅ PDP context activated"); + } else { + Serial1.println("❌ Failed to activate PDP context"); + sendAT("AT+QIACT?", 2000); + } + + // تنظیمات HTTP + sendAT("AT+QHTTPCFG=\"contextid\",1", 2000); + sendAT("AT+QHTTPCFG=\"requestheader\",1", 2000); + sendAT("AT+QHTTPCFG=\"responseheader\",1", 2000); + + // تنظیمات SSL + sendAT("AT+QSSLCFG=\"sslversion\",1,4", 2000); + sendAT("AT+QSSLCFG=\"ciphersuite\",1,0XFFFF", 2000); + sendAT("AT+QSSLCFG=\"seclevel\",1,0", 2000); + sendAT("AT+QSSLCFG=\"ignorelocaltime\",1,1", 2000); + + Serial1.println("✅ EC200U Initialized"); +} + +void getNetworkTime() { + if (sendAT("AT+QLTS=2", 5000)) { + networkTime = "Time received"; + } else { + networkTime = "No time"; + } +} + +// --- MQ7 تابع مخصوص ماژول آماده --- +float MQ7_ReadPPM() { + long sum = 0; + for (int i = 0; i < 10; i++) { + sum += analogRead(MQ7_PIN); + delay(5); + } + float adcValue = sum / 10.0; + float voltage = (adcValue / 4095.0) * 3.3; // اصلاح به 3.3V برای STM32 + + 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; + else if (voltage < 1.0) ppm = 140 + (voltage - 0.5) * 800; + else if (voltage < 2.0) ppm = 500 + (voltage - 1.0) * 1500; + else ppm = 2000 + (voltage - 2.0) * 2000; + + if (ppm < 0) ppm = 0; + if (ppm > 10000) ppm = 10000; + + return ppm; +} + +// --- Soil Sensor (تبدیل به درصد) --- +int readSoil() { + int adcValue = analogRead(SOIL_PIN); + const int adcDry = 4095; // خاک کاملاً خشک (12-bit ADC) + const int adcWet = 1200; // خاک کاملاً خیس + + // محاسبه درصد رطوبت + float soilPercent = (float)(adcDry - adcValue) / (adcDry - adcWet) * 100.0; + + // محدود کردن بین 0 تا 100 + if (soilPercent > 100.0) soilPercent = 100.0; + if (soilPercent < 0.0) soilPercent = 0.0; + + return (int)soilPercent; +} + +// --- سایر سنسورها --- +float readLight() { + float lux = lightMeter.readLightLevel(); + if (isnan(lux)) return 0; + return lux; +} + +float readTemp() { + float temp = dht.readTemperature(); + if (isnan(temp)) return -999; + return temp; +} + +float readHum() { + float hum = dht.readHumidity(); + if (isnan(hum)) return -999; + return hum; +} + +bool sendData(float temp, float hum, int soil, float gas, float lux, String timeStr) { + // بررسی مقادیر سنسورها + if (temp == -999 || hum == -999) { + Serial1.println("❌ DHT Sensor error!"); + return false; + } + + String gazStr = String(gas, 0); + gazStr.trim(); + String dataStr = "temperatureC=" + String(temp, 1) + + "&humidityPercent=" + String(hum, 1) + + "&soilPercent=" + String(soil) + + "&gasPPM=" + gazStr + + "&lux=" + String(lux, 1); + + String url = "https://ghback.nabaksoft.ir/api/Telemetry/AddData?deviceName=dr110&" + dataStr; + url.replace(" ", ""); + + Serial1.println("📤 Sending data to server..."); + Serial1.println("URL: " + url); + Serial1.println("Length: " + String(url.length())); + + // تنظیمات SSL برای HTTPS + Serial1.println("🔒 Configuring SSL..."); + if (!sendAT("AT+QHTTPCFG=\"sslctxid\",1", 2000)) { + Serial1.println("❌ SSL configuration failed"); + return false; + } + + // تنظیم URL + String urlCmd = "AT+QHTTPURL=" + String(url.length()) + ",443"; + Serial1.println(">> " + urlCmd); + + EC200U.println(urlCmd); + + // منتظر CONNECT + if (waitForResponse("CONNECT", 10000)) { + Serial1.println("✅ CONNECT received, sending URL..."); + + // ارسال URL + EC200U.print(url); + + // منتظر OK + if (waitForResponse("OK", 5000)) { + Serial1.println("✅ URL set successfully"); + } else { + Serial1.println("❌ Failed to set URL"); + return false; + } + } else { + Serial1.println("❌ CONNECT timeout"); + return false; + } + + // اجرای درخواست GET + Serial1.println("🚀 Sending GET request..."); + EC200U.println("AT+QHTTPGET=120"); + + if (waitForResponse("+QHTTPGET:", 30000)) { + Serial1.println("✅ GET request sent"); + + // بررسی کد پاسخ + String response = ""; + unsigned long start = millis(); + while (millis() - start < 5000) { + while (EC200U.available()) { + char c = EC200U.read(); + response += c; + Serial1.write(c); + } + if (response.indexOf("OK") != -1 || response.indexOf("ERROR") != -1) { + break; + } + } + + // خواندن پاسخ سرور + Serial1.println("📖 Reading server response..."); + EC200U.println("AT+QHTTPREAD=80"); + + if (waitForResponse("+QHTTPREAD:", 15000)) { + Serial1.println("✅ Response received"); + + // خواندن داده‌های پاسخ + String serverResponse = ""; + start = millis(); + while (millis() - start < 10000) { + while (EC200U.available()) { + char c = EC200U.read(); + serverResponse += c; + Serial1.write(c); + } + if (serverResponse.indexOf("OK") != -1 || serverResponse.indexOf("ERROR") != -1) { + break; + } + } + + Serial1.println("✅ Data sent successfully"); + return true; + } else { + Serial1.println("❌ Failed to read response"); + return false; + } + } else { + Serial1.println("❌ GET request failed"); + return false; + } +} + +// --------------------------- setup --------------------------- +void setup() { + pinMode(PWRKEY_PIN, OUTPUT); + digitalWrite(PWRKEY_PIN, LOW); + + Serial1.begin(115200); + EC200U.begin(115200); + delay(3000); + + Serial1.println("🚀 System Starting..."); + + // مقداردهی سنسورها + dht.begin(); + + Wire.setSDA(SDA_PIN); + Wire.setSCL(SCL_PIN); + Wire.begin(); + + if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) { + Serial1.println("✅ BH1750 OK"); + } else { + Serial1.println("❌ BH1750 Error"); + } + + // مقداردهی پین‌های آنالوگ + pinMode(SOIL_PIN, INPUT); + pinMode(MQ7_PIN, INPUT); + + initEC200U(); + getNetworkTime(); + + Serial1.println("✅ System Ready"); +} + +// --------------------------- loop --------------------------- +unsigned long lastUpload = 0; + +void loop() { + if (millis() - lastUpload > UPLOAD_INTERVAL_MIN * 60UL * 1000UL || lastUpload == 0) { + Serial1.println("=========================================="); + + // خواندن سنسورها + float temp = readTemp(); + float hum = readHum(); + int soil = readSoil(); + float gas = MQ7_ReadPPM(); + float lux = readLight(); + + // نمایش مقادیر + Serial1.println("📊 Sensor Readings:"); + Serial1.println("Temperature: " + String(temp, 1) + "°C"); + Serial1.println("Humidity: " + String(hum, 1) + "%"); + Serial1.println("Soil: " + String(soil) + "%"); + Serial1.println("Gas: " + String(gas, 0) + " ppm"); + Serial1.println("Light: " + String(lux, 1) + " lux"); + Serial1.println("------------------------------------------"); + + // ارسال داده + if (sendData(temp, hum, soil, gas, lux, networkTime)) { + Serial1.println("🎉 Data upload successful!"); + } else { + Serial1.println("❌ Data upload failed!"); + } + + lastUpload = millis(); + Serial1.println("=========================================="); + } + + delay(1000); +} \ No newline at end of file