GSM сигнализация не работает без ПК

restiv
Offline
Зарегистрирован: 03.01.2016

Доброго времени суток уважаемые форумчане!

На просторах интернета нашел простенькую GSM сигнализацию на основе модуля SIM800l и управлением с помощью СМС. Заказал, собрал, запустил. Все работало отлично, но стоило мне отключить сигналку от ПК, как она перестала работать. Стоит мне снова подключить сигналку к ПК, так она снова начинает работать как часы. Реагирует на СМС команды, высылает ответы на команды, срабатывает на открытие двери (датчик Холла стоит), световая индикация срабатывает. Но при отключении от ПК, снова превращается в "кирпич". Подскажите в чем проблема? Скетч прилагаю.

#include <SoftwareSerial.h>                                      // Библиотека програмной реализации обмена по UART-протоколу
SoftwareSerial SIM800(8, 9);                                     // RX, TX

int flag1=0;                                                     //Переменная 1 для выполнения программы сработки
int flag2=0;                                                     //Переменная 2 для выполнения программы взятия и снятия
int flag3=0;                                                     //Переменная 3 для выполнения программы контроля входящего напряжени
int flag4=0;                                                     //Переменная 4 для выполнения программы РЕЛЕ
int flag5=0;                                                     //Переменная 5 для выполнения программы Розетка
String n1 = "+71111111111";
String n2 = "+71111111112";
String sms0 = "Pod Ohranoi";
String sms1 = "Srabotka";
//String sms2 = "+12Volt Warning";
//String sms3 = "+12Volt Ready";
String sms4 = "Snyto";
String sms5 = "Realy ON";
String sms6 = "Realy OFF";
String sms7 = "Realy2 ON";
String sms8 = "Realy2 OFF";
String sms9 = "The system works normally.OK";
String msgphone   = "";

uint8_t hours = 0; 
String _response    = "";                                         // Переменная для хранения ответа модуля
long lastUpdate = millis();                                       // Время последнего обновления
long updatePeriod   = 15000;                                      // Проверять каждые 15 секунд

String phones = "+71111111111, +71111111112, +71111113";                     // Белый список телефонов

void setup() {
 pinMode(5, OUTPUT);                                              //  Сюда подключаем выход на реле управления розеткой
 pinMode(6, OUTPUT);                                              //  Сюда подключаем выход на реле управления обогрева АВТО
 pinMode(2, OUTPUT);                                              //  Сюда подключаем красный Диод черз резистор минус к выходу 4 через резистор 560 Ом
 pinMode(3, OUTPUT);                                              //  Сюда подключаем зеленый Диод черз резистор минус к выходу 5 через резистор 560 Ом
 pinMode(4, INPUT);                                              //  геркон или объемник
 pinMode(7, INPUT);                                               //  +5 вольт с делителя напряжения питания (следит за питанием 12 вольт БП)
  
  Serial.begin(9600);                                             // Скорость обмена данными с компьютером (это для отладки)
  SIM800.begin(9600);                                             // Скорость обмена данными с модемом
  Serial.println("Start!");

  sendATCommand("AT", true);                                      // Отправили AT для настройки скорости обмена данными
  delay(5000); // Ждем 5 секунд
  sendATCommand("AT+CMGDA=\"DEL ALL\"", true);                    // Удаляем все SMS, чтобы не забивать память

  // Команды настройки модема при каждом запуске
  _response = sendATCommand("AT+CLIP=1", true);                   // Включаем АОН
  _response = sendATCommand("AT+DDET=1", true);                   // Включаем DTMF
  _response = sendATCommand("AT+CMGF=1;&W", true);                // Включаем текстовый режима SMS (Text mode) и сразу сохраняем значение (AT&W)!
  lastUpdate = millis();                                          // Обнуляем таймер
}

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;                                                   // Возвращаем результат. Пусто, если проблема
}

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;                                                   // ... возвращаем результат. Пусто, если проблема
}

bool hasmsg = false;                                              // Флаг наличия сообщений к удалению


