Arduino Nano SIM800 SMS команды

Мы с каждым разом разбираем все более интересные применения GSM-модуля SIM800. В этот раз я покажу, как принимать SMS сообщения и обрабатывать команды, которые могут в них храниться.

На основании программы из предыдущего видео я набросал следующие строки из двух команд, отправляемых в SIM800 для чтения SMS. 

//https://geekmatic.in.ua | https://pinout.uno
#include <SoftwareSerial.h>
SoftwareSerial SIM800serial (2, 3);

#define OK 1
#define NOTOK 2
#define TIMEOUT 3
String txt;

void setup() {
  pinMode(5, OUTPUT);
  digitalWrite(5, HIGH); //SIM800 ON only for this module
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  Serial.begin(9600);
  SIM800serial.begin(9600);
  delay(5000);
  SIM800command("AT", "OK", "ERROR", 500, 5);
}

void loop() {
  SIM800command("AT+CMGF=1", "OK", "ERROR", 2000, 1); //SMS to text mode - not PDU mode
  SIM800command("AT+CMGL=\"ALL\"", "OK", "ERROR", 5000, 1);////sms list
  SIM800command("AT+CMGD=1,3", "OK", "ERROR", 10000, 1);//sms delete
  delay(2000);
}
byte SIM800command(String command, String response1, String response2, uint16_t timeOut, uint16_t repetitions) {
  byte returnValue = NOTOK;
  byte countt = 0;
  
  while (countt < repetitions && returnValue != OK) {
    SIM800serial.println(command);
    
    if (SIM800waitFor(response1, response2, timeOut) == OK) {
      returnValue = OK;
    } else {returnValue = NOTOK;}
    countt++;
  }
  
  return returnValue;
}

byte SIM800waitFor(String response1, String response2, uint16_t timeOut) {
  uint16_t entry = 0;
  uint16_t count = 0;
  String reply = SIM800read();
  byte retVal = 99;

  do {
    reply = SIM800read();
    delay(1);
    entry ++;
  } while ((reply.indexOf(response1) + reply.indexOf(response2) == -2) && entry < timeOut );

  if (entry >= timeOut) {
    retVal = TIMEOUT;
  } else {
    if (reply.indexOf(response1) + reply.indexOf(response2) > -2) retVal = OK;
    else retVal = NOTOK;
  }
  
  return retVal;
}

String SIM800read() {
  String reply = "";
  
  if (SIM800serial.available())  {
    reply = SIM800serial.readString();
  }

  if (reply!=""){
    Serial.print("Reply: ");
    Serial.println(reply);
    txt = reply;
  }
  
  return reply;
}
 

Первая команда включает текстовый режим отображения SMS. 

Вторая команда выводит список всех входящих SMS из памяти SIM-карты. Существует так же отдельная команда у SIM800 для отображения одной SMS, но надо знать номер ячейки, где она сейчас хранится. Нам все-таки более интересен вывод всего списка.

Вот расшифровка этой команды. Тут можно задавать такие фильтрующие параметры, как полученные непрочтенные, полученные прочтенные, не отправленные, отправленные или вообще все. 

У меня в команде стоит параметр ALL – значит SIM800 выдаст список всех входящих и выходящих SMS, которые сохранены в памяти. Загружаю скетч в контроллер. Программа будет проверять наличие текстовых сообщений каждые 2 секунды и выводить их список.

Открываю монитор порта.

Отправляю текст Sms на номер SIM-карты, вставленной в SIM800.

В мониторе порта видим, что в памяти появилось одно сообщение с текстом, который я написал в телефоне. Кстати, обратите внимание, что в начале, в момент прихода SMS, GSM-модуль ругнулся кодом CMTI: SM, 1, что означает, что пришло текстовое сообщение и оно помещено в ячейку 1 памяти SIM-карты. Такой отчет SIM800 пишет в UART без запросов от контроллера.

