249 lines
5.9 KiB
C++
249 lines
5.9 KiB
C++
#include <Arduino.h>
|
|
#include <Wire.h>
|
|
#include <Adafruit_GFX.h>
|
|
#include <Adafruit_SSD1306.h>
|
|
#include <Fonts/FreeSans9pt7b.h>
|
|
#include <Fonts/FreeSansBold12pt7b.h>
|
|
#include <Fonts/FreeSansBold18pt7b.h>
|
|
//#include <Adafruit_SHT31.h>
|
|
//#include <BH1750.h>
|
|
#include <SPI.h>
|
|
|
|
// -------------------- فایلهای پروژه --------------------
|
|
#include "Config.h"
|
|
#include "Memory.h"
|
|
#include "Sensors.h"
|
|
#include "EC200U.h"
|
|
#include "Display.h"
|
|
#include "Voltage_Reader.h"
|
|
#include "BatteryReader.h"
|
|
|
|
// -------------------- متغیرهای سراسری --------------------
|
|
//Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
|
|
|
BatteryReader batteryReader(BATTERY_VOLTAGE_PIN_A3); // برای باتری
|
|
|
|
//Adafruit_SHT31 sht31 = Adafruit_SHT31();
|
|
//BH1750 lightMeter;
|
|
|
|
SystemStatus i2cStatus = {false, false, 0, 0, 0};
|
|
|
|
HardwareSerial EC200U(USART3);
|
|
SPIClass flashSPI(FLASH_MOSI, FLASH_MISO, FLASH_SCK);
|
|
|
|
DeviceConfig config;
|
|
SensorData currentData;
|
|
|
|
// متغیرهای موقت برای پردازش پیامکها
|
|
String tempPhoneNumber = "";
|
|
String tempTokenCode = "";
|
|
bool awaitingSMS2 = false;
|
|
|
|
unsigned long lastSensorRead = 0;
|
|
unsigned long lastUpload = 0;
|
|
unsigned long lastDisplayChange = 0;
|
|
unsigned long lastNetworkStatusUpdate = 0;
|
|
|
|
Arduino_GC9A01* tft = nullptr;
|
|
|
|
bool networkConnected = false;
|
|
int displayMode = 0;
|
|
String lastError = "";
|
|
String currentAPN = "";
|
|
String lastMessage = "";
|
|
|
|
// وضعیت سنسورها و اتصالات
|
|
bool sht31Connected = false;
|
|
bool lightSensorConnected = false;
|
|
bool coSensorConnected = false;
|
|
bool simConnected = false;
|
|
bool networkRegistered = false;
|
|
int signalStrength = 0;
|
|
|
|
// متغیرهای CO کالیبراسیون
|
|
unsigned long systemStartTime = 0;
|
|
const long calibrationPeriod = 600000; // 10 دقیقه
|
|
|
|
//float MQ7_R0 = 10000.0;
|
|
|
|
bool isInCall = false;
|
|
|
|
|
|
bool powerState = false;
|
|
|
|
|
|
TwoWire Wire1(1); // I2C1
|
|
|
|
|
|
// -------------------- Setup --------------------
|
|
void setup() {
|
|
Serial1.begin(115200);
|
|
|
|
pinMode(PWRKEY_PIN, OUTPUT);
|
|
digitalWrite(PWRKEY_PIN, LOW);
|
|
|
|
pinMode(POWER_PIN, INPUT);
|
|
|
|
powerState = digitalRead(POWER_PIN) == HIGH;
|
|
|
|
delay(1000);
|
|
|
|
Serial1.println("\n\n🚀 IoT Device Starting...");
|
|
|
|
systemStartTime = millis();
|
|
|
|
pinMode(MQ7_PIN, INPUT);
|
|
initDisplay();
|
|
initSensors();
|
|
// Wire1.setSDA(PB9);
|
|
// Wire1.setSCL(PB8);
|
|
// Wire1.begin();
|
|
// //Wire1.setClock(100000);
|
|
|
|
// // I2C2 برای BH1750
|
|
// Wire.setSDA(PB7);
|
|
// Wire.setSCL(PB6);
|
|
// Wire.begin();
|
|
//Wire.setClock(100000);
|
|
|
|
// 1. ولتاژ را تست کن
|
|
bool voltageOK = voltageReader.testCircuit();
|
|
|
|
if (!voltageOK) {
|
|
Serial1.println("⚠️ Voltage issue detected!");
|
|
}
|
|
|
|
// 2. اطلاعات دیباگ ولتاژ
|
|
voltageReader.debugInfo();
|
|
|
|
// 3. خواندن اولیه ولتاژ
|
|
float initialVoltage = voltageReader.readVoltage();
|
|
Serial1.print("Initial voltage: ");
|
|
Serial1.print(initialVoltage, 2);
|
|
Serial1.println("V");
|
|
Serial1.println("1");
|
|
|
|
/*
|
|
// Wire = Wire1;
|
|
sht31Connected = sht31.begin(0x44,&Wire1);
|
|
Serial1.println("1");
|
|
Wire.beginTransmission(0x23);
|
|
uint8_t err = Wire.endTransmission();
|
|
|
|
Serial1.print("BH1750 ACK = ");
|
|
Serial1.println(err);
|
|
lightSensorConnected = lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23);
|
|
//lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE);
|
|
Serial1.println("2");
|
|
*/
|
|
flashInit();
|
|
readConfig();
|
|
|
|
currentData.batteryVoltage = batteryReader.readVoltage();
|
|
|
|
//calibrateMQ7();
|
|
//setupMQ7();
|
|
|
|
awaitingSMS2 = false;
|
|
tempPhoneNumber = "";
|
|
tempTokenCode = "";
|
|
|
|
readSensors();
|
|
displayAllParameters();
|
|
updateDisplay();
|
|
//--------------------------------
|
|
|
|
EC200U.begin(115200);
|
|
initEC200U();
|
|
if (config.verified) {
|
|
Serial1.println("Device ID: " + String(config.deviceId));
|
|
currentAPN = simTypeToAPN(config.simType);
|
|
//initEC200U();
|
|
} else {
|
|
Serial1.println("⚠️ Not configured - Waiting for SMS");
|
|
}
|
|
|
|
|
|
updateNetworkStatus();
|
|
lastNetworkStatusUpdate = millis();
|
|
|
|
Serial1.println("✅ Ready - CO calibration: " + String(MQ7sensorPreheated ? "Complete" : "In progress"));
|
|
|
|
if (config.verified && networkConnected) {
|
|
Serial1.println("\n🚀 First upload - sending data immediately...");
|
|
uploadData();
|
|
}
|
|
}
|
|
|
|
// -------------------- Loop --------------------
|
|
void loop() {
|
|
if (!isInCall) {
|
|
digitalWrite(PWRKEY_PIN, LOW);
|
|
}
|
|
|
|
|
|
checkSMS();
|
|
|
|
if (millis() - lastSensorRead > SENSOR_READ_INTERVAL) {
|
|
//readSensors();
|
|
readSensors();
|
|
lastSensorRead=millis();
|
|
float batteryVoltage = batteryReader.readVoltage();
|
|
float batteryPercent = batteryReader.getBatteryPercentage();
|
|
currentData.batteryVoltage=batteryVoltage;
|
|
currentData.batteryPercent=batteryPercent;
|
|
|
|
/*Serial1.print("📊 Battery Voltage: ");
|
|
Serial1.print(batteryVoltage, 2);
|
|
Serial1.println("V");*/
|
|
/*
|
|
Serial1.print("📊 Battery Percentage: ");
|
|
Serial1.print(batteryPercent, 2);
|
|
Serial1.println("%");
|
|
*/
|
|
|
|
float voltage = voltageReader.readVoltage();
|
|
/**/
|
|
Serial1.print("📊 System Voltage: ");
|
|
Serial1.print(voltage, 2);
|
|
Serial1.println("V");
|
|
/**/
|
|
currentData.volage=voltage;
|
|
|
|
bool currentPower = digitalRead(POWER_PIN) == HIGH;
|
|
|
|
if(currentPower)
|
|
currentData.power=1;
|
|
else
|
|
currentData.power=0;
|
|
|
|
if(powerState)
|
|
currentData.oldPower=1;
|
|
else
|
|
currentData.oldPower=0;
|
|
|
|
if (currentPower != powerState) {
|
|
powerState = currentPower;
|
|
|
|
if (powerState) {
|
|
Serial.println("5V Connected");
|
|
} else {
|
|
Serial.println("5V Disconnected");
|
|
}
|
|
lastUpload -= 86400000L;
|
|
}
|
|
powerState = currentPower;
|
|
|
|
updateDisplay();
|
|
unsigned long uploadIntervalMs = config.uploadInterval * 60000UL;
|
|
if (millis() - lastUpload > uploadIntervalMs) {
|
|
// Serial1.print("Upload interval reached (");
|
|
// Serial1.print(config.uploadInterval);
|
|
// Serial1.println(" min), starting upload...");
|
|
uploadData();
|
|
}
|
|
}
|
|
|
|
delay(100);
|
|
}
|