#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;
const unsigned long backlightDuration = 5000;
String systemPassword = ""; // پسورد سیستم ذخیره میشود
bool firstRun = true; // اولین بار بودن اجرا
String inputPassword = ""; // ذخیره پسورد ورودی از کیپد
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"); // خاموش کردن Echo برای جلوگیری از مشکلات در پاسخدهی
delay(1000);
lcd.begin(16, 2);
lcd.backlight(); // روشن کردن بکلایت
lcd.setCursor(0, 0);
lcd.print("System ready");
delay(1000);
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Enter Password:");
}
void loop() {
if (firstRun) { // اگر اولین بار اجرا شده است
getPasswordSetup(); // تابع تنظیم پسورد
} else {
checkPassword(); // بررسی و تایید پسورد برای دفعات بعدی
}
// کنترل سیستم از طریق پیامک
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();
}
}
// چک کردن وضعیت دکمههای کیپد
char key = keypad.getKey(); // خواندن کلید فشرده شده
if (key) {
if (key == 'A') {
setActive();
} else if (key == 'B') {
setInactive();
} else if (key == 'c') {
setSilentMode();
} else if ((key == 'D') && (alarmTriggered || isCalling)) {
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 && (alarmTriggered || isCalling)) {
setStopAlarm();
}
// بررسی سنسورهای حرکت و آلارم در حالت ACTIVE و SILENT_MODE
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 = millis();
if (systemState == ACTIVE) {
digitalWrite(BUZZER_PIN, HIGH);
}
alarmTriggered = true;
}
}
// بررسی زمان آلارم برای خاموش شدن خودکار
if (isAlarmActive && (millis() - alarmStartTime >= alarmDuration)) {
digitalWrite(BUZZER_PIN, LOW);
isAlarmActive = false;
alarmTriggered = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Alarm off");
delay(1000);
showSystemState();
}
// بررسی زمان روشن ماندن بکلایت
if (isBacklightOn && millis() - backlightStartTime >= backlightDuration) {
lcd.noBacklight();
isBacklightOn = false;
}
LEDARM();
checkCallStatus();
}
// تابع فعال کردن سیستم
void setActive() {
systemState = ACTIVE;
setBacklight();
Serial.println("سيستم فعال شده و آماده است");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("System Active");
indicateState(); // پخش صدا برای حالت ACTIVE
isAlarmActive = false;
alarmTriggered = false;
digitalWrite(BUZZER_PIN, LOW);
if (isCalling) endCall();
delay(500);
}
// تابع غیرفعال کردن سیستم
void setInactive() {
systemState = INACTIVE;
setBacklight();
Serial.println("سيستم غیرفعال است");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("System Inactive");
indicateState(); // پخش صدا برای حالت ACTIVE
digitalWrite(BUZZER_PIN, LOW);
isAlarmActive = false;
alarmTriggered = false;
if (isCalling) endCall();
showSystemState();
}
// تابع فعال کردن حالت سایلنت
void setSilentMode() {
systemState = SILENT_MODE;
setBacklight();
Serial.println("سيستم در حالت سایلنت");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("System Silent");
indicateState(); // پخش صدا برای حالت ACTIVE
isAlarmActive = false;
digitalWrite(BUZZER_PIN, LOW);
if (isCalling) endCall();
delay(500);
showSystemState();
}
// تابع متوقف کردن آلارم و تماس
void setStopAlarm() {
digitalWrite(BUZZER_PIN, LOW);
isAlarmActive = false;
alarmTriggered = false;
sim800.println("ATH");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Stop Alarm");
indicateState(); // پخش صدا برای حالت ACTIVE
if (isCalling) endCall();
Serial.println("الارم متوقف شد");
delay(1000);
showSystemState();
}
// تابع فعال کردن آلارم و تماس
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;");
delay(500);
lcd.setCursor(0, 1);
lcd.print("Dialing...");
isCalling = true;
}
}
// تابع پایان تماس
void endCall() {
if (isCalling) {
sim800.println("ATH");
delay(500);
lcd.setCursor(0, 1);
lcd.print("Call ended");
isCalling = false;
delay(1000);
showSystemState();
}
}
// نمایش وضعیت سیستم روی LCD
void showSystemState() {
lcd.clear();
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;
}
}
// کنترل روشنایی بکلایت
void setBacklight() {
lcd.backlight();
backlightStartTime = millis();
isBacklightOn = true;
}
// بررسی LED حالت اکتیو
void LEDARM() {
if (systemState == ACTIVE || systemState == SILENT_MODE) {
digitalWrite(LEDActive, HIGH);
} else {
digitalWrite(LEDActive, 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 indicateState() { // تعداد بوق بیزر برای نمایش حالت دستکاه
int beepCount = 0;
if (systemState == ACTIVE) {
beepCount = 1; // یک بوق برای ACTIVE
}
else if (systemState == INACTIVE) {
beepCount = 2; // دو بوق برای INACTIVE
}
else if (systemState == SILENT_MODE) {
beepCount = 3; // سه بوق برای SILENT_MODE
}
for (int i = 0; i < beepCount; i++) { // بیزر به تعداد beepCount بوق میزند
digitalWrite(BUZZER_PIN, HIGH);
delay(300); // طول بوق
digitalWrite(BUZZER_PIN, LOW);
delay(300); // فاصله بین بوقها
}
delay(300); // توقف کوتاه پس از پخش صدا
// تابع تنظیم پسورد برای اولین بار
}
void getPasswordSetup() {
char key = keypad.getKey(); // خواندن کلید فشرده شده
if (key) {
if (key == '#') { // کلید '#' را برای تنظیم پسورد استفاده میکنیم
systemPassword = inputPassword; // پسورد وارد شده را ذخیره میکنیم
inputPassword = ""; // پاک کردن پسورد وارد شده
firstRun = false; // تغییر حالت اولین بار بودن به false
lcd.clear();
lcd.print("Password Set!");
delay(2000);
lcd.clear();
lcd.print("System Ready");
} else {
inputPassword += key; // اضافه کردن کلید فشرده شده به پسورد ورودی
lcd.setCursor(inputPassword.length() - 1, 1);
lcd.print("*"); // نمایش کاراکترهای پسورد به صورت مخفی
}
}
}
// تابع بررسی پسورد در دفعات بعدی
void checkPassword() {
char key = keypad.getKey();
if (key) {
if (key == '#') { // کلید '#' را برای تایید پسورد استفاده میکنیم
if (inputPassword == systemPassword) {
lcd.clear();
lcd.print("Access Granted");
delay(2000);
lcd.clear();
lcd.print("System Ready");
inputPassword = ""; // ریست پسورد ورودی
} else {
lcd.clear();
lcd.print("Access Denied");
delay(2000);
lcd.clear();
lcd.print("Enter Password:");
inputPassword = ""; // ریست پسورد ورودی
}
} else {
inputPassword += key;
lcd.setCursor(inputPassword.length() - 1, 1);
lcd.print("*");
}
}
}