Так же здесь видим, что нам желательно очищать память, где хранятся сообщения после их прочтения. Для чего, добавляем в скетч команду удаления CMGD.

Вот расшифровка этой команды. Первый параметр – номер ячейки памяти. Второй – это фильтр:

0  удалить одну ячейку;

1 удалить все прочитанные;

2 удалить все прочитанные и отправленные;

3 удалить все прочитанные входящие и все исходящие.

4 удалить абсолютно все.

Я выбрал третий вариант, удаляющий все входящие и исходящие SMS, оставляющий непрочитанные, чтобы случайно не удалить входящее сообщение, которое еще не обработано.

Прямо сейчас поставьте жирный лайк этому видео, а я загружу программу в Arduino. И открою монитор порта. 

Видим ответ команды удаления сообщений CMGD OK.

Отправляю сообщение Sms2.

Сообщение пришло и прочитано. И повторно уже не читается. Потому, что память очищена.

Приём SMS – это чудесно, но давайте же перейдем в практическую плоскость и заставим Arduino Nano выполнять команды.

Для тестирования SMS-команд соберём следующую схему. Я к своему шилду добавлю два светодиода, которыми попробую управлять при помощи SMS.

Вот мой шилд для проектов на Arduino Nano и SIM800, но вы можете собрать эту схему по своему без моего шилда. Припаиваю светодиоды и их ограничивающие резисторы прямо к контроллеру Arduino Nano.

Получилось красиво!

Программа будет такой. Команду включения текстового режима я перенёс в setup. Её не обязательно выполнять каждый цикл.

//https://geekmatic.in.ua | https://pinout.uno
#include <SoftwareSerial.h>
SoftwareSerial SIM800serial (2, 3);

#define OK 1
#define NOTOK 2
#define TIMEOUT 3

String txt;

void setup() {
  pinMode(5, OUTPUT);
  digitalWrite(5, HIGH); //SIM800 ON only for this module
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  Serial.begin(9600);
  SIM800serial.begin(9600);
  delay(5000);
  SIM800command("AT", "OK", "ERROR", 500, 5);
  SIM800command("AT+CMGF=1", "OK", "ERROR", 2000, 1); //SMS to text mode - not PDU mode
}

void loop() {
  SIM800command("AT+CMGL=\"ALL\"", "OK", "ERROR", 5000, 1);////sms list
  parse_cmd( txt );
  SIM800command("AT+CMGD=1,3", "OK", "ERROR", 10000, 1);//sms delete
  delay(2000);
}

void parse_cmd( String str){
  String part1;
  Serial.println("read_cmd start"); 

  if (str.indexOf("sms")>-1) { //sms
    SIM800command("AT+CMGS=\"+380934158245\"", ">", "ERROR", 5000, 1);
    String str = "Hello from Arduino and SIM800!"; //SMS text
    SIM800serial.print(str);//the content of the message
    char j=0x1A;
    SIM800command((String)j, ">", "ERROR", 2000, 1);
    Serial.println("Sms");
    delay(4000);
  }
  
  if (str.indexOf("ring")>-1) { //ring
    Serial.println("Ring"); 
    SIM800command("ATD+380934158245;", "OK", "ERROR", 1000, 1);
    delay(10000);
    SIM800command("ATH", "OK", "ERROR", 500, 5);
  }
  
  //on
  if (str.indexOf("on")>-1) { digitalWrite(7, HIGH); Serial.println("On");} 

  //off
  if (str.indexOf("off")>-1) { digitalWrite(7, LOW); Serial.println("Off");} 
  
  if (str.indexOf("pwm")>-1) {//pwm
    part1 = str.substring(str.indexOf("pwm") + 4, str.length());
    int brightness = part1.toInt();
    Serial.print("Pwm = "); 
    Serial.println(brightness); 
    analogWrite(6, brightness);
  }
}
byte SIM800command(String command, String response1, String response2, uint16_t timeOut, uint16_t repetitions) {
  byte returnValue = NOTOK;
  byte countt = 0;
  
  while (countt < repetitions && returnValue != OK) {
    SIM800serial.println(command);
    
    if (SIM800waitFor(response1, response2, timeOut) == OK) {
      returnValue = OK;
    } else {returnValue = NOTOK;}
    countt++;
  }
  
  return returnValue;
}

