Отправка СМС через GSM модуль SIM800L без delay()
- Войдите на сайт для отправки комментариев
При работе с GSM модулем, в моем случае - SIM800L, весь процесс неизбежно делится на сбор/обработку данных и отправку СМС. Все попавшиеся мне примеры с отправкой СМС используют delay() для задержки между последовательно отправляемыми АТ командами. Странно, т.к. при работе с DS18B20 использование delay() является дурным тоном.
Задержек при отправке СМС минимум 3, причем их величина - сотни мсек. Останавливать работу остальных функций на это время - непозволительная роскошь. Поэтому решил использовать класс таймера noDelay, который скопировал в самом начале освоения Ардуины, - респект автору noDelay !
Скетч с демонстрацией работы выкладываю для всеобщей пользы. Пример состоит из четырех файлов:
- основного
// первое СМС отправляется через SMS_INTERVAL после старта программы // остальные - через SMS_INTERVAL после прдыдущего СМС // !!!!!!!!! SIM800L подключен к Serial1 (для Mega2560) // для Uno и др. - используйте библиотеку SoftSerial //------------------------------------------------------------------------------------------------------------- #include "noDelay.h" #define TEST_MODE 1 // режим отладки = 1, рабочий = 0 // используется для отключения вывода в Serial #define SMSSEND_MODE 0 // отправлять СМС = 1, не отправлять = 0 // при 0 - вывод в Serial noDELAY nD_SMSsend; // таймер отправки СМС // для SIM800L const long SMS_INTERVAL = 5000; // мин интервал между СМС, мсек String myPhoneNumber = "+79000000000"; // ИЗМЕНИТЬ НА РЕАЛЬНЫЙ !!!!!!! String SMStext = "My first SMS"; // текст СМС byte SMSpartNumber = 0; // служебная переменная, порядковый номер части СМС boolean flag_SMS_send = true; // флаг отправки СМС //--------------------------------------------------------------------------------------------------- void loop() { if (flag_SMS_send) // проверка флага для отправки СМС if (nD_SMSsend.tick()) // проверка таймера между СМС, // требуется при последовательной отправкенескольких СМС { f_SendSMS(SMStext, myPhoneNumber); } // функция отправки СМС на заданный номер } // end of loop //***************************************************************************************************
- setup(обычно, я выношу его в отдельный файл для удобства восприятия)
//-------------------------------------------------------------------------------------------------------- // SETUP function void setup(void) { Serial.begin(9600); delay(500); #if TEST_MODE Serial.println(" SETUP begin"); delay(50); #endif // настройка SIM800L Serial1.begin(19200); //Скорость порта для связи Arduino с GSM модулем Serial1.println("AT"); delay(300); #if TEST_MODE while (Serial1.available()) Serial.write(Serial1.read()); #endif Serial1.println("AT+CMGF=1"); delay(300); #if TEST_MODE while (Serial1.available()) Serial.write(Serial1.read()); #endif Serial1.println("AT+CSCS=\"GSM\""); delay(300); #if TEST_MODE while (Serial1.available()) Serial.write(Serial1.read()); #endif delay(1000); nD_SMSsend.start(SMS_INTERVAL); // запуск таймера отправки СМС }// end of setup //***************************************************************************
- функция отправки СМС
//-------------------------------------------------------------------- // отправка СМС без использования delay() void f_SendSMS(String text, String phone) { switch (SMSpartNumber) { case 0 : SMSpartNumber++; #if SMSSEND_MODE Serial1.println("AT+CMGS=\"" + phone + "\""); #else Serial.println("SMS send started"); delay(50); Serial.println("AT+CMGS=\"" + phone + "\""); delay(50); #endif nD_SMSsend.start(1000); break; case 1 : SMSpartNumber++; #if SMSSEND_MODE Serial1.print(text); #else Serial.println(text); delay(50); #endif nD_SMSsend.start(300); break; case 2 : SMSpartNumber++; #if SMSSEND_MODE Serial1.print((char)26); #endif nD_SMSsend.start(300); break; case 3 : SMSpartNumber = 0; flag_SMS_send = false; // сбрасываем флаг отправки СМС #if SMSSEND_MODE nD_SMSsend.start(SMS_INTERVAL); #else Serial.println("SMS send finish"); delay(50); #endif break; } // end of switch } // end of f_SendSMS //----------------------------------------------------------------------------------
- класс noDelay.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // динамически управляемая генерация событий с динамически изменяемым интервалом времени между событиями. #include <Arduino.h> class noDELAY { private: unsigned long previous; unsigned long interval; boolean s; public: //------------------------------------------------------------------------------- // конструктор noDELAY() {s = false;} //------------------------------------------------------------------------------- // запуск таймера void start(unsigned long _interval) { interval = _interval; s = true; previous = millis(); } //------------------------------------------------------------------------------- // остановка таймера void stop() {s = false;} //------------------------------------------------------------------------------- // проверка окончания заданного интервала boolean tick() { unsigned long current = millis(); if (!s) { return false; } else if (current - previous >= interval) { previous = current; return true; } else { return false; } } //------------------------------------------------------------------------------- }; // end of class //===============================================================================