Введение:
В этом уроке мы создадим систему удаленного управления домом по смс, используя 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не установлен, тогда производится отправка смс уведомления о том, что пришло ошибочное сообщение.
- Если флаг

Обсуждение