Главная chevron_right Наши уроки chevron_right Arduino chevron_right Удаленное управление домом по GSM/GPRS

Удаленное управление домом по GSM/GPRS

Собираем систему удалённого управления домом через SMS на Arduino и GSM/GPRS Shield: управляем лампочками, вентилятором, светодиодной лентой и линейным приводом

Видео-обложка запускается при наведении

Введение:

В этом уроке мы создадим систему удаленного управления домом по смс, используя GSM/GPRS Shield.

При получении смс устройство будет выполнять одну из указанных в смс функций, после чего уведомит вас об этом в ответной смс.

Видео:

Нам понадобится:

Для реализации проекта нам необходимо установить библиотеки:

  • iarduino_GSM- для работы с GSM/GPRS Shield;
  • Библиотеки SoftwareSerial входит в базовый набор Arduino IDE и не требует установки;

О том, как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki - Установка библиотек в Arduino IDE.

Описание работы системы удалённого управления:

  • После подачи питания дождитесь получения смс с уведомлением о том, что инициализация прошла успешно и модем GSM зарегистрировался в сети. После этого устройство готово к работе.
  • Устройство может принимать сообщения, содержащие параметры "Действие", "Устройство", "Яркость".
  • Для управления устройством вам необходимо сформировать смс по следующему алгоритму:Основные функции:[ДЕЙСТВИЕ] [УСТРОЙСТВО];Дополнительные функции:[ЗНАЧЕНИЕ%]; — задаём значение ШИМ-сигнала для яркости/скорости;
  • После правильно написанной и отправленной информации дождитесь обратного сообщения с уведомлением о том, что ваша команда прошла.

Схема сборки:

Arduino / Piranha UNO:

Batery Shield:

Установите Battery Shield на Arduino / Piranha UNO: Во время установки Battery Shield должен быть в выключенном состоянии.

GSM/GPRS Shield:

На Battery Shield установите GSM/GPRS Shield A9:

На плате GSM/GPRS Shield A9 имеется слот для SIM-карт и переключатель UART. Установите SIM-карту в слот, выберите положение переключателя RX-7/TX-8.

Trema Shield:

На GSM/GPRS Shield A9 установите Trema Shield:

Линейный привод:

Подключим линейный привод к Trema Shield. Для этого необходимо 2 электромеханических реле подключить к выводу 4.

После этого установить перемычки согласно рисунку.

Далее подключить к реле линейный привод и подвести внешнее питание 12В.

Лампочки:

Подключите к выводу 2 и 3 Trema Shield 2 твердотельных реле.

Далее согласно схеме подключите к реле лампочки и питание 220В.

Будьте предельно внимательны и осторожны!

Светодиодная лента:

Подключите к 6 выводу Trema Shield Trema-модуль Силовой ключ, а к нему подключите светодиодную ленту, пустив провод питания ленты (красный) напрямую к источнику питания 12В, а провод GND ленты (чёрный) в разрыв через Trema-модуль Силовой ключ.

Вентилятор(кулер):

Подключите к 5 выводу Trema Shield Trema-модуль Силовой ключ, а к нему подключите вентилятор (кулер), пустив провод питания вентилятора (красный) напрямую к источнику питания 12В, а провод GND вентилятора (чёрный) в разрыв через Trema-модуль Силовой ключ.

Код программы (скетч):

В скетче используются библиотеки iarduino_GSM и SoftwareSerial.

              // БИБЛИОТЕКИ
#include       <Wire.h>                                                                               // Подключаем библиотеку для работы с аппаратной шиной I2C, до подключения библиотек iarduino_I2C_Encoder и iarduino_I2C_DSL.
#include       <SoftwareSerial.h>                                                                     // Подключаем библиотеку SoftwareSerial для программной реализации шины UART.
#include       <iarduino_GSM.h>                                                                       // Подключаем библиотеку iarduino_GSM для работы с GSM/GPRS Shield.

