Борьба с зависанием GSM модуля

Тема в разделе "Arduino & Shields", создана пользователем nationalist, 20 июл 2017.

  1. nationalist

    nationalist Нуб

    Доброго дня всем! Соорудил из gsm модуля и ардуинки сигнализацию в авто. Все работает. Но через пару недель вдруг подвис GSM модуль и перестал слать оповещения. Сама дуина отрабатывала при этом на ура - ставила/снимала с охраны, работал светодиод-индикатор.
    Вот я и задумался - как реализовать периодический контроль работоспособности GMS модуля? и в случае зависания - хотя бы оповещать меня. Ну или перезагружать модуль?
    Подскажите как это сделать красиво? ))
     
  2. что за модуль?
     
  3. nationalist

    nationalist Нуб

    Модуль SIM900 в виде шилда. Включается и выключается подачей "1" на 9 пин.
     
  4. Airbus

    Airbus Радиохулиган Модератор

    Можно посылать ему АТ каждые 5 минут к примеру и если он не ответит ОК релюхой подключенной к ардуине вырубать его и снова включать через минуту.Это первое что пришло на ум хотя все сложнее у меня например на старлайне ГСМ модуль после перезагрузки и чистки ластиком контактов СИМ рпботает пару дней а потом опять глючит.Тут надо причину искать.И хорошо если дело в Сети а если в модуле?Тут только выкинуть и заменить.
     
  5. nationalist

    nationalist Нуб

    Да, я тоже так думаю. Это первое, что приходит на ум.
    Единственное, я затрудняюсь реализовать код. Еще пока на Вы с программированием.
    Не знаю, как правильно сделать так, чтобы дуина поняла, что он не ответил на команду.
     
  6. Radius

    Radius Гик

    Мы в своих устройствах принудительно раз в сутки делаем рестарт GSM-модуля, но у нас не охранная система. Для охранной системы действительно нужно периодически опрашивать модуль и в случае отсутствия ответа делать ему RESET.
     
  7. nationalist

    nationalist Нуб

    Да, чем проще, тем лучше. Пожалуй, сделаю принудительную перезагрузку раз в сутки. 10-15 секунд перезагрузки погоды не сделают.
    Только кто подскажет, может ли SIM900 зависнуть так, что не будет реагировать на сигналы включения/выключения?
    Дело в том, что тупо рубить питание ему не получится - устройство собрано. Вмешиваться можно только в код. Во второй версии устройства я предусмотрю такую функцию.
     
  8. Airbus

    Airbus Радиохулиган Модератор

    Есть идеи?Если что поправим....
     
  9. nationalist

    nationalist Нуб

    Ну вот если проверять работоспособность модуля, то я родил вот такую функцию, которую нужно вызывать периодически.
    Код (C++):

    void TestGsm(){
      gprsSerial.println("AT");  //отправляем модулю команду АТ
      bool out = true; // переменная для выхода из цикла
      static unsigned long previousMillis=0; // предыдущее время в миллисекундах
      previousMillis=millis();
      while(out){ //начинаем цикл ожидания ответа  
        if(millis()-previousMillis>=3000){ // если ответа нет 3 секунды    
          // РЕСТАРТИМ GSM МОДУЛЬ
          out = false; //выходим из цикла while
        }
        if (gprsSerial.available()){    // если в буфере есть что-то      
          while (gprsSerial.available()){  // начинаем считывать в цикле, пока что-то есть в буфере  
            char currSymb = gprsSerial.read();    
            if ('\r' == currSymb) { // когда получен символ окончания строки, парсим строку:      
              if (!currStr.compareTo("OK")){ // если модуль ответил "ОК", просто выходим из цикла проверки
                out = false; //выходим из цикла while
              }
              currStr = ""; // обнуляем полученную строку
            }else if ('\n' != currSymb) { // Пока не получим символ окончания строки, собираем строку
              currStr += String(currSymb); // переменная currStr уже объявлена в начале программы
            }
          }
        }
      }
    }
     
    Поправьте, может ошибся где?
     
    Последнее редактирование: 22 июл 2017
    Alba нравится это.
  10. Alba

    Alba Нерд

    Правильно ли я его прикрутил?

    Код (C++):
    #include <SoftwareSerial.h>

    SoftwareSerial gprsSerial(7, 8);
    int nasos1Pin = 2;
    int nasos2Pin = 3;
    int power = 9 ;
    void setup()
    {
        gprsSerial.begin(19200);
        pinMode(nasos1Pin, OUTPUT);
        pinMode(nasos2Pin, OUTPUT);
        pinMode(power, OUTPUT);
        digitalWrite(power,HIGH); //подали питание
    delay(3000); //на 3 сек
    digitalWrite(power,LOW); //сняли питание
        // Настраиваем приём сообщений с других устройств
        // Между командами даём время на их обработку
        gprsSerial.print("AT+CMGF=1\r");
        delay(300);
        gprsSerial.print("AT+IFC=1, 1\r");
        delay(300);
        gprsSerial.print("AT+CPBS=\"SM\"\r");
        delay(300);
        gprsSerial.print("AT+CNMI=1,2,2,1,0\r");
        delay(500);
    }
    String currStr = "";
    // Переменная принимает значение True, если текущая строка является сообщением
    boolean isStringMessage = false;

    void TestGsm(){
      gprsSerial.println("AT");  //отправляем модулю команду АТ
      bool out = true; // переменная для выхода из цикла
      static unsigned long previousMillis=0; // предыдущее время в миллисекундах
      previousMillis=millis();
      while(out){ //начинаем цикл ожидания ответа  
        if(millis()-previousMillis>=3000){ // если ответа нет 3 секунды    
          // РЕСТАРТИМ GSM МОДУЛЬ
          out = false; //выходим из цикла while
        }
        if (gprsSerial.available()){    // если в буфере есть что-то      
          while (gprsSerial.available()){  // начинаем считывать в цикле, пока что-то есть в буфере  
            char currSymb = gprsSerial.read();    
            if ('\r' == currSymb) { // когда получен символ окончания строки, парсим строку:      
              if (!currStr.compareTo("OK")){ // если модуль ответил "ОК", просто выходим из цикла проверки
                out = false; //выходим из цикла while
              }
              currStr = ""; // обнуляем полученную строку
            }else if ('\n' != currSymb) { // Пока не получим символ окончания строки, собираем строку
              currStr += String(currSymb); // переменная currStr уже объявлена в начале программы
            }
          }
        }
      }
    }
    void loop()
    {
        if (!gprsSerial.available())
            return;
        char currSymb = gprsSerial.read();  
        if ('\r' == currSymb) {
            if (isStringMessage) {
                //если текущая строка - SMS-сообщение,
                //отреагируем на него соответствующим образом
                if (!currStr.compareTo("Nasos1 on")) {
                    digitalWrite(nasos1Pin, HIGH);
                } else if (!currStr.compareTo("Nasos1 off")) {
                    digitalWrite(nasos1Pin, LOW);
                } else if (!currStr.compareTo("Nasos2 on")) {
                    digitalWrite(nasos2Pin, HIGH);
                } else if (!currStr.compareTo("Nasos2 off")) {
                    digitalWrite(nasos2Pin, LOW);
                }
                isStringMessage = false;
            } else {
                if (currStr.startsWith("+CMT")) {
                    //если текущая строка начинается с "+CMT",
                    //то следующая строка является сообщением
                    isStringMessage = true;
                }
            }
            currStr = "";
        } else if ('\n' != currSymb) {
            currStr += String(currSymb);
        }
    }
     
  11. Alba

    Alba Нерд

    Не могу разобраться как прикрутить подъём трубки через 3 сек