Sim800l и ардуино перестает принимать и отправлять смс

Еще раз. Перейдите на передачу строк по ссылке в и из функций. У вас временный обьект строки при передаче параметра и при возврате значения ставит барьер в кучу, который провоцирует сегментацию.

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

Смски не копятся,удаляются сразу плюс стоит програмное отключение сим модуля раз в час.
Проблема с стринг.
Буду пробовать переделать на ссылки.

Так заставьте работать. Это же Ваша отладочная информация. Что за ошибка? Показывайте код и текст ошибки.


Так сделал.Ждемс

монитор протри.

А ещё так миленько номер замазал. Настоящий секретчик! А то что выше в скетче открыто лежит - враг не догадается :grinning_face:

Да, в скетче забыл удалить.Переживу.
Как неуловимый Джо.(никому не нужен)
Чувство юмора и хорошее настроение это здорово,хотелось бы по делу чего-нибудь почитать.
Все равно спасибо.

Ждите-с дальше.

Если хотите помощи, то я Вас просил выложить код и текст сообщения об ошибке компиляции. Пока этого нет, можете ждать-с!

Как Вы изволили выразиться:

а не весёлых картинок.

Добрый день.ошибки сейчас нет.
Изменения сохранил,скомпелировалось норм.
Вместо слова “беда” я “попросил” прислать мне СМС.
Не знаю пришлёт или нет.
Месяц смотреть в монитор порта нет возможности.
Как я уже писал,ардуинка продолжает работать и может отправлять смс(адекватно,согласно программе)
Но не может их(смс) обрабатывать тоесть
Достать текст и отреагировать на него,при этом в монитор порта пишет о приходе смс

Который день ошибок нет,
Внёс изменения - всё в порядке,
Скомпоновалось в чудесный свет,
Но в коде есть ещё загадки.

Когда"беда" должна настать,
Прислать мне должно эсемеску,
Но месяц мне ответа ждать
Возможности и вовсе нету.

Как я уже писал - всё хорошо:
Работает и отправляет,
Но обработать смс -
Откликнутся он не желает.

А в мониторе - всё ОК,
И потому вопрос извечный,
Что мне поделать поскорей,
Во избежания мыслей вечных.

Дааа, совсем нет навыка отладки.
Делаете свой класс с теми же самыми функциями, что и у sim800. Прием из эфира эмулируете через последовательный порт. Отправку в эфир тоже через него. Подменяете класс сим800 на свой. Запускаете и начинаете “радиообмен” используя данные из файла. Ошибку словите, если она есть, через 5 минут. Уберете delay (для эмуляции ждать радиообмена не надо), цикл отладки будет занимать секунды.

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

Обычно для диагностики факт ошибки пишется в епром. Причем пишется только первая ошибка из каждого подмножества ошибок. Подробно: время, сопутствующие параметры. Далее либо периодически, либо по запросу, либо при личном визите протокол ошибок добывается наружу.
Причем процедуры протоколирования и выдачи данных наружу должны быть реализованы без использования динамической памяти и прочих “заканчивающихся” ресурсов, т.е. работать всегда, как бы плохо устройству ни было. И обычно сначала реализуется диагностическая часть программы, а потом в устройство по одной добавляются функции. Так вы всегда имеете представление о том что происходит и ловите ошибку в момент ее появления в коде, а не когда их появилось много и вы из-за глюков перестали понимать что происходит.

Снимаю шляпу.
Здорово

Спасибо.Навыка нет ибо я не программист,но сдаться ка и уср…ся никогда не поздно .
Можно сравнительно недорого заказать у профессионалов (коих тут много)готовый код по моим хотелкам и ,учитывая стоимость времени, потраченного мною на сию затею,возможно будет более рационально и гарантировано качественно и значительно быстрее.Тогда это будет “победа железяки”.
Сей исход меня не устраивает.
Спасибо всем за любую помощь и потраченное на меня время

Добрый день.ардуины (2штуки пробовал)
Перестали обрабатывать и реагировать на смс вообще.код выполняется,смс получает,читает(видно из монитора порта),при аварии сети отправляет смс об аварии.но на команды не реагирует.
Код не менял.раньше работало.(пусть и не слишком долго)может в них есть какой-то органичный ресурс?буду рад любым версиям.Спасибо

Что такое “команды”? Откуда поступает воздействие и какая должна быть исполнительная активность на них?

Это ж при каких условиях произойдёт?

if (lastUpdate + updatePeriod < millis() )

И нет ли бяды от лишней ;

 if (Serial.available()) {      // Ожидаем команды по Serial
    SIM800.write(Serial.read()); //и отправляем полученную команду модему
  };

Пери переполнении millis()

Ненуачё, кто-то борется с переполнением, а тут человек его использует :slight_smile:

#include <DHT11.h>
#include "SoftwareSerial.h"
#include <OneWire.h>
#define POWER_MODE  0
OneWire sensDs (A0); 
DHT11 dht11(15);
SoftwareSerial SIM800(2, 3); //программные RX, TX для связи с модулем SIM800L
unsigned long tpr1, tpr2, tpr4, tdi, ttemp, tsim, timeout, talt, talv, lastUpdate;// Перемен. для хранения точки отсчета для таймеров
int j = 0, k = 0, x2 = 20,wt = 1,wv = 1, t_1 = 0,  humidity = 0,temperature = 0, p8 = 11;
//String _response = "";                          // Переменная для хранения ответа модуля

