Здравствуйте!
Вот такая коробочка у меня получилась.
Для сборки понадобится:
Корпус от старого нерабочего роутера, или любая друга подходящая коробка.
GSM модуль SIM800L.
Активная Sim карта с положительным балансом.
Литий-ионный аккумулятор 3,7 вольта на 2000-3000 миллиампер.
Контроллер заряда аккумуляторов на 3,7 вольта USB-MINI.
Пожарный звуковой оповещатель.
NPN транзистор подходящий по мощности для пожарного оповещателя.
Датчики движения HC-SR501 и концевые выключатели (в сумме 5 штук).
Один маломощный светодиод для индикации.
4 сопротивления: 250, 1К, 2К и 2,4К .
Соединительные провода .
Плата Arduino UNO
Перед тем как приступить к сборке прибора, укажите свой номер в скетче, как показано в видео инструкции, и загрузите этот скетч на плату.
//Начало скетча
#include <SoftwareSerial.h>
const int rx_prog = 2; //программный rx для подключения SIM800L
const int tx_prog = 3; //программный tx для подключения SIM800L
SoftwareSerial SIM800(rx_prog, tx_prog); //программные RX, TX для связи с модулем SIM800L
const int led_2 = 9; //светодиод для индикации сигнализации
const int sensor_Pin4 = 4; //линия для подключения датчика
const int sensor_Pin5 = 5; //линия для подключения датчика
const int sensor_Pin6 = 6; //линия для подключения датчика
const int line_dor = 10; //линия для подключения датчика
const int line_windovs = 12; //линия для подключения датчика
const int speaker = 8; //подключение сирены
const int set_220 = 7; //контакт для определения наличия питания в сети
String phon = "+38095xxxxxxx"; //номер на который будет выполняться звонок
String phones = "+38095xxxxxxx, +48513xxxxxxx, +48610xxxxxxx"; //несколько номеров администраторов, для управления по СМС
String balance = "*111#"; //номер для проверки баланса Sim карты GSM сигнализации
void numbr_sms(){
SIM800.println("AT+CMGS=\"+38095xxxxxxx\""); //1 номер для получения СМС, вписывается в международном формате начиная с +
delay(3000);
}
long spiker_time = 20000; //(20 секунд)время работы сирены, после отключения датчиков
long ring_time = 20000; //(20 секунд)пауза между звонками при срабатывании сигнализации
int batery_limit = 50; //значение в процентах при котором отправится СМС о разряженной батареи (оптимально 20-60)
int val, send_mesag_state_Batery = 0, send_mesag_Balanse = 0, led_2_OFF, led_2_ON;
int hhh = 0, stat_line_dor = 0, stat_line_windovs = 0, stat_sensor_Pin4 = 0, stat_sensor_Pin5 = 0, stat_sensor_Pin6 = 0;
int ring = 0, ring_st = 1, ring_f = 0, send_mesag = 0, sms_st = 1, blinker = 1;
String signalingS = "", signaling = "", line_dorS = "", line_windovsS = "", sensorR_Pin4 = "", sensorR_Pin5 = "", sensorR_Pin6 = "";
int k=0, v=0, msgphone = 0, state_Batery = 100;
// Переменные для хранения точек отсчета, для таймеров
unsigned long timing10, timing11, timing12, timing13, timing14;
String _response = ""; // Переменная для хранения ответа модуля
long lastUpdate = millis(); // Время последнего обновления
long updatePeriod = 60000; // Проверять каждую минуту
String waitResponse() { // Функция ожидания ответа и возврата полученного результата
String _resp = ""; // Переменная для хранения результата
long _timeout = millis() + 10000; // Переменная для отслеживания тайм аута (10 секунд)
while (!SIM800.available() && millis() < _timeout) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил тайм аут, то...
if (SIM800.available()) { // Если есть, что считывать...
_resp = SIM800.readString(); // считываем и запоминаем
}else { // Если пришел тайм аут, то...
Serial.println("Timeout..."); // оповещаем об этом и...
}return _resp; // возвращаем результат. Пусто, если проблема
}
String sendATCommand(String cmd, bool waiting) {
String _resp = ""; // Переменная для хранения результата
Serial.println(cmd); // Дублируем команду в монитор порта
SIM800.println(cmd); // Отправляем команду модулю
if (waiting) { // Если необходимо дождаться ответа...
_resp = waitResponse(); // ... ждем, когда будет передан ответ
// Если Echo Mode выключен (ATE0), то эти 3 строки можно за комментировать
if (_resp.startsWith(cmd)) { // Убираем из ответа дублирующуюся команду
_resp = _resp.substring(_resp.indexOf("\r", cmd.length()) + 2);}
Serial.println(_resp); // Дублируем ответ в монитор порта
}return _resp; // Возвращаем результат. Пусто, если проблема
}
void parseSMS(String msg) { // Парсим SMS
String msgheader = "";
String msgbody = "";
String msgphone = "";
msg = msg.substring(msg.indexOf("+CMGR: ")); //удаляем АТ команду
msgheader = msg.substring(0, msg.indexOf("\r")); // выдергиваем телефон от начала до перехода на следующую строку
msgbody = msg.substring(msgheader.length() + 2); //сохраняем в строку msgbody
msgbody = msgbody.substring(0, msgbody.lastIndexOf("OK"));// выдергиваем текст SMS от номера до ОК
msgbody.trim(); // удаляем пробелы в начале и в конце
int firstIndex = msgheader.indexOf("\",\"") + 3;
int secondIndex = msgheader.indexOf("\",\"", firstIndex);
msgphone = msgheader.substring(firstIndex, secondIndex);
Serial.println("Phone: " + msgphone); // Выводим номер телефона
Serial.println("Message: " + msgbody); // Выводим текст SMS
if (msgphone.length() > 6 && phones.indexOf(msgphone) > -1) { // Если телефон в белом списке, то...
//<<<<<<<<<<<<<<<<<<< SMS команды >>>>>>>>>>>>>>>>>>>>>>
if(msgbody == "Ktr3"){ Serial.println("SMS = Ktr3"); delay(300); k=3;} //запрос SMS о состоянии сигнализации, и датчиков сигнализации
if(msgbody == "Sms0"){ Serial.println("SMS = Sms0"); delay(300); sms_st = 0;} //выключить отправку SMS при срабатывании сигнализации
if(msgbody == "Sms1"){ Serial.println("SMS = Sms1"); delay(300); sms_st = 1;} //включить отправку SMS при срабатывании сигнализации
if(msgbody == "Ring0"){Serial.println("SMS = Ring0");delay(300); ring_st = 0;} //выключить исходящий вызов при срабатывании сигнализации
if(msgbody == "Ring1"){Serial.println("SMS = Ring1");delay(300);ring_st = 1;ring = 0;} //включить исходящий вызов при срабатывании сигнализации
if(msgbody == "Sig0"){ Serial.println("SMS = Sig0"); delay(300);hhh = 0; } //выключить сигнализацию
if(msgbody == "Sig1"){ Serial.println("SMS = Sig1"); delay(300);hhh = 1; } //включить сигнализацию
if(msgbody == "Bal"){ Serial.println("SMS = Bal"); //проверка баланса SIM карты
SIM800.println("AT+CUSD=1,\"" + balance + "\"");}
}else {
Serial.println("Unknown phonenumber");
}}
void text_sms(){
SIM800.print("Set = "); SIM800.print(v); SIM800.println(" volt");delay(300);
if (state_Batery == 10){state_Batery = 100;}
SIM800.print("Battery status = "); SIM800.print(state_Batery); SIM800.println("%");delay(300);
SIM800.println(signaling);delay(300);
SIM800.println(signalingS);delay(300);
SIM800.println(line_dorS);delay(300);
SIM800.println(line_windovsS);delay(300);
SIM800.println(sensorR_Pin4);delay(300);
SIM800.println(sensorR_Pin5);delay(300);
SIM800.println(sensorR_Pin6);delay(300);
SIM800.print("Ring = "); delay(300); SIM800.println(ring_st); delay(300);
SIM800.print("SMS = "); delay(300); SIM800.println(sms_st);
}
void go_sms(){
delay(300);
SIM800.print((char)26);//команда для отправки SMS
delay(300);
}
void setup() { //>>>>>>>>>>>>>>>>> SETUP <<<<<<<<<<<<<<<<<<<
pinMode(set_220, INPUT);
Serial.begin(9600); // Скорость обмена данными с компьютером
SIM800.begin(9600); // Скорость обмена данными с модемом
Serial.println("Start!");
analogReference(INTERNAL);
sendATCommand("AT", true); // Отправили AT для настройки скорости обмена данными
sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удаляем все SMS, чтобы не забивать память
sendATCommand("AT+CMGF=1;&W", true); // Включаем текстовый режима SMS (Text mode) и сразу сохраняем значение (AT&W)!
//sendATCommand("AT+CSCB=1;&W", true); // Включаем приём специальных сообщений и сразу сохраняем значение (AT&W)!
lastUpdate = millis(); // Обнуляем таймер
pinMode(line_dor, INPUT_PULLUP);
pinMode(line_windovs, INPUT_PULLUP);
pinMode(sensor_Pin4, INPUT_PULLUP);
pinMode(sensor_Pin5, INPUT_PULLUP);
pinMode(sensor_Pin6, INPUT_PULLUP);
pinMode(speaker, OUTPUT);
pinMode(led_2, OUTPUT);
}
bool hasmsg = false; // Флаг наличия сообщений к удалению
void loop() { //>>>>>>>>>>>>>>>>>> LOOP <<<<<<<<<<<<<<<<<<
if (Serial.available() > 0) { //для UART
char val = Serial.read();
if(val == '3'){k = 3;} //запрос SMS отчета
if(val == '4'){ delay(1000); SIM800.println("AT+CUSD=1,\"" + balance + "\"");}//проверка баланса SIM карты
if(val == '5'){hhh = 1;} //включить сигнализацию
if(val == '6'){hhh = 0;} //выключить сигнализацию
if(val == '7'){ring_st = 1; ring = 0;} //включить исходящий вызов при срабатывании сигнализации
if(val == '8'){ring_st = 0;} //выключить исходящий вызов при срабатывании сигнализации
if(val == '9'){sms_st = 1;} //включить отправку SMS при срабатывании сигнализации
if(val == '0'){sms_st = 0;} //выключить отправку SMS при срабатывании сигнализации
}
/*
//>>>>>>>>>>>>> Получение AT команд из сериал и отправка в модуль <<<<<<<<<<<<<<<<
if (Serial.available()) { // Ожидаем команды по Serial...
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему
};*/
if (lastUpdate + updatePeriod < millis() ) { // Пора проверить наличие новых сообщений
do {
_response = sendATCommand("AT+CMGL=\"REC UNREAD\",1", true);// Отправляем запрос чтения непрочитанных сообщений
if (_response.indexOf("+CMGL: ") > -1) { // Если есть хоть одно, получаем его индекс
Serial.println ("POLUCHENO 1 SMS");
int msgIndex = _response.substring(_response.indexOf("+CMGL: ") + 7, _response.indexOf("\"REC UNREAD\"", _response.indexOf("+CMGL: ")) - 1).toInt();
char i = 0; // Объявляем счетчик попыток
do {
i++; // Увеличиваем счетчик
_response = sendATCommand("AT+CMGR=" + (String)msgIndex + ",1", true); // Пробуем получить текст SMS по индексу
_response.trim(); // Убираем пробелы в начале/конце
if (_response.endsWith("OK")) { // Если ответ заканчивается на "ОК"
if (!hasmsg) hasmsg = true; // Ставим флаг наличия сообщений для удаления
sendATCommand("AT+CMGR=" + (String)msgIndex, true); // Делаем сообщение прочитанным
sendATCommand("\n", true); // Перестраховка - вывод новой строки
parseSMS(_response); // Отправляем текст сообщения на обработку
break; // Выход из do{}
}else { // Если сообщение не заканчивается на OK
Serial.println ("Error answer"); // Какая-то ошибка
sendATCommand("\n", true); // Отправляем новую строку и повторяем попытку
}} while (i < 10);
break;}
else {
lastUpdate = millis(); // Обнуляем таймер
if (hasmsg) {
sendATCommand("AT+CMGDA=\"DEL READ\"", true); // Удаляем все прочитанные сообщения
hasmsg = false;
}break;}} while (1);}
if (SIM800.available()) { // Если модем, что-то отправил...
_response = waitResponse(); // Получаем ответ от модема для анализа
_response.trim(); // Убираем лишние пробелы в начале и конце
Serial.println(_response); // Если нужно выводим в монитор порта
if (_response.indexOf("+CMTI:")>-1) { // Пришло сообщение об отправке SMS
lastUpdate = millis() - updatePeriod; // Теперь нет необходимости обрабатывать SMS здесь, достаточно просто
}
if (_response.indexOf("+CBC:")>-1) { //Если пришел ответ о состоянии батареи
state_Batery = _response.substring(17, 19).toInt(); //Выдергиваем часть строки с данными о состоянии батареи, переводим в integer
//Serial.print("Batery = "); Serial.println(state_Batery);
//Serial.print("Set = "); Serial.println(v);
}
//команды для проверки баланса
if (_response.indexOf("+CUSD:")>-1) { //Если пришел ответ о состоянии баланса
Serial.println(">>>>>send_mesag_Balanse++;<<<<<");
send_mesag_Balanse++;
}}
if (k == 3){delay(300);
Serial.println("<<<Soobshenie Otpravleno (Ktr3)>>>");
numbr_sms(); text_sms(); go_sms();k=0;}
//опрос датчиков
stat_line_dor = digitalRead(line_dor);
if (stat_line_dor == LOW && signalingS == "Signaling OK!") { line_dorS = "Door OK!";}
if (stat_line_dor == HIGH) {line_dorS = "The DOR is OPEN!";}
stat_line_windovs = digitalRead(line_windovs);
if (stat_line_windovs == LOW && signalingS == "Signaling OK!") { line_windovsS = "Windovs OK!";}
if (stat_line_windovs == HIGH) {line_windovsS = "The WINDOVS is OPEN!";}
stat_sensor_Pin4 = digitalRead(sensor_Pin4);
if (stat_sensor_Pin4 == LOW && signalingS == "Signaling OK!") { sensorR_Pin4 = "Sensor 4 OK!";}
if (stat_sensor_Pin4 == HIGH) {sensorR_Pin4 = "Sensor 4 WORKED!";}
stat_sensor_Pin5 = digitalRead(sensor_Pin5);
if (stat_sensor_Pin5 == LOW && signalingS == "Signaling OK!") { sensorR_Pin5 = "Sensor 5 OK!";}
if (stat_sensor_Pin5 == HIGH) {sensorR_Pin5 = "Sensor 5 WORKED!";}
stat_sensor_Pin6 = digitalRead(sensor_Pin6);
if (stat_sensor_Pin6 == LOW && signalingS == "Signaling OK!") { sensorR_Pin6 = "Sensor 6 OK!";}
if (stat_sensor_Pin6 == HIGH) {sensorR_Pin6 = "Sensor 6 WORKED!";}
//Сигнализация выключена
if(hhh == 0){
send_mesag = 0; ring = 0; ring_f = 0;
signaling = "Signaling OFF"; digitalWrite(speaker, LOW);}
//Сигнализация включена
if(hhh == 1){ signaling = "Signaling ON";
// если датчик сработает
if (ring == 0 && led_2_ON == 200)
{ signalingS = "POPYTKA VZLOMA"; digitalWrite(speaker, HIGH);
if (ring_st == 1){ring ++; }
if(sms_st == 1){send_mesag++; }
timing10 = millis(); Serial.println("POPYTKA VZLOMA");
} //else {signalingS = "Signaling OK!";
//if (millis() - timing12 > spiker_time){timing12 = millis(); digitalWrite(speaker, LOW);}
// }
}
// 3 звонка при срабатывании датчиков
if (ring > 0 && millis() - timing10 > ring_time && ring_st == 1){
timing10 = millis(); ring++;
// Serial.print("<<<< Ring "); Serial.print(ring - 1); Serial.println(" >>>");
SIM800.println("ATD" + phon + ";");
}
if (ring > 3) {ring = 0; send_mesag = 0;}
//опрос датчиков
//блинк для индикации сигнализации
if(stat_sensor_Pin6 == LOW && stat_sensor_Pin5 == LOW && stat_sensor_Pin4 == LOW && stat_line_windovs == LOW && stat_line_dor == LOW)
{blinker = 1;}else{blinker = 0;}
if(hhh == 0 && blinker == 1){led_2_ON = 1000; led_2_OFF = 1000;}
if(hhh == 1 && blinker == 1){led_2_ON = 3000; led_2_OFF = 100;}
//опрос датчиков
if(stat_sensor_Pin6 == HIGH || stat_sensor_Pin5 == HIGH || stat_sensor_Pin4 == HIGH || stat_line_windovs == HIGH || stat_line_dor == HIGH)
{led_2_ON = 200; led_2_OFF = 100;
if(hhh == 1){digitalWrite(speaker, HIGH);}
}else {
if (millis() - timing12 > spiker_time){timing12 = millis(); digitalWrite(speaker, LOW);}
}
if (millis() - timing13 > led_2_ON){
timing13 = millis();timing14 = millis();
digitalWrite(led_2, HIGH);
}
if (millis() - timing14 > led_2_OFF){digitalWrite(led_2, LOW);}
if (send_mesag == 1 && sms_st == 1){
// Serial.println("<<<Soobshenie Otpravleno (Pri vzlome)>>>");
numbr_sms(); text_sms(); go_sms(); send_mesag++;
}
if (send_mesag > 2) {send_mesag = 2;}
if (send_mesag_Balanse == 1){
// Serial.println("<<<Soobshenie Otpravleno (Balanse)>>>");
numbr_sms(); SIM800.println(_response); go_sms();
send_mesag_Balanse = 0; delay(1000);
sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удаляем все SMS, чтобы не забивать память
}
if (send_mesag_Balanse >= 2) {send_mesag_Balanse = 0;}
//Сообщение о разряженной батареи
if(state_Batery > 11 && state_Batery < batery_limit){send_mesag_state_Batery++;}else{send_mesag_state_Batery = 0;}
if (send_mesag_state_Batery == 1){
//Serial.println("<<<Soobshenie Otpravleno (Batery < 50%)>>>");
numbr_sms();
SIM800.print("Set = "); SIM800.print(v); SIM800.println(" volt");
delay(300);
SIM800.print("Battery status = "); SIM800.print(state_Batery); SIM800.println("%");
go_sms();
}
if (send_mesag_state_Batery > 2) {send_mesag_state_Batery = 2;}
int sensorVal = digitalRead(set_220); // для получения состояния сети 220
if (sensorVal == HIGH) { v = 220;} else {v = 0;}
if (millis() - timing11 > 40000){
timing11 = millis();
SIM800.println("AT+CBC"); // Получить уровень заряда батареи
// Serial.print ("Ring = ");Serial.print (ring_st);
// Serial.print (" SMS = ");Serial.println (sms_st);
// Serial.println ("GO STATUS BATTERY?");
signalingS = "Signaling OK!";
}
}
//Конец скетча
После загрузки скетча соберите все, как показано на этой схеме.