#define pinPWR 7                                                                                      // Вывод Arduino используемый для включения  GSM/GPRS Shield.
#define pinRX  8                                                                                      // Вывод Arduino RX подключаемый к выводу TX GSM/GPRS Shield.
#define pinTX  9                                                                                      // Вывод Arduino TX подключаемый к выводу RX GSM/GPRS Shield.
iarduino_GSM    gsm(pinPWR);                                                                          // Создаём объект gsm для работы с функциями и методами библиотеки iarduino_GSM.
SoftwareSerial  softSerial(pinRX, pinTX);                                                             // Создаём объект softSerial для работы по программной шине UATR, указывая выводы RX и TX платы Arduino (выводы 7 и 8)
              // ПЕРЕМЕННЫЕ
uint8_t         Sum        = 0;                                                                       // Переменная для хранения процентного значения ШИМ-сигнала
              // Для отправки СМС о удачном запуске устройства, укажите в строке ниже номер телефона без пробелов.
char            SMSnum[13] = "7_ВАШ_НОМЕР_ТЕЛЕФОНА";                                                  // Объявляем строку для хранения номера отправителя SMS сообщений.
char            SMStxt[161];                                                                          // Объявляем строку для хранения текста принятых SMS сообщений.
String          strSMStxt;                                                                            // переменная типа String для более удобной работы
uint8_t         flgFunc;                                                                              // флаг наличия действия
uint8_t         flgDev;                                                                               // флаг наличия устройства
uint8_t         flgPWM;                                                                               // флаг наличия ШИМ
uint8_t         lvlPWM;                                                                               // Переменная количества символов в строке
const char*     Func[2][5] = {{"ВКЛЮЧИТЬ", "ВЫКЛЮЧИТЬ"},                                              // Двумерный массив с функциями и устройствами
                              {"СВЕТ КУХНЯ" , "СВЕТ КОМНАТА", "ДВЕРЬ", "ВЕНТИЛЯТОР", "ПОДСВЕТКА"}};   //
const char      Pins[]     =  {     2,             3,            4,         5,           6       };   // Массив с номерами выводов устройств
                                                                                                      //
void setup() {                                                                                        //
                // Инициируем GSM/GPRS Shield и проверяем его готовность к работе:
  gsm.begin(softSerial);                                                                              // Инициируем работу GSM/GPRS Shield, указывая объект шины UART.
  while (gsm.status() != GSM_OK) { delay(1000); }                                                     // Ждём завершения регистрации модема в сети оператора связи.
                // Установка кодировки для символов Кириллицы:
  gsm.TXTsendCodingDetect("п");                                                                       // Выполняем автоопределение кодировки скетча для отправки текста на Русском языке.
                // Отправка сообщения об удачном запуске:
  gsm.SMSsend( F("Инициализация прошла успешно."), SMSnum);                                           // Данная строка будет отвечать отправителю указанным SMS сообщением.
                // Настраиваем выводы
  pinMode(Pins[0],   OUTPUT);                                                                         // настройка вывода на работу в режиме выхода
  pinMode(Pins[1],   OUTPUT);                                                                         // настройка вывода на работу в режиме выхода
  pinMode(Pins[2],   OUTPUT);                                                                         // настройка вывода на работу в режиме выхода
  pinMode(Pins[3],   OUTPUT);                                                                         // настройка вывода на работу в режиме выхода
  pinMode(Pins[4],   OUTPUT);                                                                         // настройка вывода на работу в режиме выхода
  digitalWrite(Pins[0], LOW);                                                                         // устанавливаем на выходе значение сигнала равным LOW
  digitalWrite(Pins[1], LOW);                                                                         // устанавливаем на выходе значение сигнала равным LOW
  digitalWrite(Pins[2], LOW);                                                                         // устанавливаем на выходе значение сигнала равным LOW
  digitalWrite(Pins[3], LOW);                                                                         // устанавливаем на выходе значение сигнала равным LOW
  digitalWrite(Pins[4], LOW);                                                                         // устанавливаем на выходе значение сигнала равным LOW
  flgFunc = 20;                                                                                       // Сбрасываем флаг
  flgDev  = 20;                                                                                       // Сбрасываем флаг
  flgPWM  =  0;                                                                                       // Сбрасываем флаг
}                                                                                                     //
                                                                                                      //