String phones = "+79775645109, +79773874353"; //Список разрешенных номеров
                   //номера вписываются в международном формате начиная с +

String waitResponse() {                  // Функция ожидания ответа и возврата полученного результата
  String _resp = "";                     // Переменная для хранения результата
  timeout = millis();      // Переменная для отслеживания тайм аута (10 секунд)
  while (!SIM800.available() && millis() - timeout < 10000) {};// Ждем ответа 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);  // Дублируем ответ в Serial
  } 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.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) { // Если телефон в белом списке, то
    if (msgbody == "Pr0") {
      j = 0;
      digitalWrite(12, HIGH);//программа 0
    }
    if (msgbody == "Pr1") {
      j = 1;
      digitalWrite(12, HIGH);//программа 1
    }
    if (msgbody == "Pr2") {
      j = 2;
      digitalWrite(12, HIGH);//программа 2
    }
    if (msgbody == "Pr3") {
      j = 3;//программа 3
    }
    if (msgbody == "Pr20") {
      j = 20;
      digitalWrite(12, HIGH);//программа 4
    }
    if (msgbody == "Ktr") {
      k = 1;
      }                    //запрос данных котла
    if (msgbody == "Klx2+") {
      x2 = x2 + 3;             //повышение заданной температуры на 3 градуса
    }
    if (msgbody == "Klx2-") {
      x2 = x2 - 3;             //понижение заданной температуры на 3 градуса
    }
     if (msgbody == "Alt-of") {
      wt = 0;                   //отключение оповещения аварии по температуре
    }
        if (msgbody == "Alt-on") {
      wt = 1;                    //включение оповещения аварии по температуре
    }
    if (msgbody == "Alv-of") {
      wv = 0;                   //отключение оповещения аварии по напряжению
    }
        if (msgbody == "Alv-on") {
      wv = 1;                   //включение оповещения аварии по напряжению
    }
  } else {
    Serial.println("Unknown phonenumber");
    sendATCommand("AT+CMGDA=\"DEL ALL\"", true);
  }
}
void setup() {
  pinMode(12, OUTPUT);
  pinMode(p8, OUTPUT);
  digitalWrite(12, HIGH);
  digitalWrite(p8, LOW);
  pinMode(7, 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)!
  lastUpdate = millis();                       // Обнуляем таймер
}
bool hasmsg = false;                           // Флаг наличия сообщений к удалению
void loop() {
  int sensorVal = digitalRead(7);
  int rele=0, v = 0,  msgphone = 0;
  byte bufData[9];  // буфер данных
  if (sensorVal == HIGH) {
    v = 220;              //проверка наличия питания
  } else {
    v = 0;
  }
   if (digitalRead(12) == LOW) {//проверка состояния реле
    rele = 1;
  } else {
    rele = 0; 
    }                       
  if (millis() - ttemp > 44000) {
    ttemp = millis();               //обновление данных датчика температуры теплоносителя
          sensDs.reset();  // сброс шины
  sensDs.write(0xCC, POWER_MODE); // пропуск ROM
  sensDs.write(0x44, POWER_MODE); // инициализация измерения
  delay(6000);  // пауза 0,9 сек
  sensDs.reset();  // сброс шины
  sensDs.write(0xCC, POWER_MODE); // пропуск ROM 
  sensDs.write(0xBE, POWER_MODE); // команда чтения памяти датчика 
  sensDs.read_bytes(bufData, 9);  // чтение памяти датчика, 9 байтов
  if ( OneWire::crc8(bufData, 8) == bufData[8] ) {  // проверка CRC
    // данные правильные
    t_1=  ((int)bufData[0] | (((int)bufData[1]) << 8)) * 0.0625 + 0.03125;     
  }
  else { 
    // ошибка CRC, отображается ----   
  }   
    temperature = dht11.readTemperature();//обновление данных датчика температуры и влажности в помещении
    humidity = dht11.readHumidity();
  
    Serial.print("T1 = "); Serial.print(t_1); Serial.print("*C, ");
    Serial.print("T2 = "); Serial.print(temperature); Serial.print("*C, ");
    Serial.print(humidity); Serial.println("%");
  }
 //  String _response = "";                          // Переменная для хранения ответа модуля
  if (millis()- lastUpdate > 60000 ) {                     // Пора проверить наличие новых сообщений
    String _response = "";                          // Переменная для хранения ответа модуля
    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");  //ошибка
            sendATCommand("\n", true); // Отправляем новую строку и повторяем попытку
          }
        }
        while (i < 10); break;
      } else {
        lastUpdate = millis();         // Обнуляем таймер
        if (hasmsg) {
          sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удаляем все прочитанные сообщения
          hasmsg = false;
        } break;
      }
    } while (1);
  }
  if (SIM800.available()) {     // Если модем, что-то отправил
    String _response = "";                          // Переменная для хранения ответа модуля
    _response = waitResponse(); // Получаем ответ от модема для анализа
    _response.trim();           // Убираем лишние пробелы в начале и конце
    Serial.println(_response);  // Если нужно выводим в монитор порта
    if (_response.indexOf("+CMTI:") > -1) { // Пришло сообщение об отправке SMS
      lastUpdate = millis(); // Теперь нет необходимости обрабатывать SMS здесь, достаточно просто сбросить счетчик авто проверки, и в следующем цикле все будет обработано
    }
  }
  if (Serial.available()) {      // Ожидаем команды по Serial
    SIM800.write(Serial.read()); //и отправляем полученную команду модему
  };
   if (j == 0) { //Программа 0
    digitalWrite(p8, HIGH);
  } else {
    digitalWrite(p8, LOW);
  }
  if (j == 1) { //Программа 1
    if (millis() - tpr1 > 12600000) { 
      tpr1 = millis(); tpr2 = millis();
      digitalWrite(12, LOW);
    }
    if (millis() - tpr2 > 1800000) { 
      digitalWrite(12, HIGH);           //описание работы реле по программе 1
    }
    if (millis() - tdi > 3000) {
      tdi = millis();
      digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); //описание мерцания диода 1 раз
    }
  }
  if (j == 2) { //Программа 2
    if (millis() - tpr1 > 23400000) {  
      tpr1 = millis(); tpr2 = millis(); digitalWrite(12, LOW);
    }
    if (millis() - tpr2 > 1800000) {  
      digitalWrite(12,HIGH);                                   //описание работы реле по программе 2
    }
    if (millis() - tdi > 3000) {
      tdi = millis();
      digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); delay(300);
      digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW);            //описание мерцания диода 2 раза
    }
  }
  if (j == 3) {
    digitalWrite(12, LOW);                                       //описание работы реле по программе 3
    if (millis() - tdi > 3000) {
      tdi = millis();
      digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); delay(300);
      digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); delay(300);
      digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW);               //описание мерцания диода 3 раза
    }
  } 
  if (j == 20) {
  
      if (temperature <= x2) {
        digitalWrite(12, LOW);
      }
      if (temperature > x2) {
        digitalWrite(12, HIGH);                                   //описание работы реле по программе 4
      }
   
    if (millis() - tdi > 3000) {
      tdi = millis();
      digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); delay(300);
      digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); delay(300);
      digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); delay(300);
      digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW);             //описание мерцания диода 4 раза
    }
  }
   if (millis() - tsim > 3600000) { 
      tsim = millis();
      SIM800.println( "AT+CPOWD=1");          //програмная перезагрузка сим модуля на случай сбоя соединения
    }
  if (k == 1) {
 
    SIM800.println( "AT+CMGS=\"+79775645109\""); //номер на который будет приходить SMS отчет
    delay(3000);                                //номер вписывается в международном формате начиная с +
    SIM800.print("T1=");                         //описание содержания смс с данными устройства
    delay(300); SIM800.print(t_1);
    delay(300); SIM800.print("*C, T2=");
    delay(300); SIM800.print(temperature);
    delay(300); SIM800.print("*C, T2-VL=");
    delay(300); SIM800.print(humidity);
    delay(300); SIM800.print("% Pr="); delay(300); SIM800.print(j);
    delay(300); SIM800.print(" t=");
    delay(300); SIM800.print(x2);
    delay(300); SIM800.print(" Set=");
    delay(300); SIM800.print(v);
    delay(300); SIM800.print("volt");
    delay(300); SIM800.print("; Al.t=");
    delay(300); SIM800.print(wt);
    delay(300); SIM800.print("; Al.v=");
    delay(300); SIM800.print(wv);
    delay(300); SIM800.print("; Rele=");
    delay(300); SIM800.print(rele);
    delay(300); SIM800.print((char)26);//команда для отправки SMS
    delay(300); Serial.println("SMS send finish");
  } k = 0;
    if ((millis() - talt > 1800000)&&(t_1<=5)&&(wt == 1)) {//проверка необходимости отправить смс об аварии по температуре теплоносителя
      talt = millis(); 
    delay(300);
     
    SIM800.println( "AT+CMGS=\"+79775645109\""); //номер на который будет приходить SMS отчет
    delay(3000);SIM800.print("T1=");
    delay(300); SIM800.print(t_1);
    delay(300); SIM800.print("ALARM");
   
    delay(300); SIM800.print((char)26);//команда для отправки SMS
    delay(300); Serial.println("SMS send finish");
  } 
    if ((millis() - talv > 1800000)&&(sensorVal == LOW)&&(wv == 1)) {  //проверка необходимости отправить смс об аварии по температуре напряжения питания
      talv = millis(); 
    delay(300);
     
    SIM800.println( "AT+CMGS=\"+79775645109\""); //номер на который будет приходить SMS отчет
  
    delay(300); SIM800.print("Set=ALARM");
   
    delay(300); SIM800.print((char)26);//команда для отправки SMS
    delay(300); Serial.println("SMS send finish");
  } 
}

Вот код.Работал.