#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
// پایههای LCD
#define LCD_RS 10
#define LCD_EN 11
#define LCD_D4 12
#define LCD_D5 14
#define LCD_D6 15
#define LCD_D7 16
#define LCD_BACKLIGHT 17
// تنظیم پایههای LCD
LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
// پایههای سنسورها و دزدگیر
#define PIR_PIN_1 2 // پایه سنسور PIR اول
#define PIR_PIN_2 3 // پایه سنسور PIR دوم
#define PIR_PIN_3 4 // پایه سنسور PIR سوم
#define SIM800_TX 1 // پایه TX ماژول سیم کارت
#define SIM800_RX 0 // پایه RX ماژول سیم کارت
#define BUZZER_PIN 5 // پایه زنگ یا بیزر
#define ACTIVE_PIN 6 // پایه برای فعال کردن حالت ACTIVE
#define INACTIVE_PIN 7 // پایه برای فعال کردن حالت INACTIVE
#define SILENT_MODE_PIN 8 // پایه برای فعال کردن حالت SILENT_MODE
#define STOP_ALARM_PIN 9 // پایه برای متوقف کردن زنگ هشدار
#define LEDActive 13 // پایه LED برای نشان دادن فعال بودن حالت اکتیو
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; // مدت زمان آلارم (10 ثانیه)
unsigned long backlightStartTime = 0; // زمان شروع روشن شدن بکلایت
bool isBacklightOn = false; // وضعیت روشن بودن بکلایت
const unsigned long backlightDuration = 5000; // مدت زمان روشن ماندن بکلایت (5 ثانیه)
SoftwareSerial sim800(SIM800_TX, SIM800_RX); // ارتباط سریال با ماژول SIM800
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(LCD_BACKLIGHT, OUTPUT);
pinMode(LEDActive, OUTPUT);
// تنظیمات سریال برای ارتباط با ماژول SIM800
sim800.begin(9600);
Serial.begin(9600);
Serial.println("در حال راهاندازی...");
sim800.println("ATE0"); // خاموش کردن Echo برای جلوگیری از مشکلات در پاسخدهی
delay(1000);
// تنظیم LCD و نمایش پیام اولیه
lcd.begin(16, 2);
Serial.println("سيستم آماده است...");
lcd.setCursor(0, 0);
lcd.print("System ready");
}
void loop() {
// کنترل سیستم از طریق پیامک
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 (digitalRead(ACTIVE_PIN) == HIGH) {
setBacklight(); // روشن کردن بکلایت
setActive(); // فعال کردن سیستم
indicateState();
} else if (digitalRead(INACTIVE_PIN) == HIGH) {
setBacklight(); // روشن کردن بکلایت
setInactive(); // غیرفعال کردن سیستم
indicateState();
} else if (digitalRead(SILENT_MODE_PIN) == HIGH) {
setBacklight(); // روشن کردن بکلایت
setSilentMode(); // فعال کردن حالت سایلنت
indicateState();
} else if (digitalRead(STOP_ALARM_PIN) == HIGH && ( alarmTriggered || isCalling )) {
setBacklight(); // روشن کردن بکلایت
setStopAlarm(); // متوقف کردن آلارم
indicateState();
}
// بررسی سنسورهای حرکت
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)) {
lcd.clear();
digitalWrite(BUZZER_PIN, LOW);
isAlarmActive = false;
alarmTriggered = false; // ریست کردن وضعیت آلارم
Serial.println("آلارم به طور خودکار خاموش شد");
lcd.print("Alarm off");
delay(1000);
showSystemState(); // نمایش وضعیت سیستم
}
// بررسی زمان روشن ماندن بکلایت
if (isBacklightOn && millis() - backlightStartTime >= backlightDuration) {
digitalWrite(LCD_BACKLIGHT, LOW); // خاموش کردن بکلایت
isBacklightOn = false;
}
LEDARM(); // چک کردن وضعیت LED برای حالت اکتیو
checkCallStatus(); // بررسی وضعیت تماس تلفنی
}
// تابع فعال کردن سیستم
void setActive() {
systemState = ACTIVE;
Serial.println("سيستم فعال شده و آماده است");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("system Active");
isAlarmActive = false;
alarmTriggered = false; // ریست کردن وضعیت آلارم
if ( isCalling == true ) {
endCall();
}
delay(500);
}
// تابع غیرفعال کردن سیستم
void setInactive() {
systemState = INACTIVE;
Serial.println("سيستم غیرفعال است");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("System inactive");
digitalWrite(BUZZER_PIN, LOW); // خاموش کردن بیزر
isAlarmActive = false;
alarmTriggered = false; // ریست کردن وضعیت آلارم
if ( isCalling == true ) {
endCall();
}
showSystemState();
}
// تابع فعال کردن حالت سایلنت
void setSilentMode() {
systemState = SILENT_MODE;
Serial.println("سيستم در حالت سایلنت");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("system Silent");
isAlarmActive = false;
if ( isCalling == true ) {
endCall();
} delay(500);
}
// تابع متوقف کردن آلارم و تماس
void setStopAlarm() {
digitalWrite(BUZZER_PIN, LOW); // خاموش کردن بیزر
isAlarmActive = false;
alarmTriggered = false;
sim800.println("ATH"); // قطع تماس
lcd.clear();
lcd.setCursor(0, 0);
lcd.println("Stop Alarm");
if ( isCalling ) {
endCall();
}
Serial.println("الارم متوقف شد");
delay(1000);
showSystemState(); // نمایش وضعیت سیستم
}
// تابع برای برقراری تماس تلفنی
void makeCall() {
if (!isCalling) {
sim800.println("ATD+98xxxxxxxxxx;"); // شماره تماس
delay(500);
Serial.println("در حال برقراری تماس...");
lcd.setCursor(0, 1);
lcd.print("Dialing...");
isCalling = true;
}
}
// تابع برای قطع تماس
void endCall() {
if (isCalling) {
sim800.println("ATH"); // قطع تماس
delay(500);
Serial.println("تماس قطع شد");
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");
if ( isCalling ) { // برسی پرین وضعیت ک الینک تا وقت این که این وضعیت پایان یابد
lcd.setCursor(0, 1);
lcd.println("Dialing...");
}
break;
case INACTIVE:
lcd.setCursor(0, 0);
lcd.print("System Inactive");
if ( isCalling ) { // برسی پرین وضعیت ک الینک تا وقت این که این وضعیت پایان یابد
lcd.setCursor(0, 1);
lcd.println("Dialing...");
}
break;
case SILENT_MODE:
lcd.setCursor(0, 0);
lcd.print("system Silent");
if ( isCalling ) { // برسی پرین وضعیت ک الینک تا وقت این که این وضعیت پایان یابد
lcd.setCursor(0, 1);
lcd.println("Dialing...");
}
break;
}
}
// تابع فعال کردن آلارم و برقراری تماس در صورت تشخیص حرکت
void activateAlarm() {
if (digitalRead(PIR_PIN_1) == HIGH ) {
Serial.println("حرکت شناسایی شد زون 1");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Motion zone 1");
if ( isCalling == true ) { // برسی پرین وضعیت ک الینک تا وقت این که این وضعیت پایان یابد
lcd.setCursor(0, 1);
lcd.println("Dialing...");
}
}
if (digitalRead(PIR_PIN_2) == HIGH ) {
Serial.println("حرکت شناسایی شد زون 2");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Motion zone 2");
if ( isCalling == true ) { // برسی پرین وضعیت ک الینک تا وقت این که این وضعیت پایان یابد
lcd.setCursor(0, 1);
lcd.println("Dialing...");
}
}
if (digitalRead(PIR_PIN_3) == HIGH ) {
Serial.println("حرکت شناسایی شد زون 3");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Motion zone 3");
if ( isCalling == true ) { // برسی پرین وضعیت ک الینک تا وقت این که این وضعیت پایان یابد
lcd.setCursor(0, 1);
lcd.println("Dialing...");
}
}
isAlarmActive = true;
alarmTriggered = false; // ریست وضعیت دزدگیر
callAnswered = false; // ریست وضعیت تماس
makeCall(); // برقراری تماس
}
// تابع روشن کردن بکلایت
void setBacklight() {
digitalWrite(LCD_BACKLIGHT, HIGH); // روشن کردن بکلایت
backlightStartTime = millis(); // ذخیره زمان شروع روشنایی
isBacklightOn = true;
}
// تابع بررسی وضعیت LED برای حالت اکتیو
void LEDARM() {
// چک کردن وضعیت سیستم برای روشن کردن LED
if (systemState == ACTIVE || systemState == SILENT_MODE) {
digitalWrite(LEDActive, HIGH); // روشن کردن LED
} else {
digitalWrite(LEDActive, LOW); // خاموش کردن LED در حالت INACTIVE
}
}
// تابع بررسی وضعیت تماس
void checkCallStatus() {
if (sim800.available()) {
String response = sim800.readString();
// بررسی پاسخ "NO CARRIER" (یعنی تماس تمام شده بدون پاسخ)
if (response.indexOf("NO CARRIER") != -1) {
Serial.println("No answer. Trying again...");
isCalling = true; // تماس گرفته نشده، دوباره تماس میگیرد
}
// بررسی پاسخ "BUSY" (خط مشغول است)
if (response.indexOf("BUSY") != -1) {
Serial.println("Line is busy. Trying again...");
isCalling = true; // تماس مشغول بود، دوباره تماس میگیرد
}
// بررسی پاسخ "NO ANSWER" (پاسخ داده نشده)
if (response.indexOf("NO ANSWER") != -1) {
Serial.println("No answer. Trying again...");
isCalling = true; // تماس پاسخ داده نشده، دوباره تماس میگیرد
}
// بررسی پاسخ "ANSWER" (یعنی تماس پاسخ داده شده است)
if (response.indexOf("ANSWER") != -1) {
Serial.println("Call answered.");
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); // توقف کوتاه پس از پخش صدا
}