void loop () {                                                                                        //
  if (millis() % 1000 < 100) {                                                                        // Выполняем код в теле оператора if первые 100 мс каждой секунды.
    delay(100);                                                                                       // Устанавливаем задержку в 100 мс, чтоб не выполнить код более 1 раза за секунду.
    if (gsm.SMSavailable()) {                                                                         // Функция SMSavailable() возвращает количество входящих непрочитанных SMS сообщений.
      gsm.SMSread(SMStxt, SMSnum);                                                                    // Читаем SMS сообщение в ранее объявленные переменные (текст SMS сообщения, адрес отправителя, дата отправки, идентификатор SMS, количество SMS, номер SMS).
      strSMStxt = SMStxt;                                                                             // Присваиваем массиву atrSMStxt значения массива SMStxt для дальнейшей проверки на совпадения
      for (int m = 0; m < (sizeof(Func[0]) / 2); m++) {                                               // проверяем в цикле, совпадает ли команда из массива с тем, что пришло в СМС
        if (strSMStxt.indexOf(Func[0][m]) > -1 && *Func[0][m] != 0) {                                 // если совпадения есть, то
          flgFunc = m;                                                                                // присваиваем флагу порядковый номер совпавшего слова из массива Func
          for (int i = 0; i < (sizeof(Func[1]) / 2); i++) {                                           // проверяем в цикле, совпадает ли имя устройства из массива с тем, что пришло в СМС
            if (strSMStxt.indexOf(Func[1][i]) > -1 && *Func[1][i] != 0) {                             // если совпадения есть и это не пустая строка, то
              flgDev = i;                                                                             // присваиваем флагу порядковый номер совпавшего слова из массива Device
              if (strchr(SMStxt, '%')) {                                                              // проверяем, есть ли в тексте СМС символ %
                flgPWM = 1;                                                                           // и если есть, то устанавливаем флаг
              }                                                                                       //
            }                                                                                         //
          }                                                                                           //
        }                                                                                             //
      }                                                                                               //
      if (flgPWM == 1) {                                                                              // если установлен флаг flgPWM, то
        lvlPWM = uint8_t(strchr(SMStxt, '%' ) - SMStxt);                                              // определяем количество символов в строке до совпадения с символом %
        if (SMStxt[lvlPWM - 1] >= '0' && SMStxt[lvlPWM - 1] <= '9') {                                 // Проверяем, является ли символ, расположенный в строке на 1 позицию левее символа %, цифрой от 0 до 9, и если да, то
          Sum = uint8_t(SMStxt[lvlPWM - 1] - '0');                                                    // прибавляем эту цифру к переменной (единицы)
          if (SMStxt[lvlPWM - 2] >= '0' && SMStxt[lvlPWM - 2] <= '9') {                               // Проверяем, является ли символ, расположенный в строке на 2 позиции левее символа %, цифрой от 0 до 9, и если да, то
            Sum += uint8_t((SMStxt[lvlPWM - 2] - '0') * 10);                                          // прибавляем эту цифру к переменной, умножив на 10 (десятки)
            if (SMStxt[lvlPWM - 3] > '0' && SMStxt[lvlPWM - 3] <= '1') {                              // Проверяем, является ли символ, расположенный в строке на 3 позиции левее символа %, цифрой от 0 до 1, и если да, то
              Sum += uint8_t((SMStxt[lvlPWM - 3] - '0') * 100) ;                                      // прибавляем эту цифру к переменной, умножив на 100 (сотни)
            } else                                                                                    // иначе проверяем, что
              if (SMStxt[lvlPWM - 3] >= '2' && SMStxt[lvlPWM - 3] <= '9') {                           // число "сотен" не больше 1, и если больше то
                flgPWM = 0;                                                                           // сбрасываем флаг ШИМ
              }                                                                                       //
          }                                                                                           //
        }                                                                                             //
      }                                                                                               //
      if (flgFunc != 20) {                                                                            // если флаг flgFunc установлен, то
        switch (flgFunc) {                                                                            // проверяем значение флага flgFunc с определёнными в операторе case
          case 0:                                                                                     // Если 0 - значит указано действие ВКЛЮЧИТЬ
            if (flgDev != 20) {                                                                       // Если установлен флаг наличия устройства, то
              if (flgPWM == 1) {                                                                      // проверяем флаг ШИМ. Если он установлен, то
                uint8_t mapPWM = map(Sum, 0, 100, 0, 255);                                            // переопределяем множество для ШИМ и
                analogWrite(Pins[flgDev], mapPWM );                                                   // подаём ШИМ-сигнал на вывод и
                gsm.SMSsend(F("Процент задан!"), SMSnum);                                             // отправляем сообщение об успешном выполнении.
                Sum    = 0;                                                                           // сбрасываем количество процентов для задания ШИМ-сигнала после выполнения
                flgPWM = 0;                                                                           // сбрасываем флаг ШИМ после выполнения
              }                                                                                       //
              else {                                                                                  // Если же флага ШИМ нет, то
                digitalWrite(Pins[flgDev], HIGH);                                                     // подаём высокий сигнал на вывод для включения и
                gsm.SMSsend(F("Устройство включено!"), SMSnum);                                       // отправляем сообщение об успешном выполнении.
              }                                                                                       //
              flgDev = 20;                                                                            // сбрасываем флаг устройства после выполнения
            } else {                                                                                  // если в СМС не указано устройство, то
              gsm.SMSsend(F("Что включить?"), SMSnum);                                                // отправляем об этом сообщение
            }                                                                                         //
            flgFunc = 20;                                                                             // сбрасываем флаг действия после выполнения
            break;                                                                                    //
          case 1:                                                                                     // Если 1 - значит указано действие ВЫКЛЮЧИТЬ
            if (flgDev != 20) {                                                                       // Если установлен флаг наличия устройства, то
              digitalWrite(Pins[flgDev], LOW);                                                        // подаём низкий сигнал на вывод для выключения
              gsm.SMSsend(F("Устройство выключено!"), SMSnum);                                        // и отправляем сообщение об успешном выполнении.
              flgDev = 20;                                                                            // сбрасываем флаг устройства после выполнения
            } else {                                                                                  // если в СМС не указано устройство, то
              gsm.SMSsend(F("Что выключить?"), SMSnum);                                               // отправляем об этом сообщение
            }                                                                                         //
            flgFunc = 20;                                                                             // сбрасываем флаг действия после выполнения
            break;                                                                                    //
        }                                                                                             //
      } else {                                                                                        //
        gsm.SMSsend(F("Ошибка в тексте!"), SMSnum);                                                   // Если текст пришёл не верный, то отправляем об этом сообщение
      }                                                                                               //
    }                                                                                                 //
  }                                                                                                   //
}                                                                                                     //