byte SIM800waitFor(String response1, String response2, uint16_t timeOut) {
  uint16_t entry = 0;
  uint16_t count = 0;
  String reply = SIM800read();
  byte retVal = 99;

  do {
    reply = SIM800read();
    delay(1);
    entry ++;
  } while ((reply.indexOf(response1) + reply.indexOf(response2) == -2) && entry < timeOut );

  if (entry >= timeOut) {
    retVal = TIMEOUT;
  } else {
    if (reply.indexOf(response1) + reply.indexOf(response2) > -2) retVal = OK;
    else retVal = NOTOK;
  }
  
  return retVal;
}

String SIM800read() {
  String reply = "";
  
  if (SIM800serial.available())  {
    reply = SIM800serial.readString();
  }

  if (reply!=""){
    Serial.print("Reply: ");
    Serial.println(reply);
    txt = reply;
  }
  
  return reply;
}
 

Дальше в loop идет команда чтения списка текстовых сообщений.

Потом новая функция для отсеивания команд из сообщений. В неё передаётся текст списка всех сообщений из памяти SIM-карты.

И команда удаления прочитанных SMS.

Вот наша хитрая функция. Если в тексте будет найдена строка sms, то устройство отправит ответное сообщение: "Hello from Arduino and SIM800!".

Если будет найдена строка ring, то Arduino позвонит по заданному номеру телефона.

Следующие две текстовые команды – on и off. Они должны включать и выключать первый светодиод.

Последняя отслеживаемая команда – это pwm. Она будет управлять яркостью второго светодиода.

Сначала в переменную brightness записывается выделенное из текста сообщения значение яркости.

Потом функцией analogWrite мы активируем ШИМ управление пином номер 6 с заданным заполнением, то есть яркостью.

Загружаю скетч в контроллер.

Отправляю первую команду для включения светодиода.

Есть включение светодиода. Теперь отправляю команду выключения.

Есть выключение.

Теперь задам яркость второму светодиоду – 100 (в диапазоне от 0 до 255).

Команда выполнилась. Теперь 10.

Светодиод почти потух. Отправлю значение яркости 254.

Получаем максимальную яркость. И выключу светодиод, передав значение ноль.

Теперь проверим команду sms.

Получил очень быстрый ответ. Так же ввожу команду ring. А вот пришла и неожиданная вторая SMS. Попробуем это исправить.

Команда ring хорошо сработала – устройство мне перезвонило.

Отправляю команду sms ещё раз. Может это была случайность?

Нет, это не случайность. Я вроде понял в чем дело. Увеличу delay на 2 секунды после отправки сообщения. Так как команда удаления не успевает обработаться в модуле SIM800. 

Проверяю команду sms еще раз.

Получаю ответ и удаление прошло удачно.

Отправляю еще раз.

И снова удачный ответ без повторов. Думаю на сегодня достаточно команд.

В ответных SMS можно вставлять значения различных датчиков, подключенных к Arduino Nano. Вместо светодиодов можно управлять различными исполнительными механизмами и другими приборами. Так же вы можете добавлять множество других текстовых команд редактируя функцию parse_cmd. 

 https://youtu.be/qvxCPU1mhoc

Додати коментар


Захисний код
Оновити

Радіаційний фон навколо ЗАЕС

EcoMonitoring

ЛІЧІЛЬНИК ВІДВІДУВАННЬ

Сьогодні 219
Вчора165
Цього тижня 384
Минулого тижня 203
Цей місяць 587
Минулий місяць 5128
За весь час 200621
Ваш IP: 216.73.216.0
Сегодня: 2025-11-03
Пользователей на сайте: 0
Гостей на сайте: 208