Sim800, функция отправляет только одну смс

Добрый день! Написал программу контроллеру отправки смс в дополнение к основной сигнализации, судя по сообщениям в мониторе порта вроде работает как задумано, но библиотечная функция GSM.sendSms(number,START_GSM) отправляет смс только один раз как у меня в setup при старте. Потом на шлейфы не реагирует, в чем может быть проблема ?


#include <MsTimer2.h>       // библиотека прерывание по таймеру
#include <Button.h>         // библиотека для кнопки
#include <Sim800L.h>        // библиотека модуля GSM связи
#include <SoftwareSerial.h> // софтверный сериал              

// ---------- ПОДКЛЮЧЕНИЯ ----------------------------------

#define SHLEIF_1_PIN A0     // шлейф 1
#define SHLEIF_2_PIN A1     // шлейф 2
#define SHLEIF_3_PIN A2     // шлейф 3
#define LED_RED       4     // светодиод, горит - на охране, не горит - снят с охраны
#define BUTTON_PIN    2     // кнопка переключения режимов
#define RX  8               // sim800
#define TX  9               // sim800

// ---------- НАСТРОЙКИ ----------------------------------

#define PAUSE      35000    // задержка чтобы выйти (или успеть отключить сигнл.), первое число секунды
#define PERIOD_SMS 60000    // 1 минута, частота повторных отправок смс 
#define SHLEYF_MIN 8.8      // минимальное напряжение шлейфа для тревоги
#define SHLEYF_MAX 12.8     // максимальное напряжение шлейфа для тревоги
#define VREF 4.9            // точное напряжение на пине 5V (в данном случае зависит от стабилизатора на плате Arduino)
#define DIV_R1 10000        // точное значение 10 кОм резистора
#define DIV_R2 4700         // точное значение 4.7 кОм резистора

// ---------- ОБЬЕКТЫ ----------------------------------

Button butt(BUTTON_PIN, 15);
Sim800L GSM(RX, TX);

// ---------- ПЕРЕМЕННЫЕ ----------------------------------

char number[]     = "***";                // номер для отправки смс
char START_GSM[]  = "GSM active!";        // текст при подаче питания
char SHLEYF_1[]   = "Srabotka SHLEYF_1";  // текст при сработке шлейфа 1
char SHLEYF_2[]   = "Srabotka SHLEYF_2";  // текст при сработке шлейфа 1
char SHLEYF_3[]   = "Srabotka SHLEYF_3";  // текст при сработке шлейфа 1

bool mode = 0;              // при старте 0 (не активно), 1 (активно)

bool flag_shleif_sms1 = 0;  // флаг регистрации состояния шлейфа "0" - не сработал, "1" сработал
bool flag_shleif_sms2 = 0;  // флаг регистрации состояния шлейфа "0" - не сработал, "1" сработал
bool flag_shleif_sms3 = 0;  // флаг регистрации состояния шлейфа "0" - не сработал, "1" сработал

bool flag_shleif_set1 = 0;  // флаг отсчёта 30 минут для повторной активации шлейфа, "0" прошло, "1" не прошло
bool flag_shleif_set2 = 0;  // флаг отсчёта 30 минут для повторной активации шлейфа, "0" прошло, "1" не прошло
bool flag_shleif_set3 = 0;  // флаг отсчёта 30 минут для повторной активации шлейфа, "0" прошло, "1" не прошло

bool flag_out = 0;          // флаг 1 - ушли, 0 - в доме 

uint32_t timer_period_sms1; // таймер задержки на уход, и деактивацию
uint32_t timer_period_sms2; // таймер задержки на уход, и деактивацию
uint32_t timer_period_sms3; // таймер задержки на уход, и деактивацию

uint32_t timer_pause1;      // таймер частоты отправки смс
uint32_t timer_pause2;      // таймер частоты отправки смс
uint32_t timer_pause3;      // таймер частоты отправки смс

uint32_t timer_for_out;     // таймер задержка при уходе

float voltageShleyf1;        // напряжение шлейфа 1
float voltageShleyf2;        // напряжение шлейфа 2
float voltageShleyf3;        // напряжение шлейфа 3

// ---------- ИНИЦИАЛИЗАЦИЯ ----------------------------------

void setup()
{
	GSM.begin(9600);
  delay(10000);
  GSM.sendSms(number,START_GSM); // смс о запуске GSM
  Serial.begin(9600);
  Serial.println("Питание подали");
  pinMode(LED_RED, OUTPUT);
  MsTimer2::set(2, timerInterrupt);
  MsTimer2::start();
}

