Введение:
В этом уроке мы создадим систему удаленного управления домом по смс, используя GSM/GPRS Shield.
При получении смс устройство будет выполнять одну из указанных в смс функций, после чего уведомит вас об этом в ответной смс.
Видео:
Нам понадобится:
- 1х Piranha UNO
- 1х GSM/GPRS Shield;
- 1х Battery Shield;
- 2х Реле;
- 2х Силовой ключ;
- 1х Линейный привод 12В;
- 1х Светодиодная лента 12В;
- 1х Источник питания 12В;
- 1х Вентилятор(кулер) 12В;
- 2х Лампочка;
Для реализации проекта нам необходимо установить библиотеки:
- 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
будет сброшен;
- Если 1 ячейка, расположенная ближе всего к символу %, содержит число от 0 до 9, то тогда мы заносим её значение в переменную
- Для этого мы находим количество символов в строке, расположенных слева от символа
- Выполняется проверка наличия флага
flgFunc
:- Если флаг
flgFunc
был установлен, тогда выполняется проверка наличия флагаflgDev
:- Если флаг
flgDev
был установлен, тогда выполняется проверка наличия флагаflgPWM
:- Если флаг
flgPWM
установлен, тогда выполняется подача ШИМ-сигнала на вывод с указанным в сообщении устройством и отправка смс с уведомлением об успешном выполнении; - Если флаг
flgPWM
не установлен, тогда выполняется подача сигналаHIGH
на вывод с указанным устройством и отправка смс с уведомлением об успешном выполнении;
- Если флаг
- Если флаг
flgDev
не установлен, тогда производится отправка смс уведомления о том, что в сообщении не указано устройство;
- Если флаг
- Если флаг
flgFunc
не установлен, тогда производится отправка смс уведомления о том, что пришло ошибочное сообщение.
- Если флаг
Обсуждение