Алгоритм работы скетча:

До кода void setup() определяются номера выводов, объявляются переменные и функции, подключаются библиотеки, и создаются объекты для работы с ними.

Перед загрузкой скетча не забудьте задать в переменной SMSnum номер телефона, куда будет приходить смс-уведомление о пройденной идентификации!

В коде void setup() конфигурируются выбранные выводы, инициируется работа GSM/GPRS Shield, выполняется цикл ожидания готовности GSM/GPRS Shield к работе (регистрация в сети оператора). И после выполнения всех указанных действий выполняется оповещение о готовности к работе, путем отправки смс на указанный номер.

Код void loop() выполняется только при получении смс сообщения. Сам блок разделён на две основные части: приём входящих сообщений и выполнение указанных в сообщении действий.

Приём входящих сообщений состоит из следующих действий:

  • Считывание сообщения из памяти SIM-карты, после чего функция автоматически их оттуда удаляет.
  • После считывания сообщения запускается цикл, в котором текст сообщения проверяется на наличие в нём управляющих команд;
  • Если команда найдена, то внутри него запускается второй цикл, в котором текст так же проверяется, но уже на наличие в нём имени устройства;
  • Если имя устройства найдено, то выполняется проверка на наличие дополнительного параметра, указанного с символом "%" - процент (от 0 до 100) яркости/скорости, с которым будет работать указанное устройство.
  • Если дополнительный параметр был указан, то ставится флаг о его наличии в полученном смс.

