200 lines
5.7 KiB
C
200 lines
5.7 KiB
C
#ifndef SENSORS_H
|
|
#define SENSORS_H
|
|
|
|
#include <Arduino.h>
|
|
#include <Adafruit_SHT31.h>
|
|
#include <BH1750.h>
|
|
#include "Config.h"
|
|
|
|
// -------------------- متغیرهای خارجی --------------------
|
|
extern Adafruit_SHT31 sht31;
|
|
extern BH1750 lightMeter;
|
|
extern SensorData currentData;
|
|
extern bool sht31Connected;
|
|
extern bool lightSensorConnected;
|
|
extern bool coSensorConnected;
|
|
extern bool calibrationComplete;
|
|
extern unsigned long systemStartTime;
|
|
extern unsigned long lastSensorRead;
|
|
extern float MQ7_R0;
|
|
|
|
#define VCC 4.63 // ولتاژ واقعی سنسور
|
|
#define RL 10000.0 // مقاومت بار RL
|
|
#define VDIV_RATIO 0.681
|
|
|
|
// ثابتهای کالیبراسیون
|
|
extern const long calibrationPeriod;
|
|
|
|
// -------------------- توابع CO --------------------
|
|
inline void calibrateMQ7() {
|
|
Serial1.println("Calibrating MQ7...");
|
|
|
|
float sumRS = 0;
|
|
for(int i = 0; i < 100; i++) {
|
|
int adc = analogRead(MQ7_PIN);
|
|
float v_adc = adc * (5.0 / 4095.0); // ولتاژ ADC 12 بیتی، 5V
|
|
float v_ao = v_adc / VDIV_RATIO; // اصلاح نسبت تقسیم ولتاژ
|
|
|
|
if (v_ao < 0.01) v_ao = 0.01;
|
|
|
|
float RS = RL * (VCC / v_ao - 1.0); // محاسبه مقاومت سنسور
|
|
sumRS += RS;
|
|
|
|
delay(50);
|
|
}
|
|
|
|
// نسبت RS/R0 در هوای پاک ≈ 9.8
|
|
MQ7_R0 = (sumRS / 100.0) / 9.8;
|
|
calibrationComplete = true;
|
|
|
|
Serial1.print("MQ7 R0 calibrated: ");
|
|
Serial1.println(MQ7_R0);
|
|
}
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
inline float readCOImproved() {
|
|
float sumVoltage = 0;
|
|
for (int i = 0; i < 20; i++) {
|
|
int adc = analogRead(MQ7_PIN);
|
|
float v_adc = adc * (5.0 / 4095.0); // ولتاژ ADC 12 بیتی، 5V
|
|
sumVoltage += v_adc;
|
|
delay(2);
|
|
}
|
|
|
|
float v_avg = sumVoltage / 20.0;
|
|
if (v_avg < 0.01) v_avg = 0.01;
|
|
if (v_avg > 4.99) v_avg = 4.99;
|
|
|
|
float v_ao = v_avg / VDIV_RATIO; // اصلاح تقسیم ولتاژ
|
|
float RS = RL * (VCC / v_ao - 1.0); // مقاومت سنسور
|
|
|
|
float ratio = RS / MQ7_R0;
|
|
float ppm = 0;
|
|
|
|
if (ratio > 0) {
|
|
// رابطه لگاریتمی تقریبی دیتاشیت MQ-7
|
|
ppm = 100.0 * pow(ratio, -1.53);
|
|
|
|
if (ppm < 0) ppm = 0;
|
|
if (ppm > 5000) ppm = 5000; // MQ-7 تا 5k ppm
|
|
}
|
|
|
|
if (!calibrationComplete) {
|
|
ppm = -ppm;
|
|
// Serial1.println("MQ7 not calibrated!");
|
|
}
|
|
|
|
return ppm;
|
|
}
|
|
|
|
// -------------------- بررسی وضعیت سنسورها --------------------
|
|
inline void checkSensorStatus() {
|
|
float temp = sht31.readTemperature();
|
|
float hum = sht31.readHumidity();
|
|
sht31Connected = !isnan(temp) && !isnan(hum) && temp > -40 && temp < 125 && hum >= 0 && hum <= 100;
|
|
|
|
float lux = lightMeter.readLightLevel();
|
|
lightSensorConnected = !isnan(lux) && lux >= 0;
|
|
|
|
int adc = analogRead(MQ7_PIN);
|
|
coSensorConnected = (adc > 0 && adc < 4095);
|
|
}
|
|
|
|
// -------------------- لاگ کامل وضعیت سیستم --------------------
|
|
inline void printFullStatus() {
|
|
extern bool simConnected;
|
|
extern bool networkRegistered;
|
|
extern bool networkConnected;
|
|
extern int signalStrength;
|
|
extern bool awaitingSMS2;
|
|
extern String lastMessage;
|
|
extern DeviceConfig config;
|
|
|
|
Serial1.println("\n========== SYSTEM STATUS ==========");
|
|
|
|
Serial1.println("--- SENSORS ---");
|
|
Serial1.print(" Temperature: ");
|
|
Serial1.print(currentData.temperature, 1);
|
|
Serial1.print(" C [");
|
|
Serial1.print(sht31Connected ? "OK" : "ERR");
|
|
Serial1.println("]");
|
|
|
|
Serial1.print(" Humidity: ");
|
|
Serial1.print(currentData.humidity, 1);
|
|
Serial1.print(" % [");
|
|
Serial1.print(sht31Connected ? "OK" : "ERR");
|
|
Serial1.println("]");
|
|
|
|
Serial1.print(" Light: ");
|
|
Serial1.print(currentData.lightLux, 0);
|
|
Serial1.print(" lux [");
|
|
Serial1.print(lightSensorConnected ? "OK" : "ERR");
|
|
Serial1.println("]");
|
|
|
|
Serial1.print(" CO: ");
|
|
Serial1.print(currentData.coPPM, 1);
|
|
Serial1.print(" ppm [");
|
|
Serial1.print(coSensorConnected ? "OK" : "ERR");
|
|
Serial1.print("] Cal:");
|
|
Serial1.println(calibrationComplete ? "Complete" : "In Progress");
|
|
|
|
Serial1.println("--- NETWORK ---");
|
|
Serial1.print(" SIM Connected: ");
|
|
Serial1.println(simConnected ? "Yes" : "No");
|
|
Serial1.print(" Network Registered:");
|
|
Serial1.println(networkRegistered ? "Yes" : "No");
|
|
Serial1.print(" Signal Strength: ");
|
|
Serial1.print(signalStrength);
|
|
Serial1.println("/31");
|
|
Serial1.print(" Internet: ");
|
|
Serial1.println(networkConnected ? "Online" : "Offline");
|
|
|
|
Serial1.println("--- CONFIG ---");
|
|
Serial1.print(" Verified: ");
|
|
Serial1.println(config.verified ? "Yes" : "No");
|
|
if (config.verified) {
|
|
Serial1.print(" Device ID: ");
|
|
Serial1.println(config.deviceId);
|
|
Serial1.print(" SIM Type: ");
|
|
Serial1.println(simTypeToString(config.simType));
|
|
Serial1.print(" Upload Int: ");
|
|
Serial1.print(config.uploadInterval);
|
|
Serial1.println(" min");
|
|
}
|
|
|
|
Serial1.println("--- SMS STATUS ---");
|
|
Serial1.print(" Awaiting SMS2: ");
|
|
Serial1.println(awaitingSMS2 ? "Yes" : "No");
|
|
Serial1.print(" Last Message: ");
|
|
Serial1.println(lastMessage);
|
|
|
|
Serial1.println("====================================\n");
|
|
}
|
|
|
|
// -------------------- خواندن سنسورها --------------------
|
|
inline void readSensors() {
|
|
currentData.temperature = sht31.readTemperature();
|
|
currentData.humidity = sht31.readHumidity();
|
|
|
|
if (!calibrationComplete && (millis() - systemStartTime >= calibrationPeriod)) {
|
|
calibrationComplete = true;
|
|
Serial1.println("✅ Calibration period completed!");
|
|
}
|
|
|
|
currentData.coPPM = readCOImproved();
|
|
|
|
currentData.lightLux = lightMeter.readLightLevel();
|
|
if (isnan(currentData.lightLux)) currentData.lightLux = 0;
|
|
|
|
checkSensorStatus();
|
|
|
|
printFullStatus();
|
|
|
|
lastSensorRead = millis();
|
|
}
|
|
|
|
#endif // SENSORS_H
|
|
|