Мобильный телефон является революционным изобретением современности. Первоначально он был придуман для совершения голосовых вызовов и передачи/приема текстовых сообщений, но после появления смартфонов функции мобильных телефонов значительно расширились. В этом проекте мы разработаем систему автоматизации дома на основе платы Arduino, которая будет управлять включением/выключением домашних электронных устройств при помощи передачи SMS сообщений с мобильного телефона (не обязательно смартфона, подойдет и обычный мобильный телефон). Ранее на нашем сайте мы уже рассматривали проекты автоматизации дома под управлением персонального компьютера и с помощью пульта инфракрасной связи.
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress).
- ЖК дисплей 16х2 (купить на AliExpress).
- GSM модуль (купить на AliExpress).
- Модуль драйвера двигателя ULN2003 (купить на AliExpress).
- Реле на 5 В.
- Электрические лампочки с держателями (патронами).
- Источник питания.
- Соединительные провода.
- Макетная плата.
- Мобильный телефон.
Общие принципы работы устройства
Структурная схема работы устройства приведена на следующем рисунке.
В нашем проекте мы в SMS сообщениях будем использовать префикс “#A.” чтобы идентифицировать начало команды, а в конце сообщения будем использовать суффикс (концевик) “*“ чтобы идентифицировать конец команды.
Когда мы передаем SMS с мобильного телефона, GSM модуль принимает его и передает на плату Arduino. Плата Arduino принимает это сообщение, извлекает из него значащую часть и сохраняет ее в строковой переменной. После этого Arduino сравнивает эту строку с заранее определенными строками (шаблонами) для управления электронными устройствами. Если строки совпадают, то Arduino выдает команду через реле на включение/выключение соответствующего устройства и высвечивает на ЖК дисплее результат операции.
В нашем проекте для демонстрации мы использовали 3 электрические лампочки, которые условно будут обозначать вентилятор, свет и телевизор.
В следующей таблице приведен список сообщений, передаваемых с помощью SMS, для включения/выключения вентилятора, света и телевизора.
S.no. | Message | Operation |
1 | #A.fan on* | Fan ON |
2 | #A.fan off* | Fan OFF |
3 | #A.light on* | Light ON |
4 | #A.light off* | Light OFF |
5 | #A.tv on* | TV ON |
6 | #A.tv off* | TV Off |
7 | #A.all on* | All ON |
8 | #A.all off* | All OFF |
Принципы работы GSM модуля
GSM модуль используется во многих устройствах, которые ориентированы на взаимодействие с технологией GSM. Обычно он используется для взаимодействия компьютера с GSM сетью. Однако в роли компьютера может выступать и плата Arduino.
GSM модуль понимает только AT команды и может на них отвечать. На большинство AT команд модуль отвечает сообщением “OK“ если он выполнил ее успешно, и сообщением “ERROR” если во время выполнения команды произошли какие либо проблемы. Существуют различные AT команды, например, ATA – ответить на звонок, ATD – сделать звонок, AT+CMGR — прочесть сообщение, AT+CMGS – передать SMS сообщение и т.д. AT команды должны заканчиваться символом возврата каретки, то есть \r (0D в шестнадцатеричном формате), например, “AT+CMGS\r”. К примеру, в нашем проекте мы можем использовать следующие AT команды:
ATE0 For echo off
AT+CNMI=2,2,0,0,0 <ENTER> режим автоматического открытия принимаемых сообщений
ATD<Mobile Number>; <ENTER> осуществить вызов (например, ATD+919610126059;\r\n)
AT+CMGF=1 <ENTER> выбор текстового режима
AT+CMGS=”Mobile Number” <ENTER> назначение мобильного номера получателя
>>после этого мы можем написать наше сообщение
>>после написания сообщения
Ctrl+Z команда передачи сообщения (26 в десятичном коде).
ENTER=0x0d в шестнадцатеричном формате
SIM900 представляет собой четырех диапазонный GSM/GPRS модуль, способный функционировать в диапазонах 850/900/1800/1900 МГц в режимах передачи/приема голоса, SMS и данных. Отличается низким энергопотреблением. Внешний вид данного модуля показан на следующем рисунке.
Работа схемы
Схема устройства представлена на следующем рисунке.
ЖК дисплей используется для отображения статуса операций и подключен к плате Arduino в 4-битном режиме. Контакты ЖК дисплея RS, EN, D4, D5, D6, D7 подсоединены к цифровым контактам Arduino 6, 7, 8, 9, 10, 11. Контакты Rx и Tx GSM непосредственно подключены к контактам Tx и Rx Arduino. GSM запитывается с помощью 12-вольтового адаптера. Три реле на 5 Вольт типа SPDT используются для управления света, вентилятора и телевизора. Реле подсоединены к контактам Arduino 3, 4 и 5 через драйвер реле ULN2003.
Исходный код программы
В программе первым делом необходимо подключить библиотеку для работы с ЖК дисплеем, сообщить Arduino к каким его контактам подключен ЖК дисплей, инициализировать необходимые контакты и переменные.
1 2 3 4 5 6 7 8 9 |
#include<LiquidCrystal.h> LiquidCrystal lcd(6,7,8,9,10,11); #define Fan 3 #define Light 4 #define TV 5 int temp=0,i=0; int led=13; |
После этого необходимо инициализировать последовательный порт для работы со скоростью 9600 бод/с, задать направление работы для используемых контактов.
1 2 3 4 5 6 7 8 |
void setup() { lcd.begin(16,2); Serial.begin(9600); pinMode(led, OUTPUT); pinMode(Fan, OUTPUT); pinMode(Light, OUTPUT); pinMode(TV, OUTPUT); |
Для работы с последовательным портом мы будем использовать 2 функции: Serial.available, которая будет проверять поступили ли какие-нибудь данные по последовательному порту и Serial.read, которая будет считывать данные из последовательного порта.
1 2 3 |
while (Serial.available()) { char inChar=Serial.read(); |
После приема данных по последовательному порту мы значащую часть SMS сообщения сохраняем в строковой переменной.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
void serialEvent() { while(Serial.available()) { if(Serial.find("#A.")) { digitalWrite(led, HIGH); delay(1000); digitalWrite(led, LOW); while (Serial.available()) { char inChar=Serial.read(); str[i++]=inChar; if(inChar=='*') { temp=1; return; } |
Затем в программе происходит сравнение этой строки с образцами строк и если фиксируется совпадение, то выдается команда на включение/выключение соответствующего устройства.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
void check() { if(!(strncmp(str,"tv on",5))) { digitalWrite(TV, HIGH); lcd.setCursor(13,1); lcd.print("ON "); delay(200); } else if(!(strncmp(str,"tv off",6))) { digitalWrite(TV, LOW); lcd.setCursor(13,1); lcd.print("OFF "); delay(200); } |
Далее приведен полный текст программы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
#include<LiquidCrystal.h> LiquidCrystal lcd(6,7,8,9,10,11); #define Fan 3 #define Light 4 #define TV 5 int temp=0,i=0; int led=13; char str[15]; void setup() { lcd.begin(16,2); Serial.begin(9600); pinMode(led, OUTPUT); pinMode(Fan, OUTPUT); pinMode(Light, OUTPUT); pinMode(TV, OUTPUT); lcd.setCursor(0,0); lcd.print("GSM Control Home"); lcd.setCursor(0,1); lcd.print(" Automaton "); delay(2000); lcd.clear(); lcd.print("Circuit Digest"); delay(1000); lcd.setCursor(0,1); lcd.print("System Ready"); Serial.println("AT+CNMI=2,2,0,0,0"); delay(500); Serial.println("AT+CMGF=1"); delay(1000); lcd.clear(); lcd.setCursor(0,0); lcd.print("Fan Light TV "); lcd.setCursor(0,1); lcd.print("OFF OFF OFF "); } void loop() { lcd.setCursor(0,0); lcd.print("Fan Light TV"); if(temp==1) { check(); temp=0; i=0; delay(1000); } } void serialEvent() { while(Serial.available()) { if(Serial.find("#A.")) { digitalWrite(led, HIGH); delay(1000); digitalWrite(led, LOW); while (Serial.available()) { char inChar=Serial.read(); str[i++]=inChar; if(inChar=='*') { temp=1; return; } } } } } void check() { if(!(strncmp(str,"tv on",5))) { digitalWrite(TV, HIGH); lcd.setCursor(13,1); lcd.print("ON "); delay(200); } else if(!(strncmp(str,"tv off",6))) { digitalWrite(TV, LOW); lcd.setCursor(13,1); lcd.print("OFF "); delay(200); } else if(!(strncmp(str,"fan on",5))) { digitalWrite(Fan, HIGH); lcd.setCursor(0,1); lcd.print("ON "); delay(200); } else if(!(strncmp(str,"fan off",7))) { digitalWrite(Fan, LOW); lcd.setCursor(0,1); lcd.print("OFF "); delay(200); } else if(!(strncmp(str,"light on",8))) { digitalWrite(Light, HIGH); lcd.setCursor(7,1); lcd.print("ON "); delay(200); } else if(!(strncmp(str,"light off",9))) { digitalWrite(Light, LOW); lcd.setCursor(7,1); lcd.print("OFF "); delay(200); } else if(!(strncmp(str,"all on",6))) { digitalWrite(Light, HIGH); digitalWrite(Fan, HIGH); digitalWrite(TV, HIGH); lcd.setCursor(0,1); lcd.print("ON ON ON "); delay(200); } else if(!(strncmp(str,"all off",7))) { digitalWrite(Light, LOW); digitalWrite(Fan, LOW); digitalWrite(TV, LOW); lcd.setCursor(0,1); lcd.print("OFF OFF OFF "); delay(200); } } |