#include <Wire.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
// تنظیم پایههای LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
// پایههای کیپد
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {10, 11, 12, A0};
byte colPins[COLS] = {A1, A2, A3, A4};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// پایههای سنسورها و دزدگیر
#define PIR_PIN_1 2
#define PIR_PIN_2 3
#define PIR_PIN_3 4
#define SIM800_TX 1
#define SIM800_RX 0
#define BUZZER_PIN 5
#define ACTIVE_PIN 6
#define INACTIVE_PIN 7
#define SILENT_MODE_PIN 8
#define STOP_ALARM_PIN 9
#define LEDActive 13
enum SystemState {
INACTIVE,
ACTIVE,
SILENT_MODE
};
SystemState systemState = INACTIVE;
bool isAlarmActive = false;
bool isCalling = false;
bool callAnswered = false;
bool alarmTriggered = false;
unsigned long alarmStartTime = 0;
const unsigned long alarmDuration = 10000;
unsigned long backlightStartTime = 0;
bool isBacklightOn = false;
String systemPassword = "";
bool firstRun = true;
String inputPassword = "";
unsigned long stateChangeTime = 0;
unsigned long messageStartMillis = 0; // زمان شروع نمایش پیام
bool isDisplayingMessage = false; // وضعیت نمایش پیام
bool showMessage = false;
bool isBuzzing = false; // برای مشخص کردن اینکه بازر فعال است یا نه
int beepCount = 0; // تعداد بوقها
unsigned long previousMillis = 0; // زمان قبلی برای بوق زدن
const unsigned long beepInterval = 200; // فاصله زمانی بوقها (200 میلیثانیه)
unsigned long messageStartTime = 0;
SoftwareSerial sim800(SIM800_TX, SIM800_RX);
void setup() {
pinMode(PIR_PIN_1, INPUT);
pinMode(PIR_PIN_2, INPUT);
pinMode(PIR_PIN_3, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(ACTIVE_PIN, INPUT);
pinMode(INACTIVE_PIN, INPUT);
pinMode(SILENT_MODE_PIN, INPUT);
pinMode(STOP_ALARM_PIN, INPUT);
pinMode(LEDActive, OUTPUT);
sim800.begin(9600);
Serial.begin(9600);
Serial.println("در حال راهاندازی...");
sim800.println("ATE0");
lcd.begin(16, 2);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("System ready");
stateChangeTime = millis();
}
void loop() {
unsigned long currentMillis = millis();
char key = keypad.getKey(); // خواندن کلید فشرده شده
if (firstRun) {
getPasswordSetup(key);
} else {
checkPassword(key);
}
if (sim800.available()) {
String sms = sim800.readString();
if (sms.indexOf("ACTIVE") >= 0) {
setActive();
} else if (sms.indexOf("INACTIVE") >= 0) {
setInactive();
} else if (sms.indexOf("SILENT") >= 0) {
setSilentMode();
}
}
if (key) {
if (key == 'A')
setActive();
else if (key == 'B')
setInactive();
else if (key == 'C')
setSilentMode();
else if (key == 'D')
setStopAlarm();
}
if (digitalRead(ACTIVE_PIN) == HIGH)
setActive();
else if (digitalRead(INACTIVE_PIN) == HIGH)
setInactive();
else if (digitalRead(SILENT_MODE_PIN) == HIGH)
setSilentMode();
else if (digitalRead(STOP_ALARM_PIN) == HIGH )
setStopAlarm();
if ((systemState == ACTIVE || systemState == SILENT_MODE) &&
(digitalRead(PIR_PIN_1) == HIGH || digitalRead(PIR_PIN_2) == HIGH || digitalRead(PIR_PIN_3) == HIGH)) {
if (!alarmTriggered) {
activateAlarm();
alarmStartTime = currentMillis;
if (systemState == ACTIVE) digitalWrite(BUZZER_PIN, HIGH);
alarmTriggered = true;
}
}
if (isAlarmActive && (currentMillis - alarmStartTime >= alarmDuration)) {
digitalWrite(BUZZER_PIN, LOW);
isAlarmActive = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Alarm off");
Serial.println("الارم به صورت خودکار متوقف شد");
stateChangeTime = currentMillis;
showSystemState();
}
if (isBacklightOn && (currentMillis - backlightStartTime >= 5000)) {
lcd.noBacklight();
isBacklightOn = false;
}
// اجرای بوق زدن با استفاده از millis
if (isBuzzing) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= beepInterval) {
previousMillis = currentMillis;
// روشن و خاموش کردن بازر
digitalWrite(BUZZER_PIN, !digitalRead(BUZZER_PIN));
// هر بار که بازر خاموش میشود، تعداد بوقها را کم میکنیم
if (digitalRead(BUZZER_PIN) == LOW) {
beepCount--;
// اگر تعداد بوقها به صفر رسید، بوق زدن را متوقف کنید
if (beepCount <= 0) {
isBuzzing = false;
digitalWrite(BUZZER_PIN, LOW); // مطمئن شوید که بازر خاموش میشود
}
}
}
}
LEDARM();
checkCallStatus();
}
void setActive() {
systemState = ACTIVE;
setBacklight();
Serial.println("سيستم فعال شده و آماده است");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("System Active");
isAlarmActive = false;
alarmTriggered = false;
setStopAlarm();
stateChangeTime = millis();
startBuzzing(2); // 2 بوق برای کلید اول
}
void setInactive() {
systemState = INACTIVE;
setBacklight();
Serial.println("سيستم غیرفعال است");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("System Inactive");
setStopAlarm();
isAlarmActive = false;
alarmTriggered = false;
showSystemState();
messageStartMillis = millis(); // ثبت زمان شروع
startBuzzing(2); // 2 بوق برای کلید اول
}
void setSilentMode() {
systemState = SILENT_MODE;
setBacklight();
Serial.println("سيستم در حالت سایلنت");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("System Silent");
isAlarmActive = false;
setStopAlarm();
stateChangeTime = millis();
messageStartMillis = millis(); // ثبت زمان شروع
showSystemState();
startBuzzing(1); // 2 بوق برای کلید اول
}
void setStopAlarm() {
if (isAlarmActive == true) {
digitalWrite(BUZZER_PIN, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Stop Alarm");
Serial.println("الارم متوقف شد");
isAlarmActive = false;
}
if ( alarmTriggered == true ){
sim800.println("ATH");
endCall();
alarmTriggered = false;
}
stateChangeTime = millis();
messageStartMillis = millis(); // ثبت زمان شروع
isDisplayingMessage = true; // اگر پیام در حال نمایش نیست، شروع نمایش پیام
showSystemState();
startBuzzing(2); // 2 بوق برای کلید اول
}
void activateAlarm() {
lcd.clear();
if (digitalRead(PIR_PIN_1) == HIGH) {
lcd.setCursor(0, 0);
lcd.print("Motion Zone 1");
} else if (digitalRead(PIR_PIN_2) == HIGH) {
lcd.setCursor(0, 0);
lcd.print("Motion Zone 2");
} else if (digitalRead(PIR_PIN_3) == HIGH) {
lcd.setCursor(0, 0);
lcd.print("Motion Zone 3");
}
isAlarmActive = true;
makeCall();
}
void makeCall() {
if (!isCalling) {
sim800.println("ATD+98xxxxxxxxxx;");
lcd.setCursor(0, 1);
lcd.print("Dialing...");
isCalling = true;
}
}
void endCall() {
if (isCalling) {
sim800.println("ATH");
lcd.setCursor(0, 1);
lcd.print("Call ended");
Serial.println("تماس متوفق شده");
isCalling = false;
stateChangeTime = millis();
showSystemState();
}
}
void showSystemState() {
if (isDisplayingMessage && (millis() - messageStartMillis >= 2000)) { // بررسی گذشتن 2000 میلیثانیه از شروع نمایش پیام
switch (systemState) { // نمایش وضعیت سیستم
case ACTIVE:
lcd.setCursor(0, 0);
lcd.print("System Active");
break;
case INACTIVE:
lcd.setCursor(0, 0);
lcd.print("System Inactive");
break;
case SILENT_MODE:
lcd.setCursor(0, 0);
lcd.print("System Silent");
break;
}
}
isDisplayingMessage = false; // ریست وضعیت نمایش
}
void setBacklight() {
lcd.backlight();
backlightStartTime = millis();
isBacklightOn = true;
}
void LEDARM() {
digitalWrite(LEDActive, (systemState == ACTIVE || systemState == SILENT_MODE) ? HIGH : LOW);
}
void checkCallStatus() {
if (sim800.available()) {
String response = sim800.readString();
if (response.indexOf("NO CARRIER") != -1 || response.indexOf("BUSY") != -1 || response.indexOf("NO ANSWER") != -1) {
isCalling = false;
}
if (response.indexOf("ANSWER") != -1) {
callAnswered = true;
isCalling = false;
}
}
if (!callAnswered && !isCalling && alarmTriggered) {
makeCall();
}
}
void getPasswordSetup(char key) {
if (key != 'A' && key != 'B' && key != 'C' && key != 'D') {
if (key == '#') {
systemPassword = inputPassword;
inputPassword = "";
firstRun = false;
lcd.clear();
lcd.print("Password Set!");
Serial.println("لطفا پسور خود را ست کنید ");
messageStartTime = millis();
showMessage = true;
} else {
inputPassword += key;
lcd.setCursor(inputPassword.length() - 1, 1);
lcd.print("*");
}
}
if (showMessage && millis() - messageStartTime >= 2000) {
lcd.clear();
lcd.print("System Ready");
showMessage = false;
}
}
void checkPassword(char key) {
if (key != 'A' && key != 'B' && key != 'C' && key != 'D') {
if (key == '#') {
if (inputPassword == systemPassword) {
lcd.clear();
lcd.print("Access Granted");
messageStartTime = millis();
showMessage = true;
inputPassword = "";
} else {
lcd.clear();
lcd.print("Access Denied");
messageStartTime = millis();
showMessage = true;
inputPassword = "";
}
} else {
inputPassword += key;
lcd.setCursor(inputPassword.length() - 1, 1);
lcd.print("*");
}
}
if (showMessage && millis() - messageStartTime >= 2000) {
lcd.clear();
lcd.print("Enter Password:");
showMessage = false;
}
}
// تابعی برای شروع بوق زدن با تعداد مشخص
void startBuzzing(int count) {
if (!isBuzzing) { // تنها وقتی شروع به بوق زدن کند که قبلا فعال نشده باشد
beepCount = count * 1; // هر بوق شامل یک روشن و یک خاموش است
isBuzzing = true;
previousMillis = millis();
}
}