Здравствуйте, переделывала скетч с сайта для сигнализации с датчиком открытия дверей герконом. Возникла небольшая проблема. Всё работает, но смс о состоянии датчика приходят слишком часто. При использовании задержки 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 }
Как с кнопкой. Опрашивается состояние датчика каждые Н сек, например 1. Запоминается предыдущее, сравнивается с текущим. Когда старое HIGH, а новое LOW, это и есть открывание. В других случаях не реагировать. О том, что с SIM800 работают не так, сейчас говорить не буду.
Установить флаг в сетупе.При сработке геркона и отправке СМС его сбросить.Чтоб отправлялось один раз.Если надо флаг можно установить или кнопкой или через какое то время с помощью миллис.