GSM сигнализация на базе Arduino UNO и GSM модуля SIM800l

Здравствуйте!

Вот такая коробочка у меня получилась.

 GSM сигнализация на базе Arduino UNO и GSM модуля SIM800l. Скачать прошивку бесплатно

Для сборки понадобится:

Корпус от старого нерабочего роутера, или любая друга подходящая коробка.

GSM модуль SIM800L.

Активная Sim карта с положительным балансом.

Литий-ионный аккумулятор 3,7 вольта на 2000-3000 миллиампер.

Контроллер заряда аккумуляторов на 3,7 вольта USB-MINI.

Пожарный звуковой оповещатель.

NPN транзистор подходящий по мощности для пожарного оповещателя.

Датчики движения HC-SR501 и концевые выключатели (в сумме 5 штук).

Один маломощный светодиод для индикации.

4 сопротивления: 250, 1К, 2К и 2,4К .

Соединительные провода .

Плата Arduino UNO

 GSM модуль SIM800L, активная Sim карта с положительным балансом,
литий-ионный аккумулятор 3,7 вольта на 2000-3000 миллиампер,
контроллер заряда USB-MINI, пожарный звуковой оповещатель,
NPN транзистор, датчики движения HC-SR501, и концевые выключатели, 
один маломощный светодиод для индикации, 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!";

}
}

//Конец скетча




После загрузки скетча соберите все, как показано на этой схеме.

Схема для сборки GSM сигнализации на базе Arduino UNO и GSM модуля SIM800l

Подробное видео “GSM сигнализация на базе Arduino UNO и GSM модуля SIM800l”


 GSM сигнализация на базе Arduino UNO и GSM модуля SIM800l.