Выполнение указанных в сообщении действий:

  • После того, как все флаги были выставлены, происходит проверка наличия флага дополнительного параметра. Если он присутствует, тогда выполняется вычисление значения числа, указанного перед символом %:Для этого мы находим количество символов в строке, расположенных слева от символа %;Полученное число покажет нам порядковый номер символа % в массиве strSMStxt;Для того, чтобы узнать, какое значение было указано, проверим 3 ближайшие ячейки массива, расположенные слева от символа %:Если 1 ячейка, расположенная ближе всего к символу %, содержит число от 0 до 9, то тогда мы заносим её значение в переменную Sum. Это будет разряд "единицы";После этого внутри первой проверки выполняется вторая проверка 2 ячейки на наличие числа от 0 до 9. Если число найдено, то оно умножается на 10 и прибавляется к переменной Sum. Это будет разряд "десятки";После этого внутри второй проверки производится третья проверка 3 ячейки. Если в ней найдена 1, то она умножается на 100 и прибавляется к переменной Sum. Это будет разряд "сотни".Если же в третьей проверке окажется, что в "сотнях" указано больше 1, то флаг flgPWM будет сброшен;
  • Выполняется проверка наличия флага flgFunc:Если флаг flgFunc был установлен, тогда выполняется проверка наличия флага flgDev:Если флаг flgDev был установлен, тогда выполняется проверка наличия флага flgPWM:Если флаг flgPWM установлен, тогда выполняется подача ШИМ-сигнала на вывод с указанным в сообщении устройством и отправка смс с уведомлением об успешном выполнении;Если флаг flgPWM не установлен, тогда выполняется подача сигнала HIGH на вывод с указанным устройством и отправка смс с уведомлением об успешном выполнении;Если флаг flgDev не установлен, тогда производится отправка смс уведомления о том, что в сообщении не указано устройство;Если флаг flgFunc не установлен, тогда производится отправка смс уведомления о том, что пришло ошибочное сообщение.

Ссылки:

Комплект для повторения проекта

Что понадобится

Это быстрый ориентир по основным модулям и деталям. Полный список для повторения проекта смотрите в самой статье.

11 позиций
GSM/GPRS Shield A9 Плата расширения для добавления контроллеру Arduino функций мобильной сети Открыть в iArduino Piranha Uno R3 Прямой аналог Arduino Uno c микроконтроллером ATmega328P на ядре AVR для разработки электронных устройств на языке C++ Открыть в iArduino Battery Shield (Li-po, 2300 мА·ч) Battery Shield Открыть в iArduino Реле (Trema-модуль v2.0) Позволяет коммутировать цепи как переменного, так и постоянного тока до 10 А. Открыть в iArduino Силовой ключ N-канал (Trema-модуль) Позволит управлять нагрузкой ШИМ сигналом. Например яркостью светодиодной ленты или скоростью мотора Открыть в iArduino Линейный актуатор XDHA12-100 (900 Н / 12 В / 100 мм) Линейный привод с усилием 900 Н, номинальным питанием 12 В и длиной штока 100 мм Открыть в iArduino Светодиодная лента (Белая 4000 К, 5 м, 300 светодиодов) Герметичная лента длиной пять метров из 300 белых светодиодов дневного свечения Открыть в iArduino Источник питания на 12В. 3А. Источник питания 12 вольт, 2 ампера, центр положительный, DC jack 5,5*2,1 мм Открыть в iArduino Arduino Uno R3 (USB ATmega16U2) Платформа c микроконтроллером ATmega328P на ядре AVR с чипом USB ATmega16U2 для разработки электронных устройств на языке C++ Открыть в iArduino Trema Shield Плата расширения для удобного подключения периферийных устройств Открыть в iArduino Твердотельное реле (Trema—модуль) Хорошее решения для коммутирования переменного тока до 2А. Имеет больший ресурс пред электромеханическими реле. Открыть в iArduino
Все уроки Arduino