Отправка СМС через 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
//===============================================================================