backup 14041130
This commit is contained in:
472
14041130/TestLCD/Sensors - Copy.hold
Normal file
472
14041130/TestLCD/Sensors - Copy.hold
Normal file
@@ -0,0 +1,472 @@
|
||||
#ifndef SENSORS_H
|
||||
#define SENSORS_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include "Config.h"
|
||||
|
||||
#define VCC 4.63
|
||||
#define RL 10000.0
|
||||
#define VDIV_RATIO 0.681
|
||||
#define I2C_TIMEOUT_MS 100
|
||||
|
||||
// تعریف پینها
|
||||
#define BH1750_SDA_PIN PB7
|
||||
#define BH1750_SCL_PIN PB6
|
||||
#define SHT31_SDA_PIN PB9
|
||||
#define SHT31_SCL_PIN PB8
|
||||
|
||||
#define SHT31_ADDR 0x44
|
||||
#define BH1750_ADDR 0x23
|
||||
|
||||
// متغیرهای خارجی
|
||||
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;
|
||||
extern TwoWire Wire1;
|
||||
extern const long calibrationPeriod;
|
||||
|
||||
// توابع
|
||||
void initSensors();
|
||||
void readSensors();
|
||||
void checkSensorStatus();
|
||||
|
||||
// -------------------- پاکسازی باس I2C --------------------
|
||||
inline void i2cBusClear(uint8_t scl_pin, uint8_t sda_pin, bool isWire1 = false) {
|
||||
Serial1.print("Clearing I2C bus on pins SCL:");
|
||||
Serial1.print(scl_pin);
|
||||
Serial1.print(" SDA:");
|
||||
Serial1.println(sda_pin);
|
||||
|
||||
// آزاد کردن باس
|
||||
if (isWire1) {
|
||||
Wire1.end();
|
||||
} else {
|
||||
Wire.end();
|
||||
}
|
||||
|
||||
delay(50);
|
||||
|
||||
// تنظیم پینها به صورت دستی
|
||||
pinMode(scl_pin, OUTPUT_OPEN_DRAIN);
|
||||
pinMode(sda_pin, OUTPUT_OPEN_DRAIN);
|
||||
|
||||
digitalWrite(sda_pin, HIGH);
|
||||
digitalWrite(scl_pin, HIGH);
|
||||
delayMicroseconds(10);
|
||||
|
||||
// تولید پالس کلاک برای رهاسازی باس
|
||||
for (int i = 0; i < 18; i++) {
|
||||
digitalWrite(scl_pin, LOW);
|
||||
delayMicroseconds(5);
|
||||
digitalWrite(scl_pin, HIGH);
|
||||
delayMicroseconds(5);
|
||||
}
|
||||
|
||||
// ایجاد شرط STOP
|
||||
digitalWrite(sda_pin, LOW);
|
||||
delayMicroseconds(5);
|
||||
digitalWrite(scl_pin, HIGH);
|
||||
delayMicroseconds(5);
|
||||
digitalWrite(sda_pin, HIGH);
|
||||
delayMicroseconds(5);
|
||||
|
||||
delay(100);
|
||||
|
||||
// راهاندازی مجدد
|
||||
if (isWire1) {
|
||||
Wire1.setSDA(sda_pin);
|
||||
Wire1.setSCL(scl_pin);
|
||||
Wire1.begin();
|
||||
Wire1.setClock(50000); // سرعت پایین برای پایداری
|
||||
} else {
|
||||
Wire.setSDA(sda_pin);
|
||||
Wire.setSCL(scl_pin);
|
||||
Wire.begin();
|
||||
Wire.setClock(50000); // سرعت پایین برای پایداری
|
||||
}
|
||||
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// -------------------- کالیبراسیون MQ7 --------------------
|
||||
inline void calibrateMQ7() {
|
||||
Serial1.println("Calibrating MQ7...");
|
||||
|
||||
float sumRS = 0;
|
||||
for(int i = 0; i < 50; i++) { // کاهش از 100 به 50
|
||||
int adc = analogRead(MQ7_PIN);
|
||||
float v_adc = adc * (5.0 / 4095.0);
|
||||
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(20); // کاهش تاخیر
|
||||
}
|
||||
|
||||
MQ7_R0 = (sumRS / 50.0) / 9.8;
|
||||
calibrationComplete = true;
|
||||
|
||||
Serial1.print("MQ7 R0 calibrated: ");
|
||||
Serial1.println(MQ7_R0);
|
||||
}
|
||||
|
||||
// -------------------- خواندن CO --------------------
|
||||
inline float readCOImproved() {
|
||||
float sumVoltage = 0;
|
||||
for (int i = 0; i < 10; i++) { // کاهش از 20 به 10
|
||||
int adc = analogRead(MQ7_PIN);
|
||||
float v_adc = adc * (5.0 / 4095.0);
|
||||
sumVoltage += v_adc;
|
||||
delay(1);
|
||||
}
|
||||
|
||||
float v_avg = sumVoltage / 10.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) {
|
||||
ppm = 100.0 * pow(ratio, -1.53);
|
||||
ppm = constrain(ppm, 0, 5000);
|
||||
}
|
||||
|
||||
if (!calibrationComplete) {
|
||||
ppm = -ppm;
|
||||
}
|
||||
|
||||
return ppm;
|
||||
}
|
||||
|
||||
// -------------------- خواندن SHT31 (سادهشده) --------------------
|
||||
inline bool readSHT31(float &temperature, float &humidity) {
|
||||
static uint8_t errorCount = 0;
|
||||
static bool needsReset = false;
|
||||
|
||||
// اگر نیاز به بازنشانی داریم
|
||||
if (needsReset) {
|
||||
Serial1.println("Resetting SHT31 I2C bus...");
|
||||
i2cBusClear(SHT31_SCL_PIN, SHT31_SDA_PIN, false);
|
||||
needsReset = false;
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// تست اتصال اولیه
|
||||
Wire.beginTransmission(SHT31_ADDR);
|
||||
uint8_t connError = Wire.endTransmission();
|
||||
|
||||
if (connError != 0) {
|
||||
Serial1.print("SHT31 connection error: ");
|
||||
Serial1.println(connError);
|
||||
errorCount++;
|
||||
|
||||
if (errorCount >= 2) {
|
||||
needsReset = true;
|
||||
errorCount = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ارسال دستور اندازهگیری (کوتاه)
|
||||
Wire.beginTransmission(SHT31_ADDR);
|
||||
if (Wire.write(0x2C) != 1) { // دستور سریع
|
||||
Serial1.println("SHT31 write failed");
|
||||
return false;
|
||||
}
|
||||
if (Wire.write(0x06) != 1) { // تکرار بالا
|
||||
Serial1.println("SHT31 write failed");
|
||||
return false;
|
||||
}
|
||||
uint8_t writeError = Wire.endTransmission();
|
||||
|
||||
if (writeError != 0) {
|
||||
Serial1.print("SHT31 write error: ");
|
||||
Serial1.println(writeError);
|
||||
errorCount++;
|
||||
|
||||
if (errorCount >= 2) {
|
||||
needsReset = true;
|
||||
errorCount = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// تاخیر اندازهگیری
|
||||
delay(20); // برای حالت High Repeatability
|
||||
|
||||
// خواندن داده
|
||||
uint8_t bytesRead = Wire.requestFrom(SHT31_ADDR, (uint8_t)6, (uint8_t)true);
|
||||
|
||||
if (bytesRead != 6) {
|
||||
Serial1.print("SHT31 read error, bytes: ");
|
||||
Serial1.println(bytesRead);
|
||||
|
||||
// خالی کردن بافر
|
||||
while (Wire.available()) {
|
||||
Wire.read();
|
||||
}
|
||||
|
||||
errorCount++;
|
||||
if (errorCount >= 2) {
|
||||
needsReset = true;
|
||||
errorCount = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// خواندن بایتها
|
||||
uint8_t data[6];
|
||||
for (int i = 0; i < 6; i++) {
|
||||
data[i] = Wire.read();
|
||||
}
|
||||
|
||||
// بررسی CRC (سادهشده)
|
||||
uint16_t tRaw = (data[0] << 8) | data[1];
|
||||
uint16_t hRaw = (data[3] << 8) | data[4];
|
||||
|
||||
// تبدیل مقادیر
|
||||
temperature = -45.0 + 175.0 * tRaw / 65535.0;
|
||||
humidity = 100.0 * hRaw / 65535.0;
|
||||
|
||||
// اعتبارسنجی
|
||||
if (isnan(temperature) || isnan(humidity) ||
|
||||
temperature < -40 || temperature > 125 ||
|
||||
humidity < 0 || humidity > 100) {
|
||||
Serial1.println("SHT31 invalid data");
|
||||
return false;
|
||||
}
|
||||
|
||||
errorCount = 0; // ریست شمارنده خطا
|
||||
return true;
|
||||
}
|
||||
|
||||
// -------------------- خواندن BH1750 --------------------
|
||||
inline bool readBH1750(float &lux) {
|
||||
static bool initialized = false;
|
||||
static uint8_t errorCount = 0;
|
||||
|
||||
// مقداردهی اولیه
|
||||
if (!initialized) {
|
||||
Serial1.println("Initializing BH1750...");
|
||||
Wire1.setSDA(BH1750_SDA_PIN);
|
||||
Wire1.setSCL(BH1750_SCL_PIN);
|
||||
Wire1.begin();
|
||||
Wire1.setClock(50000); // سرعت پایین
|
||||
delay(100);
|
||||
|
||||
// پاور آن
|
||||
Wire1.beginTransmission(BH1750_ADDR);
|
||||
Wire1.write(0x01);
|
||||
if (Wire1.endTransmission() != 0) {
|
||||
Serial1.println("BH1750 power on failed");
|
||||
return false;
|
||||
}
|
||||
delay(10);
|
||||
|
||||
// تنظیم حالت
|
||||
Wire1.beginTransmission(BH1750_ADDR);
|
||||
Wire1.write(0x13); // Continuous H-Resolution Mode 0.5lx
|
||||
if (Wire1.endTransmission() != 0) {
|
||||
Serial1.println("BH1750 mode set failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
delay(180); // زمان اولیه برای اندازهگیری
|
||||
}
|
||||
|
||||
// خواندن داده
|
||||
uint8_t bytesRead = Wire1.requestFrom(BH1750_ADDR, (uint8_t)2);
|
||||
|
||||
if (bytesRead != 2) {
|
||||
Serial1.print("BH1750 read error, bytes: ");
|
||||
Serial1.println(bytesRead);
|
||||
errorCount++;
|
||||
|
||||
if (errorCount >= 3) {
|
||||
initialized = false;
|
||||
errorCount = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// خواندن بایتها
|
||||
uint8_t highByte = Wire1.read();
|
||||
uint8_t lowByte = Wire1.read();
|
||||
|
||||
uint16_t raw = (highByte << 8) | lowByte;
|
||||
lux = raw / 1.2f;
|
||||
|
||||
errorCount = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// -------------------- بررسی وضعیت سنسورها --------------------
|
||||
inline void checkSensorStatus() {
|
||||
// فقط چاپ وضعیت فعلی
|
||||
Serial1.println("--- Sensor Status ---");
|
||||
Serial1.print("SHT31: ");
|
||||
Serial1.println(sht31Connected ? "OK" : "ERROR");
|
||||
Serial1.print("BH1750: ");
|
||||
Serial1.println(lightSensorConnected ? "OK" : "ERROR");
|
||||
Serial1.print("MQ7: ");
|
||||
Serial1.println(coSensorConnected ? "OK" : "ERROR");
|
||||
}
|
||||
|
||||
// -------------------- خواندن همه سنسورها --------------------
|
||||
inline void readSensors() {
|
||||
Serial1.println("\n=== Reading Sensors ===");
|
||||
|
||||
// اول BH1750 را بخوان (چون کار میکند)
|
||||
float lux;
|
||||
if (readBH1750(lux)) {
|
||||
currentData.lightLux = lux;
|
||||
lightSensorConnected = true;
|
||||
Serial1.print("BH1750: ");
|
||||
Serial1.print(lux, 0);
|
||||
Serial1.println(" lux");
|
||||
} else {
|
||||
currentData.lightLux = 0;
|
||||
lightSensorConnected = false;
|
||||
Serial1.println("BH1750: FAILED");
|
||||
}
|
||||
|
||||
// سپس SHT31
|
||||
float temperature = NAN, humidity = NAN;
|
||||
bool sht31Read = readSHT31(temperature, humidity);
|
||||
|
||||
if (sht31Read && !isnan(temperature) && !isnan(humidity)) {
|
||||
currentData.temperature = temperature;
|
||||
currentData.humidity = humidity;
|
||||
sht31Connected = true;
|
||||
Serial1.print("SHT31: T=");
|
||||
Serial1.print(temperature, 1);
|
||||
Serial1.print("C, H=");
|
||||
Serial1.print(humidity, 1);
|
||||
Serial1.println("%");
|
||||
} else {
|
||||
currentData.temperature = NAN;
|
||||
currentData.humidity = NAN;
|
||||
sht31Connected = false;
|
||||
Serial1.println("SHT31: FAILED");
|
||||
}
|
||||
|
||||
// کالیبراسیون MQ7
|
||||
if (!calibrationComplete && (millis() - systemStartTime >= calibrationPeriod)) {
|
||||
calibrateMQ7();
|
||||
calibrationComplete = true;
|
||||
}
|
||||
|
||||
// خواندن CO
|
||||
currentData.coPPM = readCOImproved();
|
||||
int adc = analogRead(MQ7_PIN);
|
||||
coSensorConnected = (adc > 10 && adc < 4085);
|
||||
|
||||
Serial1.print("MQ7: ");
|
||||
Serial1.print(currentData.coPPM, 1);
|
||||
Serial1.println(" ppm");
|
||||
|
||||
// محاسبه درصدها
|
||||
calculatePercentages(currentData);
|
||||
|
||||
lastSensorRead = millis();
|
||||
Serial1.println("=== Sensor Readings Complete ===\n");
|
||||
|
||||
// اگر SHT31 کار نمیکند، سیستم را مسدود نکن
|
||||
if (!sht31Connected) {
|
||||
Serial1.println("Warning: SHT31 not responding, continuing anyway...");
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------- مقداردهی اولیه --------------------
|
||||
inline void initSensors() {
|
||||
Serial1.println("Initializing sensors...");
|
||||
|
||||
// راهاندازی I2C1 برای SHT31 (سرعت پایین)
|
||||
Wire.setSDA(SHT31_SDA_PIN);
|
||||
Wire.setSCL(SHT31_SCL_PIN);
|
||||
Wire.begin();
|
||||
Wire.setClock(50000); // 50kHz برای پایداری
|
||||
Wire.setTimeout(100);
|
||||
|
||||
// راهاندازی I2C2 برای BH1750
|
||||
Wire1.setSDA(BH1750_SDA_PIN);
|
||||
Wire1.setSCL(BH1750_SCL_PIN);
|
||||
Wire1.begin();
|
||||
Wire1.setClock(50000); // 50kHz
|
||||
Wire1.setTimeout(100);
|
||||
|
||||
// پیکربندی MQ7
|
||||
pinMode(MQ7_PIN, INPUT);
|
||||
analogReadResolution(12);
|
||||
|
||||
delay(1000);
|
||||
|
||||
// اسکن آدرسهای I2C
|
||||
Serial1.println("Scanning I2C1 (SHT31)...");
|
||||
byte error;
|
||||
int found1 = 0;
|
||||
for(byte addr = 1; addr < 127; addr++) {
|
||||
Wire.beginTransmission(addr);
|
||||
error = Wire.endTransmission();
|
||||
if (error == 0) {
|
||||
Serial1.print("Found device at 0x");
|
||||
if (addr < 16) Serial1.print("0");
|
||||
Serial1.println(addr, HEX);
|
||||
found1++;
|
||||
}
|
||||
}
|
||||
Serial1.print("I2C1 devices: ");
|
||||
Serial1.println(found1);
|
||||
|
||||
Serial1.println("Scanning I2C2 (BH1750)...");
|
||||
int found2 = 0;
|
||||
for(byte addr = 1; addr < 127; addr++) {
|
||||
Wire1.beginTransmission(addr);
|
||||
error = Wire1.endTransmission();
|
||||
if (error == 0) {
|
||||
Serial1.print("Found device at 0x");
|
||||
if (addr < 16) Serial1.print("0");
|
||||
Serial1.println(addr, HEX);
|
||||
found2++;
|
||||
}
|
||||
}
|
||||
Serial1.print("I2C2 devices: ");
|
||||
Serial1.println(found2);
|
||||
|
||||
// تست اولیه سریع
|
||||
Serial1.println("Quick sensor test...");
|
||||
float lux;
|
||||
if (readBH1750(lux)) {
|
||||
lightSensorConnected = true;
|
||||
Serial1.print("BH1750 OK: ");
|
||||
Serial1.print(lux);
|
||||
Serial1.println(" lux");
|
||||
}
|
||||
|
||||
delay(100);
|
||||
|
||||
float temp, hum;
|
||||
if (readSHT31(temp, hum)) {
|
||||
sht31Connected = true;
|
||||
Serial1.print("SHT31 OK: ");
|
||||
Serial1.print(temp);
|
||||
Serial1.print("C ");
|
||||
Serial1.print(hum);
|
||||
Serial1.println("%");
|
||||
}
|
||||
|
||||
Serial1.println("Sensor init done");
|
||||
}
|
||||
|
||||
#endif // SENSORS_H
|
||||
Reference in New Issue
Block a user