void loop() {
 
  if (lastUpdate + updatePeriod < millis() ) {                    // Пора проверить наличие новых сообщений
    do {
      _response = sendATCommand("AT+CMGL=\"REC UNREAD\",1", true);// Отправляем запрос чтения непрочитанных сообщений
      if (_response.indexOf("+CMGL: ") > -1) {                    // Если есть хоть одно, получаем его индекс
        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) {
          delay(4000); // Ждем 4 секунд
          sendATCommand("AT+CMGDA=\"DEL ALL\"", 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 (Serial.available())  {                                      // Ожидаем команды по Serial... (возможность через серийный порт общаться с модемом для отладки)
    SIM800.write(Serial.read());                                  // ...и отправляем полученную команду модему
  };

//Сработка

  if (digitalRead(4)==HIGH && flag2==1 && flag1==0) {
        flag1++;
        digitalWrite(2, HIGH);                                      // Выключаем зеленый светодиод
        digitalWrite(3, LOW);                                     // Включаем красный светодиод
       
        SIM800.println("AT+CMGS=\"" + n1 + "\"");                  // ...и отправляем полученную команду модему
        delay(500);                                                // Ждем 0,5 секунд
        SIM800.println(sms1+ "\r\n" + ((char)26));                 // текст смс и После текста отправляем перенос строки и Ctrl+Z
        delay(5000);                                               // Ждем 5 секунд

      
}
    
/*Контроль питания отсутствие
   
  if (digitalRead(7)==LOW && flag3==0) {
    flag3++;
   
    SIM800.println("AT+CMGS=\"" + n1 + "\"");                       // ...и отправляем полученную команду модему
    delay(500); // Ждем 0,5 секунд
    SIM800.println(sms2+ "\r\n" + ((char)26));                      // текст смс и После текста отправляем перенос строки и Ctrl+Z
    delay(5000);                                                    // Ждем 5 секунд

   
}

//Контроль питания востановлено
   
  if (digitalRead(7)==HIGH && flag3==1) {
    flag3=0;
    SIM800.println("AT+CMGS=\"" + n1 + "\"");                       // ...и отправляем полученную команду модему
    delay(500); // Ждем 0,5 секунд
    SIM800.println(sms3+ "\r\n" + ((char)26));                      // текст смс и После текста отправляем перенос строки и Ctrl+Z
    delay(5000);                                                    // Ждем 5 секунд

   
}
*/
}

void parseSMS(String msg) {                                   // Парсим SMS
  String msgheader  = "";
  String msgbody    = "";
  

  msg = msg.substring(msg.indexOf("+CMGR: "));
  msgheader = msg.substring(0, msg.indexOf("\r"));            // Выдергиваем телефон

  msgbody = msg.substring(msgheader.length() + 2);
  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) { // Если телефон в белом списке, то...
    setLedState(msgbody, msgphone);                           // ...выполняем команду
  }
  else {
    Serial.println("Unknown phonenumber");
    SIM800.println("AT+CMGS=\"" + n1 + "\"");   // ...и отправляем полученную команду модему, отправляет 1 номеру Unknown phonenumber, можно добавить, чтоб номер еще отправлял левый
    delay(1000); // Ждем 1 секунд
    SIM800.println(msgphone + " Unknown phonenumber" + "\r\n" + ((char)26));    // текст смс и После текста отправляем перенос строки и Ctrl+Z
    }
}

void setLedState (String result, String phone) {
  bool correct = false;                           // Для оптимизации кода, переменная корректности команды
  String msgToSend = "";
  String my_ohr = "";                             // Переменная для хранения ответа охраны
  String my_power = "";                           // Переменная для хранения ответа питания
  String my_realy = "";                           // Переменная для хранения ответа Реле
  String my_realy2 = "";                           // Переменная для хранения ответа Розетки
  String my_status = "";                           // Переменная для хранения ответа статуса
  
  //Постановка на охрану
  
  if (result == "On" && digitalRead(10)==LOW && flag1==0 && flag2==0) {
          digitalWrite(3, HIGH);                                 // Исполняем команду
          flag2++;
          delay(2000); // Ждем 1 секунд
          msgToSend = sms0;                                      // Статус исполнения
      
   correct = true;                                               // Флаг корректности команды
 
}
   //Снятие с охраны
   
  if (result == "Off" && flag2==1) {
    flag1=0;
    flag2=0;
    digitalWrite(2, LOW);                      // выключаем светодиод
    digitalWrite(3, LOW);                      // выключаем светодиод
    delay(1000); // Ждем 1 секунд
    msgToSend = sms4;                                         // Статус исполнения

 correct = true;                                         // Флаг корректности команды
 
}

//Включение РЕЛЕ
   
  if (result == "Realy ON" && flag4==0) {
    flag4=1;
    digitalWrite(3, HIGH);                     // включаем РЕЛЕ
    delay(1000); // Ждем 1 секунд
    msgToSend = sms5;                          // Статус исполнения

 correct = true;                               // Флаг корректности команды
 
}

//Выключение РЕЛЕ
   
  if (result == "Realy OFF" && flag4==1) {
    flag4=0;
    digitalWrite(3, LOW);                     // вsключаем РЕЛЕ
    delay(1000); // Ждем 1 секунд
    msgToSend = sms6;                         // Статус исполнения

 correct = true;                              // Флаг корректности команды
 
}

//Включение Розетки
   
  if (result == "Realy2 ON" && flag5==0) {
    flag5=1;
    digitalWrite(6, HIGH);                     // включаем РЕЛЕ
    delay(1000); // Ждем 1 секунд
    msgToSend = sms7;                          // Статус исполнения

 correct = true;                               // Флаг корректности команды
 
}

//Выключение Розетки
   
  if (result == "Realy2 OFF" && flag5==1) {
    flag5=0;
    digitalWrite(6, LOW);                     // вsключаем РЕЛЕ
    delay(1000); // Ждем 1 секунд
    msgToSend = sms8;                         // Статус исполнения

 correct = true;                              // Флаг корректности команды
 
}

if(millis() - lastUpdate >= 3600000) {lastUpdate = millis(); hours++;}

  if(hours >= 1) {// Меняем время контроля системы на свое, 1 часа.кол-во часов .
    msgToSend = sms9;
    delay(10000);                                                               
    hours = 0;                                     
    lastUpdate = millis();                         
  }


//Статус
   
  if (result == "Status") {
    if (flag2==1 && digitalRead(2)==HIGH){
    my_ohr = "Pod Ohranoi";                                                    //Статус на охране
    }
    if (flag2==0 && flag1==0 && digitalRead(2)==LOW && digitalRead(3)==LOW) {
    my_ohr = "Snyto";                                                          //Статус снят с охраны
    }
    if (flag2==1 && flag1==1 && digitalRead(2)==LOW && digitalRead(3)==HIGH) {
    my_ohr = "Srabotka";                                                       // Статус сработки
    }
    if (flag3==0) {
    my_power = "+12Volt Ready";                                                // Статус наличия питания 12 вольт
    }
    if (flag3==1) {
    my_power = "+12Volt Warning";                                              // Статус отсутствия питания 12 вольт
    }
    if (flag4==1 && digitalRead(6)==HIGH) {
    my_realy = "Realy ON";                                                     // Статус включеного РЕЛЕ
    }
    if (flag4==0 && digitalRead(6)==LOW) {
    my_realy = "Realy OFF";                                                    // Статус отключеного РЕЛЕ
    }
    if (flag5==1 && digitalRead(7)==HIGH) {
    my_realy2 = "Realy2 ON";                                                     // Статус включеного РЕЛЕ
    }
    if (flag5==0 && digitalRead(7)==LOW) {
    my_realy2 = "Realy2 OFF";                                                    // Статус отключеного РЕЛЕ
    }
        
   msgToSend = (my_ohr + "\r\n" + my_power + "\r\n" + my_realy + "\r\n" + my_realy2);               // Статус исполнения

 correct = true;                                                               // Флаг корректности команды
   
}
  
  if (!correct) {
  msgToSend = "Incorrect command: " + result;               // Статус исполнения
  }

  //Тут идет проверка номера, если команды отправляет 1 номер, то все в норме, если 2 или 3 и так далее из белого списка, то ответ дублируется 1 номеру + номер того, кто производит запросы
  if (msgphone == "+77051314021"){
  SIM800.println("AT+CMGS=\"" + msgphone + "\"");   // ...и отправляем полученную команду модему
  delay(500); // Ждем 0,5 секунд
  SIM800.println(msgToSend + "\r\n" + ((char)26));    // текст смс и После текста отправляем перенос строки и Ctrl+Z
  Serial.println("1 uslovie" + msgphone + msgToSend + "\r\n" + ((char)26));
  }

  
  else
  {
  SIM800.println("AT+CMGS=\"" + msgphone + "\"");   // ...и отправляем полученную команду модему
  delay(500); // Ждем 0,5 секунд
  SIM800.println(msgToSend+ "\r\n" + ((char)26));    // текст смс и После текста отправляем перенос строки и Ctrl+Z
  delay(5000); // Ждем 5 секунд
 
  SIM800.println("AT+CMGS=\"" + n1 + "\"");   // ...и отправляем полученную команду модему
  delay(500); // Ждем 0,5 секунд
  SIM800.println(msgphone + " " + msgToSend + "\r\n" + ((char)26));    // текст смс и После текста отправляем перенос строки и Ctrl+Z
  delay(1000); // Ждем 1 секунд
  Serial.println("2 uslovie" + msgphone + msgToSend + "\r\n" + ((char)26));
  }

}



 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Схема подключения?

andriano
andriano аватар
Онлайн
Зарегистрирован: 20.06.2015

restiv пишет:

Все работало отлично, но стоило мне отключить сигналку от ПК, как она перестала работать.

Ни одна схема не сможет работать, если на нее не подавать питание.

restiv
Offline
Зарегистрирован: 03.01.2016

andycat пишет:
Схема подключения?

Извините, набросал как смог.

restiv
Offline
Зарегистрирован: 03.01.2016

andriano пишет:

restiv пишет:

Все работало отлично, но стоило мне отключить сигналку от ПК, как она перестала работать.

Ни одна схема не сможет работать, если на нее не подавать питание.

Так с питанием как раз все в порядке. Схема питается от контроллера заряда TP4056 и плюс там еще предусмотрено резервное питание от 18650.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

На приведенной схеме ардуина не запитана от контроллера заряда и при отключениии от ПК работать не сможет.

restiv
Offline
Зарегистрирован: 03.01.2016

Jeka_M пишет:

На приведенной схеме ардуина не запитана от контроллера заряда и при отключениии от ПК работать не сможет.

Я прошу прощение, я просто забыл прорисовать. Уже исправил. На самом деле и ардуино и модуль запитаны от контроллера заряда. Ардуино запитана через пин VIN. 

Я может не совсем правильно выразился. Дело в том, что когда я отключаю ардуинку от ПК, то и модуль SIM800l , и ардуинка продолжают работать, и моргать светодиодами. Если позвонить на модуль, то звонок проходит. Но модуль не реагирует на смс команды. т.е. смс доходят до модуля, но модуль их игнорирует. А стоит только подключить ардуинку к ПК, так она тут же начинает отвечать на смс команды.  

Я даже пробовал запитывать ардуинку от power bank через юсб шнур, думал, может где то питания не хватает ардуинке. Но все равно это никак не помогает.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

restiv пишет:

На самом деле и ардуино и модуль запитаны от контроллера заряда. Ардуино запитана через пин VIN. 

Это неправильно. Пин VIN подключён к линейному регулятору напряжения на плате ардуино и предназначен для подачи нестабилизированного питания с напряжением от 6В до 12В. А контроллер зарада выдает около 4.2В, а аккумулятор и того меньше.

Если напряжение питания 5В и меньше, то подавать его нужно на пин +5V, который подключен напрямую к ножке VCC микроконтроллера.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Уважаемый ТС, слона надо есть по частям. Сначала вместо аккумуляторов и всей остальной обвязки по питанию подключите блок питания ампера в 2, чтобы наверняка. Если все заработает, то проблема в Вашем питании. Туда и надо будет копать.

restiv
Offline
Зарегистрирован: 03.01.2016

Jeka_M пишет:

Это неправильно. Пин VIN подключён к линейному регулятору напряжения на плате ардуино и предназначен для подачи нестабилизированного питания с напряжением от 6В до 12В. А контроллер зарада выдает около 4.2В, а аккумулятор и того меньше.

Если напряжение питания 5В и меньше, то подавать его нужно на пин +5V, который подключен напрямую к ножке VCC микроконтроллера.

Спасибо. Перепаял и все заработало. Еще раз спасибо. Но вот в процессе эксплуатации обнаружился глюк. После срабатывания сигналки нужно ее снять с охраны и потом снова поставить, чтобы она вновь была активированна. А как можно это исправить? Чтобы не приходилось снимать, а чтобы можно было просто повторно перепоставить командой "On"?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

restiv пишет:

 а чтобы можно было просто повторно перепоставить командой "On"?

Можно, для этого flag1 надо сделать нулем.

restiv
Offline
Зарегистрирован: 03.01.2016

Добрый день форумчане!

Прошу еще вашего совета. В исходном скетче не отрабатывает функция отвечающая за отправку еженедельных сообщений, о состоянии системы строки 85-94. Подскажите в чем я накосячил?

#include <SoftwareSerial.h>                                      // Библиотека програмной реализации обмена по UART-протоколу
SoftwareSerial SIM800(8, 9);                                     // RX, TX

int flag1=0;                                                     //Переменная 1 для выполнения программы сработки
int flag2=0;                                                     //Переменная 2 для выполнения программы взятия и снятия
int flag3=0;                                                     //Переменная 3 для выполнения программы контроля входящего напряжени
int flag4=0;                                                     //Переменная 4 для выполнения программы РЕЛЕ
int flag5=0;                                                     //Переменная 5 для выполнения программы Розетка
String n2 = "+77777777777";
String n1 = "+77777777778";
String sms0 = "Pod Ohranoi";
String sms1 = "Srabotka";
String sms2 = "220 Volt Off";
String sms3 = "220 Volt On";
String sms4 = "Snyto";
String sms5 = "Realy ON";
String sms6 = "Realy OFF";
String sms7 = "Realy2 ON";
String sms8 = "Realy2 OFF";
String sms9 = "The system works normally.OK";
String msgphone   = "";

uint8_t hours = 0; 
String _response    = "";                                         // Переменная для хранения ответа модуля
long lastUpdate = millis();                                       // Время последнего обновления
long updatePeriod   = 15000;                                      // Проверять каждые 15 секунд

String phones = "+7777777777, +7777777778, +71111113";          // Белый список телефонов

void setup() {
 pinMode(5, OUTPUT);                                              //  Сюда подключаем выход на реле управления розеткой
 //pinMode(6, OUTPUT);                                            //  Сюда подключаем выход на реле управления обогрева АВТО
 pinMode(2, OUTPUT);                                              //  Сюда подключаем красный Диод черз резистор минус к выходу 4 через резистор 560 Ом
 pinMode(3, OUTPUT);                                              //  Сюда подключаем зеленый Диод черз резистор минус к выходу 5 через резистор 560 Ом
 pinMode(4, INPUT);                                               //  геркон или объемник
 pinMode(6, INPUT);                                               //  +5 вольт с делителя напряжения питания (следит за питанием 220 вольт)
  
  Serial.begin(9600);                                             // Скорость обмена данными с компьютером (это для отладки)
  SIM800.begin(9600);                                             // Скорость обмена данными с модемом
  Serial.println("Start!");

  sendATCommand("AT", true);                                      // Отправили AT для настройки скорости обмена данными
  delay(5000); // Ждем 5 секунд
  sendATCommand("AT+CMGDA=\"DEL ALL\"", true);                    // Удаляем все SMS, чтобы не забивать память

  // Команды настройки модема при каждом запуске
  _response = sendATCommand("AT+CLIP=1", true);                   // Включаем АОН
  _response = sendATCommand("AT+DDET=1", true);                   // Включаем DTMF
  _response = sendATCommand("AT+CMGF=1;&W", true);                // Включаем текстовый режима SMS (Text mode) и сразу сохраняем значение (AT&W)!
  lastUpdate = millis();                                          // Обнуляем таймер
}

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;                                                   // Возвращаем результат. Пусто, если проблема
}

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;                                                   // ... возвращаем результат. Пусто, если проблема
}

bool hasmsg = false;                                              // Флаг наличия сообщений к удалению


void loop() {

 if(millis() - lastUpdate >= 3600000) {lastUpdate = millis(); hours++;}

  if(hours >= 2) {                                                // Меняем время контроля системы на свое,144 часа.кол-во часов .
    SIM800.println("AT+CMGS=\"" + n1 + "\"");                       // ...и отправляем полученную команду модему
    delay(500); // Ждем 0,5 секунд
    SIM800.println(sms9+ "\r\n" + ((char)26));                      // текст смс и После текста отправляем перенос строки и Ctrl+Z
    delay(5000);                                                    // Ждем 5 секунд                       
    hours = 0;                                     
    lastUpdate = millis();
  }

      if (lastUpdate + updatePeriod < millis() ) {                  // Пора проверить наличие новых сообщений
    do {
      _response = sendATCommand("AT+CMGL=\"REC UNREAD\",1", true);  // Отправляем запрос чтения непрочитанных сообщений
      if (_response.indexOf("+CMGL: ") > -1) {                      // Если есть хоть одно, получаем его индекс
        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) {
          delay(4000); // Ждем 4 секунд
          sendATCommand("AT+CMGDA=\"DEL ALL\"", 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 (Serial.available())  {                                        // Ожидаем команды по Serial... (возможность через серийный порт общаться с модемом для отладки)
    SIM800.write(Serial.read());                                    // ...и отправляем полученную команду модему
  };

//Сработка

  if (digitalRead(4)==HIGH && flag2==1 && flag1==0) {
        flag1++;
        digitalWrite(2, HIGH);                                      // Выключаем зеленый светодиод
        digitalWrite(3, LOW);                                       // Включаем красный светодиод
       
        SIM800.println("AT+CMGS=\"" + n1 + "\"");                   // ...и отправляем полученную команду модему
        delay(500);                                                 // Ждем 0,5 секунд
        SIM800.println(sms1+ "\r\n" + ((char)26));                  // текст смс и После текста отправляем перенос строки и Ctrl+Z
        delay(5000);                                                // Ждем 5 секунд

      
}
    
//Контроль питания отсутствие
   
  if (digitalRead(6)==LOW && flag3==0) {
    flag3++;
   
    SIM800.println("AT+CMGS=\"" + n1 + "\"");                       // ...и отправляем полученную команду модему
    delay(500); // Ждем 0,5 секунд
    SIM800.println(sms2+ "\r\n" + ((char)26));                      // текст смс и После текста отправляем перенос строки и Ctrl+Z
    delay(5000);                                                    // Ждем 5 секунд

   
}

//Контроль питания востановлено
   
  if (digitalRead(6)==HIGH && flag3==1) {
    flag3=0;
    SIM800.println("AT+CMGS=\"" + n1 + "\"");                       // ...и отправляем полученную команду модему
    delay(500); // Ждем 0,5 секунд
    SIM800.println(sms3+ "\r\n" + ((char)26));                      // текст смс и После текста отправляем перенос строки и Ctrl+Z
    delay(5000);                                                    // Ждем 5 секунд

   
}

}

void parseSMS(String msg) {                                        // Парсим SMS
  String msgheader  = "";
  String msgbody    = "";
  

  msg = msg.substring(msg.indexOf("+CMGR: "));
  msgheader = msg.substring(0, msg.indexOf("\r"));                // Выдергиваем телефон

  msgbody = msg.substring(msgheader.length() + 2);
  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) {   // Если телефон в белом списке, то...
    setLedState(msgbody, msgphone);                               // ...выполняем команду
  }
  else {
    Serial.println("Unknown phonenumber");
    SIM800.println("AT+CMGS=\"" + n1 + "\"");                     // ...и отправляем полученную команду модему, отправляет 1 номеру Unknown phonenumber, можно добавить, чтоб номер еще отправлял левый
    delay(1000); // Ждем 1 секунд
    SIM800.println(msgphone + " Unknown phonenumber" + "\r\n" + ((char)26));    // текст смс и После текста отправляем перенос строки и Ctrl+Z
    }
}

void setLedState (String result, String phone) {
  bool correct = false;                                          // Для оптимизации кода, переменная корректности команды
  String msgToSend = "";
  String my_ohr = "";                                            // Переменная для хранения ответа охраны
  String my_power = "";                                          // Переменная для хранения ответа питания
  String my_realy = "";                                          // Переменная для хранения ответа Реле
  String my_realy2 = "";                                         // Переменная для хранения ответа Розетки
  String my_status = "";                                         // Переменная для хранения ответа статуса
  
  //Постановка на охрану
  
  if (result == "On" && digitalRead(10)==LOW && flag1==0 && flag2==0) {
          digitalWrite(3, HIGH);                                 // Исполняем команду
          flag2++;
          delay(2000); // Ждем 1 секунд
          msgToSend = sms0;                                      // Статус исполнения
      
   correct = true;                                               // Флаг корректности команды
 
}
   //Снятие с охраны
   
  if (result == "Off" && flag2==1) {
    flag1=0;
    flag2=0;
    digitalWrite(2, LOW);                                        // выключаем светодиод
    digitalWrite(3, LOW);                                        // выключаем светодиод
    delay(1000); // Ждем 1 секунд
    msgToSend = sms4;                                            // Статус исполнения

 correct = true;                                                 // Флаг корректности команды
 
}

//Включение РЕЛЕ
   
  if (result == "Realy ON" && flag4==0) {
    flag4=1;
    digitalWrite(3, HIGH);                                       // включаем РЕЛЕ
    delay(1000); // Ждем 1 секунд
    msgToSend = sms5;                                            // Статус исполнения

 correct = true;                                                 // Флаг корректности команды
 
}

//Выключение РЕЛЕ
   
  if (result == "Realy OFF" && flag4==1) {
    flag4=0;
    digitalWrite(3, LOW);                                        // вsключаем РЕЛЕ
    delay(1000); // Ждем 1 секунд
    msgToSend = sms6;                                            // Статус исполнения

 correct = true;                                                 // Флаг корректности команды
 
}

//Включение Розетки
   
  if (result == "Realy2 ON" && flag5==0) {
    flag5=1;
    digitalWrite(7, HIGH);                                     // включаем РЕЛЕ
    delay(1000); // Ждем 1 секунд
    msgToSend = sms7;                                          // Статус исполнения

 correct = true;                                               // Флаг корректности команды
 
}

//Выключение Розетки
   
  if (result == "Realy2 OFF" && flag5==1) {
    flag5=0;
    digitalWrite(7, LOW);                                      // вsключаем РЕЛЕ
    delay(1000); // Ждем 1 секунд
    msgToSend = sms8;                                          // Статус исполнения

 correct = true;                                               // Флаг корректности команды
 
}

//Статус
   
  if (result == "Status") {
    if (flag2==1 && digitalRead(2)==HIGH){
    my_ohr = "Pod Ohranoi";                                                    //Статус на охране
    }
    if (flag2==0 && flag1==0 && digitalRead(2)==LOW && digitalRead(3)==LOW) {
    my_ohr = "Snyto";                                                          //Статус снят с охраны
    }
    if (flag2==1 && flag1==1 && digitalRead(2)==LOW && digitalRead(3)==HIGH) {
    my_ohr = "Srabotka";                                                       // Статус сработки
    }
    if (flag3==0) {
    my_power = "+12Volt Ready";                                                // Статус наличия питания 12 вольт
    }
    if (flag3==1) {
    my_power = "+12Volt Warning";                                              // Статус отсутствия питания 12 вольт
    }
    if (flag4==1 && digitalRead(7)==HIGH) {
    my_realy = "Realy ON";                                                     // Статус включеного РЕЛЕ
    }
    if (flag4==0 && digitalRead(7)==LOW) {
    my_realy = "Realy OFF";                                                    // Статус отключеного РЕЛЕ
    }
    if (flag5==1 && digitalRead(7)==HIGH) {
    my_realy2 = "Realy2 ON";                                                     // Статус включеного РЕЛЕ
    }
    if (flag5==0 && digitalRead(7)==LOW) {
    my_realy2 = "Realy2 OFF";                                                    // Статус отключеного РЕЛЕ
    }
        
   msgToSend = (my_ohr + "\r\n" + my_power + "\r\n" + my_realy + "\r\n" + my_realy2);               // Статус исполнения

 correct = true;                                                                // Флаг корректности команды
   
}
  
  if (!correct) {
  msgToSend = "Incorrect command: " + result;                                   // Статус исполнения
  }

  //Тут идет проверка номера, если команды отправляет 1 номер, то все в норме, если 2 или 3 и так далее из белого списка, то ответ дублируется 1 номеру + номер того, кто производит запросы
  if (msgphone == "+77051314021"){
  SIM800.println("AT+CMGS=\"" + msgphone + "\"");                               // ...и отправляем полученную команду модему
  delay(500); // Ждем 0,5 секунд
  SIM800.println(msgToSend + "\r\n" + ((char)26));                              // текст смс и После текста отправляем перенос строки и Ctrl+Z
  Serial.println("1 uslovie" + msgphone + msgToSend + "\r\n" + ((char)26));
  }

  
  else
  {
  SIM800.println("AT+CMGS=\"" + msgphone + "\"");                              // ...и отправляем полученную команду модему
  delay(500); // Ждем 0,5 секунд
  SIM800.println(msgToSend+ "\r\n" + ((char)26));                              // текст смс и После текста отправляем перенос строки и Ctrl+Z
  delay(5000); // Ждем 5 секунд
 
  SIM800.println("AT+CMGS=\"" + n1 + "\"");                                    // ...и отправляем полученную команду модему
  delay(500); // Ждем 0,5 секунд
  SIM800.println(msgphone + " " + msgToSend + "\r\n" + ((char)26));            // текст смс и После текста отправляем перенос строки и Ctrl+Z
  delay(1000); // Ждем 1 секунд
  Serial.println("2 uslovie" + msgphone + msgToSend + "\r\n" + ((char)26));
  }

}



 

vvadim
Offline
Зарегистрирован: 23.05.2012

кстати, для нормальной работы на SIM8OOL  нужно подать 4 вольта 1 ампер.

ваша схема по питаню в корне не правильная.

restiv
Offline
Зарегистрирован: 03.01.2016

vvadim пишет:

кстати, для нормальной работы на SIM8OOL  нужно подать 4 вольта 1 ампер.

ваша схема по питаню в корне не правильная.

Согласно даташиту на SIM800l он питается от 3,4-4,4 В. По моей схеме питание подается около 4,2 В. Все в допустимых рамках. Что касается силы тока, то контроллер заряда TP 4056 как раз расчитан на 1А. Так что не понимаю, в чем конкретно она в корне не правильная??? Поясните пожалуйста! 

vlad072
Offline
Зарегистрирован: 01.08.2017

Нормальный 18650 отдаёт до 30А и больше без проблем, так что не парься. Даже самый дешманский для фонариков ампер 5 отдаст точно. Только нужно ещё поставить step-down 5-вольтовый чтоб заряжать аккум через клемы +/- со стороны micro-usb, вот такой пойдёт https://ru.aliexpress.com/item/Mini360-HM-DC-DC-23/32921703886.html?Единственное что, если в ардуинке стоит кварц на 16МГц, при низком заряде её может проглючить. На таких частотах атмеге надо 5В. Короче надо кварц на 8Мгц при таком варианте питания.

restiv
Offline
Зарегистрирован: 03.01.2016

Добрый день форумчане!

Прошу еще вашего совета. В исходном скетче не отрабатывает функция отвечающая за отправку еженедельных сообщений, о состоянии системы строки 85-94. Подскажите в чем я накосячил?

#include <SoftwareSerial.h>                                      // Библиотека програмной реализации обмена по UART-протоколу
SoftwareSerial SIM800(8, 9);                                     // RX, TX

int flag1=0;                                                     //Переменная 1 для выполнения программы сработки
int flag2=0;                                                     //Переменная 2 для выполнения программы взятия и снятия
int flag3=0;                                                     //Переменная 3 для выполнения программы контроля входящего напряжени
int flag4=0;                                                     //Переменная 4 для выполнения программы РЕЛЕ
int flag5=0;                                                     //Переменная 5 для выполнения программы Розетка
String n2 = "+77777777777";
String n1 = "+77777777778";
String sms0 = "Pod Ohranoi";
String sms1 = "Srabotka";
String sms2 = "220 Volt Off";
String sms3 = "220 Volt On";
String sms4 = "Snyto";
String sms5 = "Realy ON";
String sms6 = "Realy OFF";
String sms7 = "Realy2 ON";
String sms8 = "Realy2 OFF";
String sms9 = "The system works normally.OK";
String msgphone   = "";

uint8_t hours = 0; 
String _response    = "";                                         // Переменная для хранения ответа модуля
long lastUpdate = millis();                                       // Время последнего обновления
long updatePeriod   = 15000;                                      // Проверять каждые 15 секунд

String phones = "+7777777777, +7777777778, +71111113";          // Белый список телефонов

void setup() {
 pinMode(5, OUTPUT);                                              //  Сюда подключаем выход на реле управления розеткой
 //pinMode(6, OUTPUT);                                            //  Сюда подключаем выход на реле управления обогрева АВТО
 pinMode(2, OUTPUT);                                              //  Сюда подключаем красный Диод черз резистор минус к выходу 4 через резистор 560 Ом
 pinMode(3, OUTPUT);                                              //  Сюда подключаем зеленый Диод черз резистор минус к выходу 5 через резистор 560 Ом
 pinMode(4, INPUT);                                               //  геркон или объемник
 pinMode(6, INPUT);                                               //  +5 вольт с делителя напряжения питания (следит за питанием 220 вольт)
  
  Serial.begin(9600);                                             // Скорость обмена данными с компьютером (это для отладки)
  SIM800.begin(9600);                                             // Скорость обмена данными с модемом
  Serial.println("Start!");

  sendATCommand("AT", true);                                      // Отправили AT для настройки скорости обмена данными
  delay(5000); // Ждем 5 секунд
  sendATCommand("AT+CMGDA=\"DEL ALL\"", true);                    // Удаляем все SMS, чтобы не забивать память

  // Команды настройки модема при каждом запуске
  _response = sendATCommand("AT+CLIP=1", true);                   // Включаем АОН
  _response = sendATCommand("AT+DDET=1", true);                   // Включаем DTMF
  _response = sendATCommand("AT+CMGF=1;&W", true);                // Включаем текстовый режима SMS (Text mode) и сразу сохраняем значение (AT&W)!
  lastUpdate = millis();                                          // Обнуляем таймер
}

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;                                                   // Возвращаем результат. Пусто, если проблема
}

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;                                                   // ... возвращаем результат. Пусто, если проблема
}

bool hasmsg = false;                                              // Флаг наличия сообщений к удалению


void loop() {

 if(millis() - lastUpdate >= 3600000) {lastUpdate = millis(); hours++;}

  if(hours >= 2) {                                                // Меняем время контроля системы на свое,144 часа.кол-во часов .
    SIM800.println("AT+CMGS=\"" + n1 + "\"");                       // ...и отправляем полученную команду модему
    delay(500); // Ждем 0,5 секунд
    SIM800.println(sms9+ "\r\n" + ((char)26));                      // текст смс и После текста отправляем перенос строки и Ctrl+Z
    delay(5000);                                                    // Ждем 5 секунд                       
    hours = 0;                                     
    lastUpdate = millis();
  }

      if (lastUpdate + updatePeriod < millis() ) {                  // Пора проверить наличие новых сообщений
    do {
      _response = sendATCommand("AT+CMGL=\"REC UNREAD\",1", true);  // Отправляем запрос чтения непрочитанных сообщений
      if (_response.indexOf("+CMGL: ") > -1) {                      // Если есть хоть одно, получаем его индекс
        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) {
          delay(4000); // Ждем 4 секунд
          sendATCommand("AT+CMGDA=\"DEL ALL\"", 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 (Serial.available())  {                                        // Ожидаем команды по Serial... (возможность через серийный порт общаться с модемом для отладки)
    SIM800.write(Serial.read());                                    // ...и отправляем полученную команду модему
  };

//Сработка

  if (digitalRead(4)==HIGH && flag2==1 && flag1==0) {
        flag1++;
        digitalWrite(2, HIGH);                                      // Выключаем зеленый светодиод
        digitalWrite(3, LOW);                                       // Включаем красный светодиод
       
        SIM800.println("AT+CMGS=\"" + n1 + "\"");                   // ...и отправляем полученную команду модему
        delay(500);                                                 // Ждем 0,5 секунд
        SIM800.println(sms1+ "\r\n" + ((char)26));                  // текст смс и После текста отправляем перенос строки и Ctrl+Z
        delay(5000);                                                // Ждем 5 секунд

      
}
    
//Контроль питания отсутствие
   
  if (digitalRead(6)==LOW && flag3==0) {
    flag3++;
   
    SIM800.println("AT+CMGS=\"" + n1 + "\"");                       // ...и отправляем полученную команду модему
    delay(500); // Ждем 0,5 секунд
    SIM800.println(sms2+ "\r\n" + ((char)26));                      // текст смс и После текста отправляем перенос строки и Ctrl+Z
    delay(5000);                                                    // Ждем 5 секунд

   
}

//Контроль питания востановлено
   
  if (digitalRead(6)==HIGH && flag3==1) {
    flag3=0;
    SIM800.println("AT+CMGS=\"" + n1 + "\"");                       // ...и отправляем полученную команду модему
    delay(500); // Ждем 0,5 секунд
    SIM800.println(sms3+ "\r\n" + ((char)26));                      // текст смс и После текста отправляем перенос строки и Ctrl+Z
    delay(5000);                                                    // Ждем 5 секунд

   
}

}

void parseSMS(String msg) {                                        // Парсим SMS
  String msgheader  = "";
  String msgbody    = "";
  

  msg = msg.substring(msg.indexOf("+CMGR: "));
  msgheader = msg.substring(0, msg.indexOf("\r"));                // Выдергиваем телефон

  msgbody = msg.substring(msgheader.length() + 2);
  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) {   // Если телефон в белом списке, то...
    setLedState(msgbody, msgphone);                               // ...выполняем команду
  }
  else {
    Serial.println("Unknown phonenumber");
    SIM800.println("AT+CMGS=\"" + n1 + "\"");                     // ...и отправляем полученную команду модему, отправляет 1 номеру Unknown phonenumber, можно добавить, чтоб номер еще отправлял левый
    delay(1000); // Ждем 1 секунд
    SIM800.println(msgphone + " Unknown phonenumber" + "\r\n" + ((char)26));    // текст смс и После текста отправляем перенос строки и Ctrl+Z
    }
}

void setLedState (String result, String phone) {
  bool correct = false;                                          // Для оптимизации кода, переменная корректности команды
  String msgToSend = "";
  String my_ohr = "";                                            // Переменная для хранения ответа охраны
  String my_power = "";                                          // Переменная для хранения ответа питания
  String my_realy = "";                                          // Переменная для хранения ответа Реле
  String my_realy2 = "";                                         // Переменная для хранения ответа Розетки
  String my_status = "";                                         // Переменная для хранения ответа статуса
  
  //Постановка на охрану
  
  if (result == "On" && digitalRead(10)==LOW && flag1==0 && flag2==0) {
          digitalWrite(3, HIGH);                                 // Исполняем команду
          flag2++;
          delay(2000); // Ждем 1 секунд
          msgToSend = sms0;                                      // Статус исполнения
      
   correct = true;                                               // Флаг корректности команды
 
}
   //Снятие с охраны
   
  if (result == "Off" && flag2==1) {
    flag1=0;
    flag2=0;
    digitalWrite(2, LOW);                                        // выключаем светодиод
    digitalWrite(3, LOW);                                        // выключаем светодиод
    delay(1000); // Ждем 1 секунд
    msgToSend = sms4;                                            // Статус исполнения

 correct = true;                                                 // Флаг корректности команды
 
}

//Включение РЕЛЕ
   
  if (result == "Realy ON" && flag4==0) {
    flag4=1;
    digitalWrite(3, HIGH);                                       // включаем РЕЛЕ
    delay(1000); // Ждем 1 секунд
    msgToSend = sms5;                                            // Статус исполнения

 correct = true;                                                 // Флаг корректности команды
 
}

//Выключение РЕЛЕ
   
  if (result == "Realy OFF" && flag4==1) {
    flag4=0;
    digitalWrite(3, LOW);                                        // вsключаем РЕЛЕ
    delay(1000); // Ждем 1 секунд
    msgToSend = sms6;                                            // Статус исполнения

 correct = true;                                                 // Флаг корректности команды
 
}

//Включение Розетки
   
  if (result == "Realy2 ON" && flag5==0) {
    flag5=1;
    digitalWrite(7, HIGH);                                     // включаем РЕЛЕ
    delay(1000); // Ждем 1 секунд
    msgToSend = sms7;                                          // Статус исполнения

 correct = true;                                               // Флаг корректности команды
 
}

//Выключение Розетки
   
  if (result == "Realy2 OFF" && flag5==1) {
    flag5=0;
    digitalWrite(7, LOW);                                      // вsключаем РЕЛЕ
    delay(1000); // Ждем 1 секунд
    msgToSend = sms8;                                          // Статус исполнения

 correct = true;                                               // Флаг корректности команды
 
}

//Статус
   
  if (result == "Status") {
    if (flag2==1 && digitalRead(2)==HIGH){
    my_ohr = "Pod Ohranoi";                                                    //Статус на охране
    }
    if (flag2==0 && flag1==0 && digitalRead(2)==LOW && digitalRead(3)==LOW) {
    my_ohr = "Snyto";                                                          //Статус снят с охраны
    }
    if (flag2==1 && flag1==1 && digitalRead(2)==LOW && digitalRead(3)==HIGH) {
    my_ohr = "Srabotka";                                                       // Статус сработки
    }
    if (flag3==0) {
    my_power = "+12Volt Ready";                                                // Статус наличия питания 12 вольт
    }
    if (flag3==1) {
    my_power = "+12Volt Warning";                                              // Статус отсутствия питания 12 вольт
    }
    if (flag4==1 && digitalRead(7)==HIGH) {
    my_realy = "Realy ON";                                                     // Статус включеного РЕЛЕ
    }
    if (flag4==0 && digitalRead(7)==LOW) {
    my_realy = "Realy OFF";                                                    // Статус отключеного РЕЛЕ
    }
    if (flag5==1 && digitalRead(7)==HIGH) {
    my_realy2 = "Realy2 ON";                                                     // Статус включеного РЕЛЕ
    }
    if (flag5==0 && digitalRead(7)==LOW) {
    my_realy2 = "Realy2 OFF";                                                    // Статус отключеного РЕЛЕ
    }
        
   msgToSend = (my_ohr + "\r\n" + my_power + "\r\n" + my_realy + "\r\n" + my_realy2);               // Статус исполнения

 correct = true;                                                                // Флаг корректности команды
   
}
  
  if (!correct) {
  msgToSend = "Incorrect command: " + result;                                   // Статус исполнения
  }

  //Тут идет проверка номера, если команды отправляет 1 номер, то все в норме, если 2 или 3 и так далее из белого списка, то ответ дублируется 1 номеру + номер того, кто производит запросы
  if (msgphone == "+77051314021"){
  SIM800.println("AT+CMGS=\"" + msgphone + "\"");                               // ...и отправляем полученную команду модему
  delay(500); // Ждем 0,5 секунд
  SIM800.println(msgToSend + "\r\n" + ((char)26));                              // текст смс и После текста отправляем перенос строки и Ctrl+Z
  Serial.println("1 uslovie" + msgphone + msgToSend + "\r\n" + ((char)26));
  }

  
  else
  {
  SIM800.println("AT+CMGS=\"" + msgphone + "\"");                              // ...и отправляем полученную команду модему
  delay(500); // Ждем 0,5 секунд
  SIM800.println(msgToSend+ "\r\n" + ((char)26));                              // текст смс и После текста отправляем перенос строки и Ctrl+Z
  delay(5000); // Ждем 5 секунд
 
  SIM800.println("AT+CMGS=\"" + n1 + "\"");                                    // ...и отправляем полученную команду модему
  delay(500); // Ждем 0,5 секунд
  SIM800.println(msgphone + " " + msgToSend + "\r\n" + ((char)26));            // текст смс и После текста отправляем перенос строки и Ctrl+Z
  delay(1000); // Ждем 1 секунд
  Serial.println("2 uslovie" + msgphone + msgToSend + "\r\n" + ((char)26));
  }

}


 

vvadim
Offline
Зарегистрирован: 23.05.2012

restiv, а нафига вы всю программу забили делеями, как то не совсем кошерно....

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Уважаемый, я не увидел никаких проблем в указанном Вами диапазоне, да и в других тоже. Порадовал Ваш пессимизм в 88 строке, что контроллер ни разу за 2 часа не увидит эту строку :)

Оставьте на ночь вывод на порт - херня какая-то.

restiv
Offline
Зарегистрирован: 03.01.2016

vvadim пишет:

restiv, а нафига вы всю программу забили делеями, как то не совсем кошерно....

Vvadim к сожалению в написании скетчей я еще очень далек от совершентсва, поэтому пока беру чужие скетчи и переделываю под себя. Так что по делеям - это не я забил.(((

restiv
Offline
Зарегистрирован: 03.01.2016

mykaida пишет:

Уважаемый, я не увидел никаких проблем в указанном Вами диапазоне, да и в других тоже. Порадовал Ваш пессимизм в 88 строке, что контроллер ни разу за 2 часа не увидит эту строку :)

Оставьте на ночь вывод на порт - херня какая-то.

Не совсем понял ваши слова насчет 88 строки. Поставлю на день вывод на порт. Понаблюдаю.

restiv
Offline
Зарегистрирован: 03.01.2016

Сократил временной интервал до 1 минуты. И наблюдал в монитр порте. Никаких намеков на отработку данного кусочка программы не было.