void loop()
{
// ---------- ОБРАБОТКА ЗАДЕРЖКИ ПРИ УХОДЕ ----------------------------------

    if (mode == true) // ЕСЛИ РЕЖИМ АКТИВ
    {
      if (flag_out == 0) // еще в помещении
      {
        Serial.println("Задержка чтобы выйти началась!");
        timer_for_out = millis();
        while ((millis() - timer_for_out) < PAUSE)
        {
        }
        flag_out = 1; // считаем что вышли
        Serial.println("Задержка чтобы выйти закончилась!");
      }
      
// ---------- ОБРАБОТКА ШЛЕЙФОВ ----------------------------------

      if ((flag_shleif_sms1 == false) && (flag_shleif_set1 == false)) // 1 --------------------------------
      {
        uint16_t avarageShleyf1 = 0;
        for (byte i = 0; i < 50; i++)
        { avarageShleyf1 += analogRead(SHLEIF_1_PIN); }
        avarageShleyf1 /= 50;
        voltageShleyf1 = (float)avarageShleyf1 * VREF * ((DIV_R1 + DIV_R2) / DIV_R2) / 1024;
        if ((voltageShleyf1 > SHLEYF_MAX) || (voltageShleyf1 < SHLEYF_MIN))
        {
          flag_shleif_sms1 = true;
          timer_period_sms1 = millis();
          Serial.println("Шлейф 1 сработал!");
        } 
      }

       if ((flag_shleif_sms2 == false) && (flag_shleif_set2 == false)) // 2 --------------------------------
      {
        uint16_t avarageShleyf2 = 0;
        for (byte i = 0; i < 50; i++)
        { avarageShleyf2 += analogRead(SHLEIF_2_PIN); }
        avarageShleyf2 /= 50;
        voltageShleyf2 = (float)avarageShleyf2 * VREF * ((DIV_R1 + DIV_R2) / DIV_R2) / 1024;
        if ((voltageShleyf2 > SHLEYF_MAX) || (voltageShleyf2 < SHLEYF_MIN))
        {
          flag_shleif_sms2 = true;
          timer_period_sms2 = millis();
          Serial.println("Шлейф 2 сработал!");
        } 
      }

// ---------- ОБРАБОТКА СМС, ФЛАГОВ, ЗАДЕРЖЕК (шлейф 1) ------------------------------

       if (flag_shleif_sms1 == true)
       {         
          if ((millis() - timer_period_sms1) >= PAUSE)    // проверка на пройденное время 35 секунд после срабатывания
          {
            GSM.sendSms(number,SHLEYF_1);                 // смс о запуске GSM
            Serial.println("Шлейф 1 - отправка смс!"); 
            flag_shleif_sms1 = false;
            flag_shleif_set1 = true;
            timer_pause1 = millis();
          }
        }

        if (flag_shleif_set1 == true)
        {
          if (millis() - timer_pause1 >= PERIOD_SMS)      // проверка на пройденное время 30 минут после отправки смс по шлейфу "n"
          {
            flag_shleif_set1 = false;
            Serial.println("Проверка шлейфа 1 активна!");   // send SMS
          }
        }
// ---------- ОБРАБОТКА СМС, ФЛАГОВ, ЗАДЕРЖЕК (шлейф 2) ------------------------------

       if (flag_shleif_sms2 == true)
       {         
          if (millis() - timer_period_sms2 >= PAUSE)    // проверка на пройденное время 35 секунд после срабатывания
          {
            GSM.sendSms(number,SHLEYF_2);               // смс о запуске GSM
            Serial.println("Шлейф 2 - отправка смс!"); 
            flag_shleif_sms2 = false;
            flag_shleif_set2 = true;
            timer_pause2 = millis();
          }
        }

        if (flag_shleif_set2 == true)
        {
          if (millis() - timer_pause2 >= PERIOD_SMS)      // проверка на пройденное время 30 минут после отправки смс по шлейфу "n"
          {
            flag_shleif_set2 = false;
            Serial.println("Проверка шлейфа 2 активна!"); // send SMS
          }
        }
    }
// ---------- ОБРАБОТКА СМС, ФЛАГОВ, ЗАДЕРЖЕК (шлейф 3, пожарный) ------------------------------

    else if (mode == false)
    {
      flag_shleif_sms1 = false; // готовность отправки смс для отправки смс
      flag_shleif_sms2 = false; // готовность отправки смс для отправки смс

      flag_shleif_set1 = false; // флаг отсчёта 30 минут для повторной активации шлейфа, "0" прошло, "1" не прошло
      flag_shleif_set2 = false; // флаг отсчёта 30 минут для повторной активации шлейфа, "0" прошло, "1" не прошло
      if (flag_out == true) Serial.println("Вы успели отключить охрану!");
      flag_out = false;
    }

    if ((flag_shleif_sms3 == false) && (flag_shleif_set3 == false))
    {
      uint16_t avarageShleyf3 = 0;
      for (byte i = 0; i < 50; i++)
      { avarageShleyf3 += analogRead(SHLEIF_3_PIN); }
      avarageShleyf3 /= 50;
      voltageShleyf3 = (float)avarageShleyf3 * VREF * ((DIV_R1 + DIV_R2) / DIV_R2) / 1024;
      if ((voltageShleyf3 > SHLEYF_MAX) || (voltageShleyf3 < SHLEYF_MIN))
      {  
        flag_shleif_sms3 = true;
        timer_period_sms3 = millis();
        Serial.println("Шлейф 3 сработал!");
      } 
    }

    if (flag_shleif_sms3 == true)
       {         
          if (millis() - timer_period_sms3 >= 1000)    // проверка на пройденное время 1 секунда после срабатывания
          {
            GSM.sendSms(number,SHLEYF_3); // смс о запуске GSM
            Serial.println("Шлейф 3 - отправка смс!"); 
            flag_shleif_sms3 = false;
            flag_shleif_set3 = true;
            timer_pause3 = millis();
          }
        }

        if (flag_shleif_set3 == true)
        {
          if (millis() - timer_pause3 >= PERIOD_SMS)      // проверка на пройденное время 30 минут после отправки смс по шлейфу "n"
          {
            flag_shleif_set3 = false;
            Serial.println("Проверка шлейфа 3 активна!"); // send SMS
          }
        }
  }

