#include <SoftwareSerial.h> // اضافه کردن کتابخانه برای ارتباط سریال نرمافزاری
#include <avr/wdt.h> // اضافه کردن کتابخانه برای Watchdog Timer
#include <TinyGPS++.h> // اضافه کردن کتابخانه GPS
SoftwareSerial sim800(0, 1); // تعریف پورت سریال نرمافزاری برای ماژول SIM800 (پینهای 0 و 1)
SoftwareSerial gpsSerial(2, 3); // تعریف پورت سریال نرمافزاری برای GPS (پینهای 2 و 3)
TinyGPSPlus gps; // ایجاد شیء GPS
// تعریف ثابتها برای پینها
const int pumpRelayPin = 4; // پین رله پمپ
const int lockPin = 5; // پین قفل دربها
const int buzzerPin = 13; // پین بوزر
const int openPin = 6; // پین باز کردن دربها
const int rightWindowLifter = 7; // پین شیشه بالابر سمت راست
const int rightWindowEncoder = 8; // پین انکودر شیشه بالابر سمت راست
const int leftWindowLifter = 9; // پین شیشه بالابر سمت چپ
const int leftWindowEncoder = 10; // پین انکودر شیشه بالابر سمت چپ
const int voltageSensorPin = A4; // پین سنسور ولتاژ
const int indicatorlight = 11; // پین چراغ راهنما
const int alarmStarlight = 12; // پین چشمک زن دزدگیر
// پینهای 74HC165
const int dataPin = A0; // پین Q7 (Pin 1)
const int clockPin = A1; // پین CP (Pin 2)
const int latchPin = A2; // پین CE (Pin 3)
const int loadPin = A3; // پین SH/LD (Pin 15)
// معرفی ورودیهایی که به 74HC165 متصل هستند
const int shockSensorPin = 0; // پین سنسور لرزش
const int doorPin = 1; // پین درب
const int remotePin1 = 2; // پین ریموت کنترل 1
const int remotePin2 = 3; // پین ریموت کنترل 2
const int remotePin3 = 4; // پین ریموت کنترل 3
const int remotePin4 = 5; // پین ریموت کنترل 4
const int switchPowerPin = 6; // پین برق سوئیچ
const int extraSensorPin = 7; // پین سنسور اضافی (در صورت نیاز)
const String phoneNumber = "+0000000000000"; // شماره تلفن مقصد
// تعریف وضعیتها با استفاده از enum
enum AlarmState { INACTIVE, ACTIVE, ACTIVE_SILENT };
// متغیرهای وضعیت
AlarmState alarmState = INACTIVE; // وضعیت اولیه دزدگیر (غیرفعال)
volatile unsigned long timerTicks = 0; // شمارش تیکهای تایمر
unsigned long alarmStartTime = 0; // زمان شروع دزدگیر
unsigned long switchOffTime = 0; // زمان خاموش شدن سوئیچ
unsigned long previousVoltageTime = 0; // زمان قبلی برای هشدار ولتاژ پایین
unsigned long indicatorlightTime = 0; // زمان چراغ راهنما
unsigned long lastStatusSMS = 0; // زمان آخرین ارسال پیامک وضعیت
unsigned long rightWindowLifterTime = 0; // متغیر زمان برای شیشه بالابر راست
unsigned long leftWindowLifterTime = 0; // متغیر زمان برای شیشه بالابر چپ
unsigned long sim800SetupTime = 0; // زمان برای تنظیمات SIM800
unsigned long confirmActionTime = 0; // زمان برای بیپها و چشمکها
bool sim800Initialized = false; // پرچم برای بررسی اتمام تنظیمات SIM800
bool lockPinState = false; // وضعیت قفل پین
bool switchPower2State = false; // وضعیت برق سوئیچ
bool ActiveBuzzer = false; // وضعیت بوزر
bool switchPower3State = false; // وضعیت برق سوئیچ دوم
bool rightWindowEncoderState = false; // وضعیت انکودر شیشه بالابر سمت راست
bool leftWindowEncoderState = false; // وضعیت انکودر شیشه بالابر سمت چپ
bool voltageBuzzerState = false; // وضعیت بازر ولتاژ
bool doorPinState = false; // وضعیت دربها
bool shockSensorPinState = false; // وضعیت سنسورهای لرزش
bool switchPower4State = false; // وضعیت برق سوئیچ سوم
bool confirmInProgress = false; // پرچم برای مدیریت بیپها و چشمکها
int confirmStep = 0; // مرحله فعلی بیپ و چشمک
const float voltageThreshold = 11.0; // حداقل ولتاژ مجاز
const unsigned long SIM800_INIT_INTERVAL = 1000; // فاصله برای دستورات SIM800 (1 ثانیه)
const unsigned long DELAY_300_MS = 300; // تاخیر 300 میلیثانیه
const unsigned long DELAY_1000_MS = 1000; // تاخیر 1 ثانیه
const unsigned long BEEP_DURATION = 100; // مدت زمان هر بیپ (100ms)
const unsigned long BLINK_DURATION = 200; // مدت زمان هر چشمک (200ms)
const unsigned long CONFIRM_INTERVAL = 200; // فاصله بین بیپها و چشمکها (200ms)
// تنظیمات اولیه
void setup() {
// تنظیم پینها به عنوان ورودی یا خروجی
pinMode(pumpRelayPin, OUTPUT);
pinMode(lockPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(openPin, OUTPUT);
pinMode(leftWindowLifter, OUTPUT);
pinMode(leftWindowEncoder, INPUT);
pinMode(rightWindowLifter, OUTPUT);
pinMode(rightWindowEncoder, INPUT);
pinMode(indicatorlight, OUTPUT);
pinMode(alarmStarlight, OUTPUT);
// تنظیم پینهای 74HC165
pinMode(dataPin, INPUT);
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(loadPin, OUTPUT);
Serial.begin(9600);
sim800.begin(9600);
gpsSerial.begin(9600);
// تنظیم تایمر سختافزاری Timer1
noInterrupts();
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 15624; // برای فرکانس 1Hz با PLANETEXT
TCCR1B |= (1 << WGM12); // حالت CTC
TCCR1B |= (1 << CS12) | (1 << CS10); // پیشتقسیمکننده 1024
TIMSK1 |= (1 << OCIE1A); // فعال کردن وقفه مقایسه
interrupts();
wdt_enable(WDTO_8S); // فعال کردن Watchdog Timer با تایمر 8 ثانیه
sim800SetupTime = millis(); // شروع زمانبندی برای تنظیمات SIM800
}
// ISR برای تایمر1
ISR(TIMER1_COMPA_vect) {
timerTicks++; // افزایش شمارش تیکهای تایمر
}
// تابع تأیید دستور با دو بیپ و دو چشمک
void confirmAction() {
if (!confirmInProgress) {
confirmInProgress = true;
confirmStep = 0;
confirmActionTime = millis();
}
unsigned long currentMillis = millis();
if (confirmStep == 0 && currentMillis - confirmActionTime >= CONFIRM_INTERVAL) {
digitalWrite(buzzerPin, HIGH);
digitalWrite(indicatorlight, HIGH);
confirmStep = 1;
confirmActionTime = currentMillis;
} else if (confirmStep == 1 && currentMillis - confirmActionTime >= BEEP_DURATION) {
digitalWrite(buzzerPin, LOW);
confirmStep = 2;
confirmActionTime = currentMillis;
} else if (confirmStep == 2 && currentMillis - confirmActionTime >= CONFIRM_INTERVAL) {
digitalWrite(indicatorlight, LOW);
confirmStep = 3;
confirmActionTime = currentMillis;
} else if (confirmStep == 3 && currentMillis - confirmActionTime >= CONFIRM_INTERVAL) {
digitalWrite(buzzerPin, HIGH);
digitalWrite(indicatorlight, HIGH);
confirmStep = 4;
confirmActionTime = currentMillis;
} else if (confirmStep == 4 && currentMillis - confirmActionTime >= BEEP_DURATION) {
digitalWrite(buzzerPin, LOW);
confirmStep = 5;
confirmActionTime = currentMillis;
} else if (confirmStep == 5 && currentMillis - confirmActionTime >= BLINK_DURATION) {
digitalWrite(indicatorlight, LOW);
confirmStep = 0;
confirmInProgress = false;
confirmActionTime = currentMillis;
}
}
// تابع خواندن ورودیها
void readInputs(bool &shockSensorState, bool &doorState, bool &remote1State, bool &remote2State,
bool &remote3State, bool &remote4State, bool &switchPowerState, int &sensorValue) {
uint8_t inputStates = read74HC165();
shockSensorState = bitRead(inputStates, shockSensorPin);
doorState = bitRead(inputStates, doorPin);
remote1State = bitRead(inputStates, remotePin1);
remote2State = bitRead(inputStates, remotePin2);
remote3State = bitRead(inputStates, remotePin3);
remote4State = bitRead(inputStates, remotePin4);
switchPowerState = bitRead(inputStates, switchPowerPin);
sensorValue = analogRead(voltageSensorPin);
}
// تابع خواندن ورودیها از 74HC165
uint8_t read74HC165() {
uint8_t value = 0;
digitalWrite(loadPin, LOW);
digitalWrite(loadPin, HIGH);
for (int i = 0; i < 8; i++) {
value |= digitalRead(dataPin) << i;
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
return value;
}
// تابع تنظیم وضعیت دزدگیر
void setAlarmState(AlarmState newState) {
alarmState = newState;
}
// تابع ارسال پیامک
void sendSMS(String phoneNumber, String message) {
static unsigned long smsStartTime = 0;
static int smsStep = 0;
unsigned long currentMillis = millis();
if (smsStep == 0 && currentMillis - smsStartTime >= SIM800_INIT_INTERVAL) {
sim800.println("AT+CMGF=1");
smsStep = 1;
smsStartTime = currentMillis;
} else if (smsStep == 1 && currentMillis - smsStartTime >= SIM800_INIT_INTERVAL) {
sim800.print("AT+CMGS=\"");
sim800.print(phoneNumber);
sim800.println("\"");
smsStep = 2;
smsStartTime = currentMillis;
} else if (smsStep == 2 && currentMillis - smsStartTime >= SIM800_INIT_INTERVAL) {
sim800.print(message);
smsStep = 3;
smsStartTime = currentMillis;
} else if (smsStep == 3 && currentMillis - smsStartTime >= SIM800_INIT_INTERVAL) {
sim800.println((char)26);
smsStep = 0;
smsStartTime = currentMillis;
}
}
// تابع بررسی دریافت پیامک
bool receiveSMS(String command) {
if (sim800.available()) {
String message = sim800.readString();
return (message.indexOf(command) != -1);
}
return false;
}
// تابع بررسی پیامکها
void checkSMS() {
if (sim800.available()) {
String message = sim800.readString();
if (message.indexOf("وضعیت") != -1) {
String statusMessage = "وضعیت دزدگیر: ";
statusMessage += (alarmState == ACTIVE) ? "فعال" :
(alarmState == INACTIVE) ? "غیرفعال" : "فعال (سایلنت)";
sendSMS(phoneNumber, statusMessage);
}
}
}
// بررسی پیامکهای دریافتی
void checkReceiveSMS() {
if (receiveSMS("فعال")) {
checkActiveAlarmState();
sendSMS(phoneNumber, "دزدگیر فعال شد!");
confirmAction();
} else if (receiveSMS("غیرفعال")) {
checkInactiveAlarmState();
sendSMS(phoneNumber, "دزدگیر غیرفعال شد!");
confirmAction();
} else if (receiveSMS("سایلنت")) {
checkActiveSilentAlarmState();
sendSMS(phoneNumber, "دزدگیر حالت سایلنت فعال شد!");
confirmAction();
}
}
// تابع دریافت موقعیت مکانی از GPS
String getGPSLocation() {
String location = "";
if (gps.location.isValid()) {
location += "Lat: " + String(gps.location.lat(), 6);
location += ", Lon: " + String(gps.location.lng(), 6);
} else {
location = "موقعیت مکانی نامعتبر";
}
return location;
}
// تابع بررسی وضعیت فعال دزدگیر خودرو
void checkActiveAlarmState() {
alarmState = ACTIVE;
switchPower2State = true;
switchPower3State = false;
ActiveBuzzer = false;
shockSensorPinState = false;
doorPinState = false;
voltageBuzzerState = false;
Serial.println("دزدگیر فعال شد!");
}
// تابع بررسی وضعیت غیرفعال دزدگیر خودرو
void checkInactiveAlarmState() {
alarmState = INACTIVE;
switchOffTime = millis();
switchPower2State = false;
ActiveBuzzer = false;
switchPower3State = false;
digitalWrite(buzzerPin, LOW);
digitalWrite(rightWindowLifter, LOW);
digitalWrite(leftWindowLifter, LOW);
digitalWrite(indicatorlight, LOW);
Serial.println("دزدگیر غیر فعال شد!");
}
// تابع بررسی وضعیت فعال سایلنت دزدگیر خودرو
void checkActiveSilentAlarmState() {
alarmState = ACTIVE_SILENT;
switchPower2State = true;
switchPower3State = false;
ActiveBuzzer = false;
shockSensorPinState = false;
doorPinState = false;
voltageBuzzerState = false;
Serial.println("دزدگیر حالت سایلنت فعال شد!");
}
// تابع بررسی و تغییر وضعیت دزدگیر
void checkRemoteStates(bool remote1State, bool remote2State, bool remote3State, bool remote4State) {
static unsigned long remoteActionTime = 0;
if (remote1State == HIGH && millis() - remoteActionTime >= DELAY_300_MS) {
checkActiveAlarmState();
confirmAction();
remoteActionTime = millis();
} else if (remote2State == HIGH && millis() - remoteActionTime >= DELAY_300_MS) {
checkInactiveAlarmState();
confirmAction();
remoteActionTime = millis();
} else if (remote3State == HIGH && ActiveBuzzer && millis() - remoteActionTime >= DELAY_300_MS) {
Serial.println("الارم غیرفعال شد!");
digitalWrite(buzzerPin, LOW);
digitalWrite(indicatorlight, LOW);
switchPower2State = true;
ActiveBuzzer = false;
doorPinState = false;
shockSensorPinState = false;
confirmAction();
remoteActionTime = millis();
} else if (remote4State == HIGH && millis() - remoteActionTime >= DELAY_300_MS) {
checkActiveSilentAlarmState();
confirmAction();
remoteActionTime = millis();
}
}
// تابع بررسی و مدیریت سنسور درب
void checkAlarmDoors(bool doorState) {
static unsigned long doorActionTime = 0;
if (doorState == HIGH && !doorPinState && millis() - doorActionTime >= DELAY_300_MS) {
Serial.println("سنسور درب فعال شد!");
alarmStartTime = millis();
sendSMS(phoneNumber, "سنسور درب فعال شد!");
digitalWrite(buzzerPin, HIGH);
Serial.println("الارم فعال شد!");
ActiveBuzzer = true;
doorPinState = true;
doorActionTime = millis();
}
}
// کنترل دربهای خودرو در وضعیت دزدگیر غیرفعال
void checkDoorState(bool doorState) {
static unsigned long doorActionTime = 0;
if (doorState == HIGH && !doorPinState && millis() - doorActionTime >= DELAY_300_MS) {
Serial.println("درب خودرو باز شد!");
doorPinState = true;
doorActionTime = millis();
} else if (doorState == LOW && doorPinState && millis() - doorActionTime >= DELAY_300_MS) {
doorPinState = false;
Serial.println("درب خودرو بسته شد!");
doorActionTime = millis();
}
}
// تابع بررسی و مدیریت الارم سنسور لرزش
void checkAlarmShockSensor(bool shockSensorState) {
static unsigned long shockActionTime = 0;
if ((alarmState == ACTIVE || alarmState == ACTIVE_SILENT) && shockSensorState == HIGH &&
!shockSensorPinState && millis() - shockActionTime >= DELAY_300_MS) {
if (alarmState == ACTIVE_SILENT) {
Serial.println("سنسور لرزش فعال شد!");
alarmStartTime = millis();
sendSMS(phoneNumber, "سنسور لرزش فعال شد!");
shockSensorPinState = true;
ActiveBuzzer = true;
} else {
Serial.println("سنسور لرزش فعال شد!");
alarmStartTime = millis();
sendSMS(phoneNumber, "سنسور لرزش فعال شد!");
digitalWrite(buzzerPin, HIGH);
Serial.println("الارم فعال شد!");
shockSensorPinState = true;
ActiveBuzzer = true;
}
shockActionTime = millis();
}
}
// تابع بررسی وضعیت بوزر
void checkBuzzer() {
if (ActiveBuzzer && millis() - alarmStartTime >= 10000) {
Serial.println("الارم غیرفعال شد!");
sendSMS(phoneNumber, "الارم غیرفعال شد!");
digitalWrite(buzzerPin, LOW);
ActiveBuzzer = false;
switchPower2State = true;
switchPower3State = false;
shockSensorPinState = false;
doorPinState = false;
voltageBuzzerState = false;
}
}
// تابع بررسی وضعیت سوئیچ خودرو
void checkSwitchPower(bool switchPowerState) {
static unsigned long switchActionTime = 0;
if (switchPowerState == HIGH && !switchPower2State && !switchPower3State) {
switchOffTime = millis();
} else if (switchPowerState == LOW && !switchPower2State && !switchPower3State &&
millis() - switchOffTime >= 10000) {
setAlarmState(ACTIVE);
sendSMS(phoneNumber, "دزدگیر فعال شد!");
Serial.println("دزدگیر فعال شد!");
confirmAction();
switchPower2State = true;
} else if (switchPowerState == HIGH && (alarmState == ACTIVE_SILENT || alarmState == ACTIVE) &&
switchPower2State && millis() - switchActionTime >= DELAY_300_MS) {
digitalWrite(buzzerPin, HIGH);
Serial.println("الارم سویچ فعال شد!");
alarmStartTime = millis();
sendSMS(phoneNumber, "الارم سویچ فعال شد!");
switchPower2State = false;
switchPower3State = true;
ActiveBuzzer = true;
switchActionTime = millis();
}
if (switchPowerState == HIGH && !switchPower4State && alarmState == INACTIVE &&
millis() - switchActionTime >= DELAY_300_MS) {
Serial.println("سوئیچ خودرو باز شد!");
switchPower4State = true;
switchActionTime = millis();
} else if (switchPowerState == LOW && switchPower4State && alarmState == INACTIVE &&
millis() - switchActionTime >= DELAY_300_MS) {
Serial.println("سوئیچ خودرو بسته شد!");
switchPower4State = false;
switchActionTime = millis();
}
}
// تابع کنترل چشمکزن و راهنماها
void checkIndicators(bool doorState) {
if ((digitalRead(buzzerPin) == HIGH) || ActiveBuzzer || (doorState == HIGH)) {
unsigned long currentMillis = millis();
if (currentMillis - indicatorlightTime >= 500) {
indicatorlightTime = currentMillis;
if (!confirmInProgress) { // جلوگیری از تداخل با چشمکهای تأیید
digitalWrite(indicatorlight, !digitalRead(indicatorlight));
}
}
} else {
if (!confirmInProgress) { // جلوگیری از خاموش کردن راهنما در حین تأیید
digitalWrite(indicatorlight, LOW);
ActiveBuzzer = false;
}
}
}
// تابع کنترل قفل دربها و شیشه بالابرها
void checkLocksAndWindows() {
static unsigned long lockActionTime = 0;
if ((alarmState == ACTIVE_SILENT || alarmState == ACTIVE) && !lockPinState &&
millis() - lockActionTime >= DELAY_1000_MS) {
digitalWrite(lockPin, HIGH);
digitalWrite(rightWindowLifter, HIGH);
digitalWrite(leftWindowLifter, HIGH);
rightWindowEncoderState = false;
leftWindowEncoderState = false;
Serial.println("شیشه بالابر سمت راست و چپ فعال شدند!");
Serial.println("دربها قفل شدند!");
rightWindowLifterTime = millis();
leftWindowLifterTime = millis();
digitalWrite(lockPin, LOW);
lockPinState = true;
lockActionTime = millis();
} else if (alarmState == INACTIVE && lockPinState && millis() - lockActionTime >= DELAY_1000_MS) {
lockPinState = false;
digitalWrite(openPin, HIGH);
Serial.println("دربها باز شدند!");
digitalWrite(openPin, LOW);
lockActionTime = millis();
}
if (digitalRead(rightWindowLifter) == HIGH && digitalRead(rightWindowEncoder) == LOW &&
!rightWindowEncoderState && millis() - rightWindowLifterTime >= DELAY_300_MS) {
digitalWrite(rightWindowLifter, LOW);
Serial.println("شیشه بالابر سمت راست غیر فعال شد!");
rightWindowEncoderState = true;
}
if (digitalRead(rightWindowLifter) == HIGH && millis() - rightWindowLifterTime >= 15000) {
digitalWrite(rightWindowLifter, LOW);
Serial.println("شیشه بالابر سمت راست غیر فعال شد!");
rightWindowEncoderState = true;
}
if (digitalRead(leftWindowLifter) == HIGH && digitalRead(leftWindowEncoder) == LOW &&
!leftWindowEncoderState && millis() - leftWindowLifterTime >= DELAY_300_MS) {
digitalWrite(leftWindowLifter, LOW);
Serial.println("شیشه بالابر سمت چپ غیر فعال شد!");
leftWindowEncoderState = true;
}
if (digitalRead(leftWindowLifter) == HIGH && millis() - leftWindowLifterTime >= 15000) {
digitalWrite(leftWindowLifter, LOW);
Serial.println("شیشه بالابر سمت چپ غیر فعال شد!");
leftWindowEncoderState = true;
}
}
// تابع بررسی ولتاژ باتری
void checkBatteryVoltage(int sensorValue) {
float voltage = sensorValue * (5.0 / 1023.0) * 2.4;
if (voltage < voltageThreshold && (alarmState == ACTIVE_SILENT || alarmState == ACTIVE) &&
!voltageBuzzerState) {
Serial.println("الارم ولتاژ پایین فعال شد!");
alarmStartTime = millis();
digitalWrite(buzzerPin, HIGH);
ActiveBuzzer = true;
voltageBuzzerState = true;
}
if (voltage < voltageThreshold && millis() - previousVoltageTime >= 20000) {
Serial.println("هشدار: ولتاژ پایین است!");
sendSMS(phoneNumber, "هشدار: ولتاژ پایین است!");
previousVoltageTime = millis();
}
}
// کنترل چشمکزن دزدگیر
void checkAlarmStarlight() {
digitalWrite(alarmStarlight, (alarmState == ACTIVE_SILENT || alarmState == ACTIVE) ? HIGH : LOW);
}
// تنظیم وضعیت رله پمپ
void checkPumpRelayState() {
digitalWrite(pumpRelayPin, (alarmState == ACTIVE_SILENT || alarmState == ACTIVE) ? LOW : HIGH);
}
// بررسی تماس ورودی
void callSim() {
static unsigned long callActionTime = 0;
static bool inCall = false;
if (sim800.available()) {
String response = sim800.readString();
Serial.println(response);
if (response.indexOf("RING") != -1 && millis() - callActionTime >= DELAY_1000_MS) {
sim800.println("ATA");
inCall = true;
callActionTime = millis();
}
if (inCall && sim800.available()) {
char c = sim800.read();
Serial.print(c);
if (c == '1') {
checkActiveAlarmState();
confirmAction();
} else if (c == '2') {
checkInactiveAlarmState();
confirmAction();
} else if (c == '3') {
checkActiveSilentAlarmState();
confirmAction();
}
String hangupResponse = sim800.readString();
if (hangupResponse.indexOf("NO CARRIER") != -1) {
sim800.println("ATH");
inCall = false;
callActionTime = millis();
}
}
}
}
// بررسی و ارسال موقعیت مکانی
void locationSMS() {
if (receiveSMS("موقعیت")) {
String location = getGPSLocation();
sendSMS(phoneNumber, location);
}
}
// تنظیمات ماژول SIM800
void setupSIM800() {
static int setupStep = 0;
unsigned long currentMillis = millis();
if (setupStep == 0 && currentMillis - sim800SetupTime >= SIM800_INIT_INTERVAL) {
sim800.println("AT");
setupStep = 1;
sim800SetupTime = currentMillis;
} else if (setupStep == 1 && currentMillis - sim800SetupTime >= SIM800_INIT_INTERVAL) {
sim800.println("AT+CLIP=1");
setupStep = 2;
sim800SetupTime = currentMillis;
} else if (setupStep == 2 && currentMillis - sim800SetupTime >= SIM800_INIT_INTERVAL) {
sim800.println("AT+CSCS=\"GSM\"");
setupStep = 3;
sim800SetupTime = currentMillis;
} else if (setupStep == 3 && currentMillis - sim800SetupTime >= SIM800_INIT_INTERVAL) {
sim800.println("AT+CMGF=1");
setupStep = 4;
sim800SetupTime = currentMillis;
} else if (setupStep == 4 && currentMillis - sim800SetupTime >= SIM800_INIT_INTERVAL) {
sim800.println("AT+CLCC=1");
setupStep = 0;
sim800Initialized = true;
sim800SetupTime = currentMillis;
}
}
// حلقه اصلی برنامه
void loop() {
if (!sim800Initialized) {
setupSIM800();
} else {
bool shockSensorState, doorState, remote1State, remote2State, remote3State, remote4State, switchPowerState;
int sensorValue;
readInputs(shockSensorState, doorState, remote1State, remote2State, remote3State, remote4State, switchPowerState, sensorValue);
checkRemoteStates(remote1State, remote2State, remote3State, remote4State);
checkAlarmDoors(doorState);
checkAlarmShockSensor(shockSensorState);
checkBuzzer();
checkSwitchPower(switchPowerState);
checkIndicators(doorState);
checkLocksAndWindows();
checkBatteryVoltage(sensorValue);
checkAlarmStarlight();
checkDoorState(doorState);
checkPumpRelayState();
checkReceiveSMS();
callSim();
locationSMS();
checkSMS();
if (confirmInProgress) {
confirmAction();
}
}
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
wdt_reset();
}