Привіт друзі! Ми з кожним разом знаємо все більш цікаві застосування 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).

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

Світлодіод майже згас. Відправлю значення яскравості 254.

Отримуємо максимальну яскравість. І вимкну світлодіод, передавши значення нуль.

Тепер перевіримо команду SMS.

Отримав дуже швидку відповідь. Також вводжу команду ring. А ось прийшла й несподівана друга SMS. Спробуємо це виправити.

Команда ring добре спрацювала – пристрій мені передзвонив.

Надсилаю команду sms ще раз. Може, це була випадковість?

Ні, це не випадковість. Я начебто зрозумів у чому річ. Збільшу delay на 2 секунди після надсилання повідомлення. Оскільки команда видалення не встигає обробитись у модулі SIM800.

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

Отримую відповідь та вилучення пройшло вдало.

Надсилаю ще раз.

І знову вдала відповідь без повторів. Думаю, на сьогодні достатньо команд.

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



Буду радий вашим питанням у коментарях! Бажаю вам вдалих експериментів та розвитку.

<< Проекти << Усі товари >> Статті, уроки >>

Написати відгук

Примітка: HTML размітка не підтримується! Використовуйте звичайтий текст.
    Погано           Добре
Шарніри під обертальну вісь 8, 10 мм 2шт.

Шарніри під обертальну вісь 8, 10 мм 2шт.

Такі шарніри призначені для кріплення вісі черв'ячної передачі на будь-якій з трьох осей переміщення..

164.87грн.

Модуль I2C 4-х MOSFET транзисторів 5А N-канальні

Модуль I2C 4-х MOSFET транзисторів 5А N-канальні

Модуль розширення дискретних виходів на основі мікросхеми MCP23008Може комутувати чотири потужні нав..

338.40грн.

Розумний дім #11: Комунікаційні мережі

Розумний дім #11: Комунікаційні мережі

Розумний дім #11: Комунікаційні мережі Жодна система розумного дому неможлива без надій..

Компаратор подвійний LM393DR

Компаратор подвійний LM393DR

LM393DR в корпусі SOP-8 для поверхневого монтажу.Ці мікросхеми розробники усіляких датчиків для люби..

4.04грн.

Модуль на DIN-рейку для Arduino Nano — 8 дискретних входів, I2C, SPI, UART

Модуль на DIN-рейку для Arduino Nano — 8 дискретних входів, I2C, SPI, UART

Головний модуль автоматизації для створення домашніх і промислових систем управління на базі Arduino..

557.49грн.