void timerInterrupt()
{
  butt.scanState();              // опрос кнопки
  if (butt.flagClick == true)
  {
    butt.flagClick = false;
    mode =! mode;
    digitalWrite (LED_RED, mode);
  }
}  

Как написано, так и работает. Прям на все деньги.

1 лайк

Ну это очень ценная информация в решении проблемы :grinning:

Мысль верная, только запятой после “ну” не хватает :frowning:

Ну “,” если просмотрели тему, не подскажете новичку ?

Да, я бы, может, и подсказал, только сам же и окажусь мудаком - не впервой, каждый раз одно и то же. Надоело и настроение не то.

Как любят наши новички выражаться (в смысле, требовать этого): “не могу или не хочу помочь, так прохожу мимо и не гажу в теме” :slight_smile:

Хотя бы в какую сторону думать? Библиотека, алгоритм ? Ведь модуль точно работает, а потом обе команды и на отправку смс, и на вывод в порт идут подряд, почему только вывод в порт работает…

А подскажите по логике.
Вот у вас сработал шлейф - после этого вы ждете 35 секунд, прежде чем отправить СМС. Зачем?
Добро бы вы в эти секунды проверяли сигнал со шлейфа - вдруг он вернется в норму и это будет означать ложное срабатывание. Но вы же ничего не проверяете. Так нафига ждать?

И дадее - после отправки СМС вы ждете 30 минут!, прежде чем включить активный режим обратно. Размер этой паузы как определялся?

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

А не лень было три одинаковых кода набивать? Почему не положить все переменные трех датчиков и все задержки для них в массив и не упростить код в три раза?

Скажу честно - я не вижу, почему у вас СМС не посылается вторично. И потому считаю, что нужно упрощать код, убирать все повторы, переписывать кривые места.

Можете привести пример кода ? Не совсем понял как все это упростить… Вот проходил урок по написанию классов, могу попробовать применить, по идее кода будет меньше.

не нужны никакие классы, все гораздо проще.

на примере обработки шлейфа

bool flag_shleif_sms[3] = {0};
bool flag_shleif_set[3] = {0};
byte SHLEIF_PIN[3] = {2, 3, 6};

for (byte i=0; i<3; i++) {
 if ((flag_shleif_sms[i] == false) && (flag_shleif_set[i] == false)) 
      {
        uint16_t avarageShleyf = 0;
        for (byte i = 0; i < 50; i++)
        { avarageShleyf += analogRead(SHLEIF_PIN[i]); }
        avarageShleyf /= 50;
        voltageShleyf = (float)avarageShleyf * VREF * ((DIV_R1 + DIV_R2) / DIV_R2) / 1024;
        if ((voltageShleyf > SHLEYF_MAX) || (voltageShleyf < SHLEYF_MIN))
        {
          flag_shleif_sms[i] = true;
          timer_period_sms[i] = millis();
          Serial.print("Шлейф ");
         Serial.print(i);
         Serial.println(" сработал!");
        } 
      }
}

Добавка:
На всякий случай поясню - этот цикл заменяет снятие данных сразу с трех шлейфов

1 лайк

Я не работал с SIM800, только интересовался, так что общие соображения, не учитывающие особенности SIM800.

Если предположить, что Sim800L.h принадлежит безглючной , надежной библиотеке и вызывать надо именно так, то отличия между первым и последующими вызовами сводится к запуску обработки прерываний от второго таймера. Отмените временно запуск прерываний таймера 2. (результат в коде все рано не используется). Но скорее всего это не повлияет.

Второе предположение. Возможно в буфере serial остаются символы от предыдущих ответов SIM800. Я не увидел в библиотеке Sim800L функции для очистки буфера, можно попробовать добавить очистку в начало функции sendSms.

Общее замечание, те примеры, что я видел, не использовали библиотеку, а использовали отправку AT команд, с разным уровнем анализа ответов модуля. В вашем коде вообще не проверяется результат команд.

2 лайка

Спасибо огромное! Получилось, помогла очистка буфера перед каждой последующей отправкой смс.

while (GSM.available()!=0) 
            {
              GSM.read();
            }