#include <EEPROM.h>
#include <TimerOne.h>
// --- تنظیمات ---
#define NUM_SENSORS 3
#define NUM_REMOTE_KEYS 4
// --- پینها ---
const int sensorPins[NUM_SENSORS] = {2, 3, 4};
const int remotePins[NUM_REMOTE_KEYS] = {6, 7, 8, 9};
const int buzzerPin = 5;
const int ledArmedPin = 10;
const int ledDisarmedPin = 11;
const int ledSilentPin = 12;
const int ledSensorPins[NUM_SENSORS] = {A0, A1, A2};
// --- باتری ---
const int batteryRelayPin = A5;
const int batteryAnalogPin = A3;
const float batteryStartCharge = 12.4;
const float batteryStopCharge = 12.6;
const float batteryDividerRatio = 2.6; // نسبت تقسیم مقاومتی
// --- EEPROM ---
#define EEPROM_ADDR_ARMED 0
#define EEPROM_ADDR_SILENT 1
// --- وضعیت سیستم ---
bool systemArmed = false;
bool silentMode = false;
bool buzzerActive = false;
bool sensorTriggered = false;
bool sensorLatched[NUM_SENSORS] = {false};
bool remoteLock[NUM_REMOTE_KEYS] = {false};
bool isCharging = false;
unsigned long lastMotionTime = 0;
const unsigned long alarmDuration = 20000;
// --- بوق ---
volatile bool beepRequested = false;
volatile int beepCount = 0;
// --- تایمر نمایش درصد باتری ---
volatile bool batteryCheckFlag = false;
volatile unsigned int batteryCheckCounter = 0;
// --- توابع EEPROM ---
void saveSystemState() {
EEPROM.write(EEPROM_ADDR_ARMED, systemArmed);
EEPROM.write(EEPROM_ADDR_SILENT, silentMode);
}
void loadSystemState() {
systemArmed = EEPROM.read(EEPROM_ADDR_ARMED);
silentMode = EEPROM.read(EEPROM_ADDR_SILENT);
Serial.println(systemArmed ? (silentMode ? "✅ دزدگیر فعال است (سایلنت)" : "✅ دزدگیر فعال است") : "❌ دزدگیر غیرفعال است");
}
// --- تایمر بوق و کنترل باتری ---
void requestBeep(int times) {
if (!beepRequested) {
beepCount = times * 2;
beepRequested = true;
}
}
void timerISR() {
static bool buzzerState = false;
static int intervalCounter = 0;
// کنترل بوق
if (beepRequested && beepCount > 0) {
if (intervalCounter == 0) {
buzzerState = !buzzerState;
digitalWrite(buzzerPin, buzzerState);
if (!buzzerState && --beepCount == 0)
beepRequested = false;
intervalCounter = 2;
} else intervalCounter--;
}
// کنترل زمان نمایش درصد باتری
batteryCheckCounter++;
if (batteryCheckCounter >= 600) { // 600 بار * 100ms = 60 ثانیه
batteryCheckCounter = 0;
batteryCheckFlag = true;
}
}
// --- آژیر ---
void activateAlarm() {
if (!silentMode) {
buzzerActive = true;
digitalWrite(buzzerPin, HIGH);
}
}
// --- LED وضعیت ---
void updateStatusLEDs() {
digitalWrite(ledArmedPin, systemArmed && !silentMode);
digitalWrite(ledSilentPin, systemArmed && silentMode);
digitalWrite(ledDisarmedPin, !systemArmed);
for (int i = 0; i < NUM_SENSORS; i++)
digitalWrite(ledSensorPins[i], sensorLatched[i]);
}
void resetSensorLEDs() {
for (int i = 0; i < NUM_SENSORS; i++) {
sensorLatched[i] = false;
digitalWrite(ledSensorPins[i], LOW);
}
}
// --- کنترل ریموت ---
void handleRemoteCommand(int key) {
switch (key) {
case 0: if (!systemArmed || silentMode) {
systemArmed = true; silentMode = false; sensorTriggered = false;
resetSensorLEDs(); saveSystemState(); requestBeep(1);
Serial.println("✅ دزدگیر فعال شد (عادی)");
} break;
case 1: if (systemArmed) {
systemArmed = false; silentMode = false;
buzzerActive = false; sensorTriggered = false;
digitalWrite(buzzerPin, LOW); saveSystemState(); requestBeep(1);
Serial.println("❌ دزدگیر غیرفعال شد");
} break;
case 2: if (!systemArmed || !silentMode) {
systemArmed = true; silentMode = true; sensorTriggered = false;
resetSensorLEDs(); saveSystemState(); requestBeep(1);
Serial.println("🔇 دزدگیر فعال شد (سایلنت)");
} break;
case 3: if (buzzerActive) {
buzzerActive = false; digitalWrite(buzzerPin, LOW); requestBeep(1);
Serial.println("🛑 آژیر دستی قطع شد");
} break;
}
updateStatusLEDs();
}
// --- کنترل باتری ---
void checkBattery() {
int rawBattery = analogRead(batteryAnalogPin);
float voltageBattery = (rawBattery * 5.0 / 1023.0) * batteryDividerRatio;
if (!isCharging && voltageBattery < batteryStartCharge) {
digitalWrite(batteryRelayPin, HIGH);
isCharging = true;
Serial.println("🔋 شارژ باتری فعال شد");
}
else if (isCharging && voltageBattery >= batteryStopCharge) {
digitalWrite(batteryRelayPin, LOW);
isCharging = false;
Serial.println("✅ شارژ باتری قطع شد");
}
}
// --- نمایش درصد باتری ---
void showBatteryPercentage() {
int rawBattery = analogRead(batteryAnalogPin);
float voltageBattery = (rawBattery * 5.0 / 1023.0) * batteryDividerRatio;
float percentage = ((voltageBattery - 11.0) / (12.6 - 11.0)) * 100.0;
if (percentage > 100) percentage = 100;
if (percentage < 0) percentage = 0;
Serial.print("🔋 درصد شارژ باتری: ");
Serial.print(percentage, 1);
Serial.println(" %");
}
// --- setup ---
void setup() {
Serial.begin(9600);
Serial.println("🛡️ دزدگیر راهاندازی شد");
for (int i = 0; i < NUM_SENSORS; i++) {
pinMode(sensorPins[i], INPUT);
pinMode(ledSensorPins[i], OUTPUT);
}
for (int i = 0; i < NUM_REMOTE_KEYS; i++) pinMode(remotePins[i], INPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(ledArmedPin, OUTPUT);
pinMode(ledDisarmedPin, OUTPUT);
pinMode(ledSilentPin, OUTPUT);
pinMode(batteryRelayPin, OUTPUT);
digitalWrite(batteryRelayPin, LOW);
Timer1.initialize(100000); // هر 100 میلی ثانیه وقفه
Timer1.attachInterrupt(timerISR);
loadSystemState();
updateStatusLEDs();
}
// --- loop ---
void loop() {
for (int i = 0; i < NUM_REMOTE_KEYS; i++) {
if (digitalRead(remotePins[i]) == HIGH && !remoteLock[i]) {
handleRemoteCommand(i);
remoteLock[i] = true;
} else if (digitalRead(remotePins[i]) == LOW) {
remoteLock[i] = false;
}
}
if (systemArmed) {
for (int i = 0; i < NUM_SENSORS; i++) {
if (digitalRead(sensorPins[i]) == HIGH) {
sensorTriggered = true;
lastMotionTime = millis();
activateAlarm();
if (!sensorLatched[i]) {
sensorLatched[i] = true;
Serial.print("🚨 تحریک از سنسور ");
Serial.println(i + 1);
updateStatusLEDs();
}
}
}
}
if (buzzerActive && millis() - lastMotionTime > alarmDuration) {
buzzerActive = false;
digitalWrite(buzzerPin, LOW);
Serial.println("🔕 آژیر خودکار قطع شد");
}
checkBattery();
if (batteryCheckFlag) {
batteryCheckFlag = false;
showBatteryPercentage();
}
}