#include <Arduino_FreeRTOS.h>
#include <semphr.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Pins
#define PIR_SENSOR_1 2
#define PIR_SENSOR_2 3
#define PIR_SENSOR_3 4
#define BUZZER_PIN 5
// Remote control buttons
#define ACTIVE_BUTTON 6
#define INACTIVE_BUTTON 7
#define SILENT_BUTTON 8
// System states
enum SystemState {
ACTIVE,
INACTIVE,
SILENT_MODE
};
volatile SystemState systemState = INACTIVE; // Default state: INACTIVE
// Semaphore
SemaphoreHandle_t buzzerSemaphore;
SemaphoreHandle_t lcdSemaphore;
// LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Function prototypes
void pirSensorTask(void *pvParameters);
void buzzerTask(void *pvParameters);
void remoteControlTask(void *pvParameters);
void updateLCD(const char* line1, const char* line2, const char* line3, const char* line4);
void setup() {
Serial.begin(9600);
pinMode(PIR_SENSOR_1, INPUT);
pinMode(PIR_SENSOR_2, INPUT);
pinMode(PIR_SENSOR_3, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(ACTIVE_BUTTON, INPUT);
pinMode(INACTIVE_BUTTON, INPUT);
pinMode(SILENT_BUTTON, INPUT);
// Initialize LCD
lcd.begin(20, 4); // 20 columns, 4 rows
lcd.backlight();
// Initialize semaphores
buzzerSemaphore = xSemaphoreCreateBinary();
lcdSemaphore = xSemaphoreCreateMutex();
// Create tasks
xTaskCreate(pirSensorTask, "PIR Sensor Task", 128, NULL, 2, NULL);
xTaskCreate(buzzerTask, "Buzzer Task", 128, NULL, 1, NULL);
xTaskCreate(remoteControlTask, "Remote Control Task", 128, NULL, 3, NULL);
// Initial LCD message
updateLCD("System : Inactive", "", "", "");
}
void loop() {
// Empty: FreeRTOS handles tasks.
}
void updateLCD(const char* line1, const char* line2, const char* line3, const char* line4) {
if (xSemaphoreTake(lcdSemaphore, (TickType_t)10) == pdTRUE) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(line1);
lcd.setCursor(0, 1);
lcd.print(line2);
lcd.setCursor(0, 2);
lcd.print(line3);
lcd.setCursor(0, 3);
lcd.print(line4);
xSemaphoreGive(lcdSemaphore);
}
}
void pirSensorTask(void *pvParameters) {
const int sensors[] = {PIR_SENSOR_1, PIR_SENSOR_2, PIR_SENSOR_3}; // آرایه سنسورها
const char* sensorNames[] = {"Motion : Sensor 1","Motion : Sensor 2 ", "Motion: Sensor 3"};
while (true) {
if (systemState == ACTIVE || systemState == SILENT_MODE) {
for (int i = 0; i < 3; i++) { // بررسی تمام سنسورها
if (digitalRead(sensors[i]) == HIGH) {
// نمایش پیام تشخیص حرکت روی سریال و LCD
Serial.println(sensorNames[i]);
if (systemState == ACTIVE) {
// در حالت ACTIVE، بیزر فعال شود
xSemaphoreGive(buzzerSemaphore);
updateLCD("System : Aactive", sensorNames[i], "", "");
}
if (systemState == SILENT_MODE) {
// در حالت SILENT، فقط پیام چاپ شود
updateLCD("System : Silent Mode", sensorNames[i], "", "");
}
}
}
}
vTaskDelay(100 / portTICK_PERIOD_MS); // بررسی هر 100 میلیثانیه
}
}
void buzzerTask(void *pvParameters) {
const uint32_t BUZZER_DURATION_MS = 30000; // مدت زمان بیزر (30 ثانیه)
while (true) {
// منتظر بمانید تا Semaphore فعال شود
if (xSemaphoreTake(buzzerSemaphore, portMAX_DELAY) == pdTRUE) {
if (systemState == ACTIVE) {
Serial.println("Buzzer activated.");
// نمایش وضعیت روی LCD
updateLCD("System : Active", "Buzzer activated!", "", "");
// فعال کردن بیزر
digitalWrite(BUZZER_PIN, HIGH);
vTaskDelay(BUZZER_DURATION_MS / portTICK_PERIOD_MS);
// خاموش کردن بیزر
digitalWrite(BUZZER_PIN, LOW);
// نمایش وضعیت پس از خاموش کردن بیزر
updateLCD("System : Active", "Buzzer deactivated", "", "");
}
}
}
}
void remoteControlTask(void *pvParameters) {
while (true) {
if (digitalRead(ACTIVE_BUTTON) == HIGH) {
systemState = ACTIVE;
Serial.println("System is now ACTIVE");
updateLCD("System : Active", "", "", "");
} else if (digitalRead(INACTIVE_BUTTON) == HIGH) {
systemState = INACTIVE;
Serial.println("System is now INACTIVE");
updateLCD("System : Inactive", "", "", "");
} else if (digitalRead(SILENT_BUTTON) == HIGH) {
systemState = SILENT_MODE;
Serial.println("System is now in SILENT MODE");
updateLCD("System :Silent Mode", "", "", "");
}
vTaskDelay(200 / portTICK_PERIOD_MS); // Check every 200ms
}
}