Files
Arduino/old/Stm32Test1/Stm32Test1.ino
2025-12-19 11:50:13 +03:30

211 lines
6.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <Arduino.h>
#include <Wire.h>
#include <BH1750.h>
#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; // 50140ppm
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);
}