Сигнализация с герконом

Тема в разделе "Arduino & Shields", создана пользователем kryptonix_ar, 27 апр 2019.

  1. kryptonix_ar

    kryptonix_ar Нуб

    Здравствуйте, переделывала скетч с сайта для сигнализации с датчиком открытия дверей герконом. Возникла небольшая проблема. Всё работает, но смс о состоянии датчика приходят слишком часто.
    При использовании задержки delay() программа работала не корректно.Подскажите как можно решить эту проблему в цикле, чтобы оповещения приходили только при изменении состояния датчика.
    http://codius.ru/articles/GSM_модуль_SIM800L_часть_2

    Код (C++):
    #include <SoftwareSerial.h>                     // Библиотека программной реализации обмена по UART-протоколу
    SoftwareSerial SIM800(8, 9);                    // RX, TX
    #define Gerkon_Pin 3
    #define Door_Led_Pin 13
    String _response = "";                          // Переменная для хранения ответа модуля
    void setup() {
      Serial.begin(9600);                           // Скорость обмена данными с компьютером
      SIM800.begin(9600);                           // Скорость обмена данными с модемом
      Serial.println("Start!");

      sendATCommand("AT", true);                    // Отправили AT для настройки скорости обмена данными
    pinMode(Gerkon_Pin, INPUT); // установить Door_Sensor_Pin как вход
    pinMode(Door_Led_Pin, OUTPUT); // установить Door_Led_Pin как выход
      _response = sendATCommand("AT+CMGF=1;&W", true); // Включаем текстовый режима SMS (Text mode) и сразу сохраняем значение (AT&W)!

    }

    String sendATCommand(String cmd, bool waiting) {
      String _resp = "";                            // Переменная для хранения результата
      Serial.println(cmd);                          // Дублируем команду в монитор порта
      SIM800.println(cmd);                          // Отправляем команду модулю
      if (waiting) {                                // Если необходимо дождаться ответа...
        _resp = waitResponse();                     // ... ждем, когда будет передан ответ
       
        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;                                 // ... возвращаем результат. Пусто, если проблема
    }

    void loop() {
      if (digitalRead(3) == LOW) {   // проблема в этом блоке

    sendSMS("+38*********", "THE DOOR IS OPEN");
    }
    if (digitalRead(3) == HIGH){
     
    sendSMS("+38********", "THE DOOR IS CLOSE");
    }
    else{
      digitalWrite(Door_Led_Pin, HIGH);// проблема в этом блоке
     
      if (SIM800.available())   {                   // Если модем, что-то отправил...
        _response = waitResponse();                 // Получаем ответ от модема для анализа
        _response.trim();                           // Убираем лишние пробелы в начале и конце
        Serial.println(_response);                  // Если нужно выводим в монитор порта
        //....
        if (_response.startsWith("+CMGS:")) {       // Пришло сообщение об отправке SMS
          int index = _response.lastIndexOf("\r\n");// Находим последний перенос строки, перед статусом
          String result = _response.substring(index + 2, _response.length()); // Получаем статус
          result.trim();                            // Убираем пробельные символы в начале/конце

          if (result == "OK") {                     // Если результат ОК - все нормально
            Serial.println ("Message was sent. OK");
          }
          else {                                    // Если нет, нужно повторить отправку
            Serial.println ("Message was not sent. Error");
          }
        }
      }
      if (Serial.available())  {                    // Ожидаем команды по Serial...
        SIM800.write(Serial.read());                // ...и отправляем полученную команду модему
      };
    }

    void sendSMS(String phone, String message)
    {
      sendATCommand("AT+CMGS=\"" + phone + "\"", true);             // Переходим в режим ввода текстового сообщения
      sendATCommand(message + "\r\n" + (String)((char)26), true);   // После текста отправляем перенос строки и Ctrl+Z
    }
     
     
  2. ostrov

    ostrov Гуру

    Как с кнопкой. Опрашивается состояние датчика каждые Н сек, например 1. Запоминается предыдущее, сравнивается с текущим. Когда старое HIGH, а новое LOW, это и есть открывание. В других случаях не реагировать.

    О том, что с SIM800 работают не так, сейчас говорить не буду.
     
    kryptonix_ar нравится это.
  3. Airbus

    Airbus Радиохулиган

    Установить флаг в сетупе.При сработке геркона и отправке СМС его сбросить.Чтоб отправлялось один раз.Если надо флаг можно установить или кнопкой или через какое то время с помощью миллис.
     
    カオナシ, kryptonix_ar и Daniil нравится это.