// Ссылка на проект https://wokwi.com/projects/450990296340385793
// После запуска симуляции перевести датчики дыма и t в нормальное положение, по умолчанию значения для "ПОЖАРА"
// Иницилизация шаговых двигателей
int vent = 23; // вентиляция
int avent = 47; // вытяжка
int nasos = 51; // насос
int Time_Step = 1;
// Иницилизация динамика
int buzzer = 12;
// Иницилизация дисплея
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Иницилизация кодового замка
#include <Keypad.h>
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'}
};
String password = "3221"; // Правильный пароль
String input = ""; // Введённая строка
// пины, к которым подключены R1..R4
byte rowPins[ROWS] = {14, 15, 16, 17};
// пины, к которым подключены C1..C4
byte colPins[COLS] = {18, 19, 22, 24};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Инициализация аварийного освещения
#include <Adafruit_NeoPixel.h>
#define NEOPIXEL_PIN 52
#define NUMPIXELS 16
Adafruit_NeoPixel pixels(NUMPIXELS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
// Инициализация двтчика температуры
#include "DHT.h"
#define DHTTPIN A0
#define DHTTPYPE DHT22
DHT dht(DHTTPIN, DHTTPYPE);
float temperature = 0.0; // Переменная для хранения температуры
// Инициализация светодиодов
int ledf = 27; // Пожар
int lede = 35; // Выход
int leda = 43; // Тревога
int ledw = 53; // "Вода"
// Инициализация сервоприводов
#include <Servo.h>
Servo lift; // Сервопривод лифта
unsigned long liftChangeTime = 0;
const unsigned long liftInterval = 5000; // 5 секунд
bool liftUp = true; // true = 180°, false = 0°
Servo lock; // Сервопривод замка
unsigned long lockOpenTime = 0;
const unsigned long lockDuration = 500; // 500 мс
bool lockOpen = false;
Servo automat; // Сервопривод автомата электропитания
int pinLift = 11;
int pinLock = 10;
int pinAutomat = 9;
// Инициализация датчика дыма
int gasPin = A1;
int gasValue = 0; // Переменная для хранения значения
// Инициализация датчика движения
int pir = 13;
// Инициализация "режимов"
int on = 8; // питание пинов
int p1 = 28; // 1 пожарная тревога
int p2 = 1; // 2 тревожная кнопка
int p3 = 2; // 3 сигнал - открыто окно
int p4 = 3; // 4 сигнал - открыта дверь
int p5 = 4; // 5 симуляция "разбита колба сплинкера"
int p6 = 5; // 6 перегрузка электросистемы
int p7 = 6; // 7 переключение на ночной режим
int p8 = 7; // 8 "сработал" сплинкер
// Функция управления шаговыми двигателями
void doStep(int pin, int delayTime) {
digitalWrite(pin, HIGH);
delay(delayTime);
digitalWrite(pin, LOW);
delay(delayTime);
}
// Функция режимов
int sw = 6;
void mode() {
if (digitalRead(p1) == HIGH) {
sw = 2; // пожар по кнопке
} else if (digitalRead(p2) == HIGH) {
sw = 5; // тревога по кнопке
} else if (digitalRead(p7) == HIGH && (digitalRead(pir) == HIGH || digitalRead(p3) == HIGH || digitalRead(p4) == HIGH)) {
sw = 4; // тревога по датчикам
} else if (digitalRead(p6) == HIGH) {
sw = 3; // пожара по перегрузу питающей сети
} else if (analogRead(gasPin) >300 || dht.readTemperature() >50) {
sw = 1; // пожар по датчикам
} else {
sw = 6; // норма день
}
}
void setup() {
sw = 6;
// Шаговые двигатели
pinMode(vent, OUTPUT);
pinMode(avent, OUTPUT);
pinMode(nasos, OUTPUT);
// Динамик
pinMode(buzzer, OUTPUT);
// Дисплей
lcd.init(); // инициализация
lcd.backlight(); // включить подсветку
lcd.setCursor(0, 0);
lcd.print("Fire System Ready");
// Аварийное освещение
pixels.begin();
for (int i = 0; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, pixels.Color(253, 224, 185));
}
pixels.show(); // Включаем
// Датчик температуры
dht.begin();
// Светодиоды
pinMode(ledf, OUTPUT);
pinMode(lede, OUTPUT);
digitalWrite(lede, HIGH);
pinMode(leda, OUTPUT);
pinMode(ledw, OUTPUT);
// Сервоприводы
lift.attach(pinLift);
lock.attach(pinLock);
automat.attach(pinAutomat);
lift.write(0); // Лифт — внизу
lock.write(0); // Замок — закрыто
automat.write(1); // Автомат — включен
// Датчик движения
pinMode(pir, INPUT);
// "Режимы"
pinMode(on, OUTPUT);
digitalWrite(on, HIGH);
pinMode(p1, INPUT);
pinMode(p2, INPUT);
pinMode(p3, INPUT);
pinMode(p4, INPUT);
pinMode(p5, INPUT);
pinMode(p6, INPUT);
pinMode(p7, INPUT);
pinMode(p8, INPUT);
}
void loop() {
char key = keypad.getKey();
unsigned long currentMillis = millis();
mode();
switch (sw) {
case 1: // Пожар по датчикам
digitalWrite(ledw, LOW);
noTone(buzzer);
digitalWrite(leda, LOW);
lcd.setCursor(0, 2);
lcd.print(" "); // Очищаем строку
doStep(avent, Time_Step);
automat.write(90); // отключение автомата
lift.write(180); // лифт вниз
lock.write(90); // открытие замка
lcd.setCursor(0, 2);
lcd.print(" "); // Очищаем строку
lcd.setCursor(0, 2);
lcd.print("FIRE!!!!");
digitalWrite(ledf, HIGH);
tone(buzzer, 1000);
lift.write(180); // отключение автомата
if (digitalRead(p8) == HIGH) {
digitalWrite(ledw, HIGH);
lcd.setCursor(0, 3);
lcd.print(" "); // Очищаем строку
lcd.setCursor(0, 3);
lcd.print("RAIN");
doStep(nasos, Time_Step);
}
break;
case 2: // Пожар по кнопке
noTone(buzzer);
lcd.setCursor(0, 3);
lcd.print(" "); // Очищаем строку
digitalWrite(ledw, LOW);
digitalWrite(leda, LOW);
lcd.setCursor(0, 2);
lcd.print(" "); // Очищаем строку
tone(buzzer, 1000);
if (key) {
if (key == '#') {
if (input == password) {
lock.write(90); // Открываем замок
lockOpen = true;
lockOpenTime = currentMillis;
}
input = ""; // Очищаем ввод
} else if (key == '*') {
input = ""; // Сброс ввода
} else {
input += key; // Добавляем символ к вводу
}
}
// Закрываем замок через 500 мс
if (lockOpen && (currentMillis - lockOpenTime >= lockDuration)) {
lock.write(0); // Закрываем замок
lockOpen = false;
}
doStep(avent, Time_Step);
automat.write(90); // отключение автомата
lift.write(180);
lcd.setCursor(0, 2);
lcd.print(" "); // Очищаем строку
lcd.setCursor(0, 2);
lcd.print("FIRE!!!!");
digitalWrite(ledf, HIGH);
break;
case 3: // Пожар из-за перегрузки
lcd.setCursor(0, 3);
lcd.print(" "); // Очищаем строку
digitalWrite(ledw, LOW);
digitalWrite(ledf, LOW);
noTone(buzzer);
digitalWrite(leda, LOW);
lcd.setCursor(0, 2);
lcd.print(" "); // Очищаем строку
if (key) {
if (key == '#') {
if (input == password) {
lock.write(90); // Открываем замок
lockOpen = true;
lockOpenTime = currentMillis;
}
input = ""; // Очищаем ввод
} else if (key == '*') {
input = ""; // Сброс ввода
} else {
input += key; // Добавляем символ к вводу
}
}
// Закрываем замок через 500 мс
if (lockOpen && (currentMillis - lockOpenTime >= lockDuration)) {
lock.write(0); // Закрываем замок
lockOpen = false;
}
// Меняем положение лифта каждые 5 секунд
if (currentMillis - liftChangeTime >= liftInterval) {
if (liftUp) {
lift.write(180); // Лифт вверх
} else {
lift.write(0); // Лифт вниз
}
liftUp = !liftUp; // Меняем направление
liftChangeTime = currentMillis;
}
doStep(vent, Time_Step);
automat.write(90); // отключение автомата
break;
case 4: // Иревога по датчикам (ночью)
lcd.setCursor(0, 3);
lcd.print(" "); // Очищаем строку
digitalWrite(ledw, LOW);
digitalWrite(ledf, LOW);
digitalWrite(leda, HIGH);
tone(buzzer, 500);
lcd.setCursor(0, 2);
lcd.print(" "); // Очищаем строку
lcd.setCursor(0, 2);
lcd.print("ALARM");
if (key) {
if (key == '#') {
if (input == password) {
lock.write(90); // Открываем замок
lockOpen = true;
lockOpenTime = currentMillis;
}
input = ""; // Очищаем ввод
} else if (key == '*') {
input = ""; // Сброс ввода
} else {
input += key; // Добавляем символ к вводу
}
}
// Закрываем замок через 500 мс
if (lockOpen && (currentMillis - lockOpenTime >= lockDuration)) {
lock.write(0); // Закрываем замок
lockOpen = false;
}
// Меняем положение лифта каждые 5 секунд
if (currentMillis - liftChangeTime >= liftInterval) {
if (liftUp) {
lift.write(180); // Лифт вверх
} else {
lift.write(0); // Лифт вниз
}
liftUp = !liftUp; // Меняем направление
liftChangeTime = currentMillis;
}
doStep(vent, Time_Step);
break;
case 5: // Тревога по кнопке
lcd.setCursor(0, 3);
lcd.print(" "); // Очищаем строку
digitalWrite(ledw, LOW);
digitalWrite(ledf, LOW);
noTone(buzzer);
digitalWrite(leda, HIGH);
tone(buzzer, 500);
lcd.setCursor(0, 2);
lcd.print(" "); // Очищаем строку
lcd.setCursor(0, 2);
lcd.print("ALARM");
if (key) {
if (key == '#') {
if (input == password) {
lock.write(90); // Открываем замок
lockOpen = true;
lockOpenTime = currentMillis;
}
input = ""; // Очищаем ввод
} else if (key == '*') {
input = ""; // Сброс ввода
} else {
input += key; // Добавляем символ к вводу
}
}
// Закрываем замок через 500 мс
if (lockOpen && (currentMillis - lockOpenTime >= lockDuration)) {
lock.write(0); // Закрываем замок
lockOpen = false;
}
// Меняем положение лифта каждые 5 секунд
if (currentMillis - liftChangeTime >= liftInterval) {
if (liftUp) {
lift.write(180); // Лифт вверх
} else {
lift.write(0); // Лифт вниз
}
liftUp = !liftUp; // Меняем направление
liftChangeTime = currentMillis;
}
doStep(vent, Time_Step);
break;
case 6: // Нормальный режим
lcd.setCursor(0, 3);
lcd.print(" "); // Очищаем строку
digitalWrite(ledw, LOW);
digitalWrite(ledf, LOW);
digitalWrite(leda, LOW);
lcd.setCursor(0, 2);
lcd.print(" "); // Очищаем строку
noTone(buzzer);
if (key) {
if (key == '#') {
if (input == password) {
lock.write(90); // Открываем замок
lockOpen = true;
lockOpenTime = currentMillis;
}
input = ""; // Очищаем ввод
} else if (key == '*') {
input = ""; // Сброс ввода
} else {
input += key; // Добавляем символ к вводу
}
}
// Закрываем замок через 500 мс
if (lockOpen && (currentMillis - lockOpenTime >= lockDuration)) {
lock.write(0); // Закрываем замок
lockOpen = false;
}
// Меняем положение лифта каждые 5 секунд
if (currentMillis - liftChangeTime >= liftInterval) {
if (liftUp) {
lift.write(180); // Лифт вверх
} else {
lift.write(0); // Лифт вниз
}
liftUp = !liftUp; // Меняем направление
liftChangeTime = currentMillis;
}
doStep(vent, Time_Step);
automat.write(0);
break;
}
}ПОЖАР
ВЫХОД
ТРЕВОГА
Сплинкер
1 - Пожарная тревога
2 - Тревожная кнопка
3 - Открыто окно
4 - Открыта дверь
5 - "Разбита колба сплинкера"
6 - "Перегрузка электросистемы"
7 - "День/Ночь"
8 - "Датчик протечки"
Аварийное освещение
Лифт
Дверной замок
Вытяжка
Вентиляция
Датчик температуры
Датчик дыма
Звуковая
сигнализация
Переключение положения
автомата
Датчик движения
"Насос системы сплинкеров"
Кодовый замок
Дисплей диспетчера