Удаленное управление устройствами с
помощью микроконтроллера Atmega8 и мобильного телефона, поддерживающего
AT
команды. Технология GSM умный дом.
Практика для студентов. Мясищев
А.А.
1. Постановка задач,
которые должны выполняться устройством
2. Описание работы и
схема устройства
3. Формирование SMS сообщения
4. Программа на Си,
реализующая работу устройства
5. Задание для
самостоятельной работы
1. Постановка задач,
которые должны выполняться устройством
Рассмотрим применение мобильного телефона Mitsubishi Trium Aria и микроконтроллера фирмы AVR ATmega8 для построения простой GSM охранно-информационной
системы с обратной связью. Например, при несанкционированном вскрытии двери
микроконтроллер должен послать на телефон предупреждение абоненту о событии в
виде SMS сообщения. С другой стороны, при дозвоне на
устройство и нажатии определенных клавиш выполняется запрос данных с датчика или передача команды
о включении – выключении заданного удаленного устройства. Для этого телефон,
установленный на удаленном устройстве, должен работать с микроконтроллером по UART, выполнять AT – команды, автоматически поднимать трубку при вызове, а также принимать и
посылать SMS сообщения. Данным требованиям удовлетворяет,
например, телефон Mitsubishi Trium Aria, который был выбран для практической работы.
Для обмена информацией с микроконтроллером телефон использует последовательный интерфейс (UART) по которому отправляется соответствующая команда. Обмен по UART может происходить на разных скоростях так как у телефона есть авто - детектор скорости. Поэтому существует возможность работы на скоростях 9600, 19200, 56000 и 115200 бит/с. Максимальное напряжение, которое подается на вход телефона – 3.3 вольта. В связи с этим устанавливается либо резисторный делитель напряжения, либо резистор и стабилитрон на 3.3 вольта (рис.4). Ввод команды в телефон должен заканчиваться символом перевода строки (в языке Си это /r).
Ниже представлены необходимые для работы устройства AT команды, которые передаются телефону:
AT – простейшая команда. Не делает абсолютно ничего. Если телефон исправен и правильно подключен к компьютеру, то после ввода этой команды и нажатия enter аппарат должен ответить OK.
ATD x; – Заставляет телефон набрать номер x. Если звонок не состоялся (например, нет сигнала базовой станции), то телефон отвечает NO DIALTONE.
ATA – принять вызов. После её выполнения телефон «берёт трубку».
ATH – положить трубку.
AT+CHUP – Отклонить вызов. Эквивалент нажатия красной трубки на клавиатуре аппарата.
AT+CMGF =0
устанавливает режим работы телефона в PDU формате (Для отправки SMS сообщения кириллицей – не
более 70символов).
AT+CMGS=<длина сообщения в формате PDU> - команда отправляющая SMS.
После отправки этой команды нужно передать символ перевода строки. Телефон ответит символом «>». Теперь можно передавать непосредственно сообщение. Сообщение должно заканчиваться символом с кодом 0×1A.(Ctrl/z). Подробнее об использование PDU формата для оповещения через SMS сообщения можно посмотреть здесь.
Конкретизируем задачи, которые должны выполняться устройством:
1. При открывании двери на телефон +380932296723 посылается SMS сообщение - "Сработал концевой выключатель входной двери". Концевым выключателем двери является кнопка PB2.
2. После дозвона на телефон +380632079201 и при нажатии на клавишу 1, на телефон с номером +380932296723 отправляется
SMS сообщение - "Температура ?? град. Кнопки 2- включить, 3-выкл. климат. устройство"
3. После дозвона на телефон +380632079201 и при нажатии на клавишу 2, на телефон с номером +380932296723
отправляется SMS сообщение – "Климатическая установка включена". Сработает исполнительный механизм.
4. После дозвона на телефон +380632079201 и при нажатии на клавишу 3, на телефон с номером +380932296723
отправляется SMS - "Климатическая установка выключена". Исполнительный механизм отключится.
5. При нажатии на кнопку PB1 последние два SMS сообщения не отправляются, и загорается в качестве индикатора светодиод PC1. Для перехода в исходное состояние необходимо нажатие на кнопку RESET.
6. Светодиод, подключенный к порту PC5 микроконтроллера должен мигать один раз в секунду.
Порты микроконтроллера PB0, PD6, PD7 работают на вход, резисторами до 5 вольт не "подтягиваются". В мобильном телефоне должен быть включен автоответ.
2. Описание работы и
схема устройства
Рассмотрим
технологию передачи команд на мобильный телефон устройства, к которому
присоединены исполнительные механизмы со второго мобильного телефона, который
находится у абонента.
Если с телефона абонента на телефон устройства
поступает звонок, то телефон устройства поднимает трубку в режиме автоответа.
При нажатии абонентом клавиш, с его
мобильного телефона поступает многочастотный сигнал. Этот сигнал
называется Dual-Tone Multi-Frequency (двух тональный многочастотный сигнал DTMF). С помощью DTMF декодера BT8870, двух тональный многочастотный сигнал
декодируется в двоичный код, который обрабатывается микроконтроллером ATmega8 и
передается исполнительному устройству. DTMF сигнал состоит из двух
синусоидальных сигналов фиксированной частоты, и легко декодируется в двоичный
код и обратно. Для кодирования символа в DTMF сигнал необходимо сложить два
синусоидальных сигнала. Например, для цифры 5
частота одного сигнала будет 1336 Гц, а другого 770 Гц (рис.1). Этот
же сигнал будет получен на втором
телефоне.
Рис.1. Соответствие между частотами тональных сигналов и клавишами телефона
На рис.2.
показана схема подключения DTMF декодера BT8870 к аудио выходу мобильного телефона
(аналоговый вход микросхемы) и к портам микроконтроллера PORTB.0, PORTD.6 и PORTD.7. На рис.3 показана схема устройства.
Рис.2. Схема включения микросхемы BT8870 - DTMF декодера.
В работе рассматривается передача 3-х команд:
1. При нажатии на
телефоне абонента клавиши 2 включается «климатическая установка» (моделируется
лампочкой, расположенной в непосредственной близости от датчика температуры).
На порт PORTD.6 подается
логический ноль, на порт PORTD.7 – 1.По перепаду сигнала на выводе 15 микросхемы BT8870 с 0 на 1(PORTB.0), данные считываются микроконтроллером с PORTD.6 и PORTD.7. На порту PORTC.2 появляется высокий уровень, который
подается на базу транзистора (рис.3) и происходит срабатывание реле,
включающего лампочку, нагревающую датчик температуры.
2. При нажатии на
телефоне абонента клавиши 3 выключается «климатическая установка». На порт PORTD.6 подается логическая единица, на порт PORTD.7 – также логическая единица. По перепаду
сигнала на выводе 15 микросхемы BT8870
с 0 на 1(PORTB.0), данные
считываются микроконтроллером с портов PORTD.6 и PORTD.7. На порту PORTC.2 появляется низкий уровень, который
выключает лампочку.
3. При нажатии на телефоне
абонента клавиши 1 выполняется пересылка SMS сообщения от устройства на телефон абонента о значении температуры,
снятые датчиком DS18B20.
На порт PORTD.6 подается
логическая единица, на порт PORTD.7 – 0. По перепаду сигнала на выводе 15 микросхемы BT8870 с 0 на 1(PORTB.0), данные считываются микроконтроллером с PORTD.6 и PORTD.7. Программой формируется сообщение вида «Температура
?? град. Кнопки 2- включить, 3-выкл. климат. устройство».
Рис.3. Схема устройства.
3. Формирование SMS сообщения
Рассмотрим формирование SMS сообщения для данного устройства. Например, сформировать сообщение "Сработал концевой выключатель входной двери". PDU сообщение, согласно работе, состоит из двух частей:
PDU = SCA + TPDU, где
SCA
- Service Centre Address - адрес сервисного центра рассылки
коротких сообщений;
TPDU -
Transport
Protocol
Data
Unit – пакет
данных транспортного протокола
SCA состоит из длины поля SCA в hex – 1 байт, типа номера (91h – международный) и преобразованного номера центра рассылки SMS сообщений. Наш номер центра в международном формате: +380639010000. Преобразуем:
1. Убирается +
2. Разбиваем на октеты 38 06 39 01 00 00
3. Переставляются тетрады(полуактеты) 83 60 93 10 00 00
Строим поле SCA:
1. Добавляем к номеру тип номера 91 83 60 93 10 00 00
2. Добавляем длину поля, подсчитывая количество октетов. Октетов 7d или 7h. Окончательно записываем: 0791836093100000
TPDU
состоит из:
1. Поля типа сообщения (11h).
2. Поля MR (00h при
передаче).
3. Поле номера получателя. Для ее получения
необходимо преобразовать номер получателя +380932296723 следующим способом:
3.1. убираем + , разбиваем
на октеты, получаем 38 09 32 29 67 23
3.2. переставляем тетрады:
839023927632, длина номера составляет 12d символов или 0Ch
3.3. добавили
интернациональный тип номера 91h: 91839023927632
и добавили длину, получаем поле номера получателя: 0C91839023927632
4. Поля идентификатора протокола PID (00h).
5. Поля DCS, схема кодирования данных в поле данных. Для кириллицы 08h.
6. Поля VP – времени действия сообщения. Для 4-х дней оно имеет значение AAh.
7. Поля UDL – длина передаваемого сообщения "Сработал концевой выключатель входной двери". Необходимо количество символов сообщения умножить на 2: 43*2=86d или 56h.
8. Поля UD
– поле данных сообщения в коде UTF-8
(UCS2):
0421044004300431043E04420430043B0020043A043E043D044604350432043E043900200432044B043A043B044E044704300
4420435043B044C002004320445043E0434043D043E0439002004340432043504400438
Здесь 0421 – С, 0440 – р, 0430 – а, 0431 – б, … и так далее:
Цифры и латинские символы для кодировки UCS2 можно получить
из кодовой таблицы ASCII добавлением впереди кода двух нолей. Окончательно получаем полное
сообщение:
079183609310000011000C918390239276320008AA560421044004300431043E04420430043B0020043A043E043D04460435
0432043E043900200432044B043A043B044E0447043004420435043B044C002004320445043E0434043D043E043900200434
0432043504400438
Для его отправки необходимо, чтобы микроконтроллер
передал телефону следующие команды:
AT+CMGF=0 // Установка режима работы телефона
в PDU формате
AT+CMGS=100 // Передать сообщение длиной 100
октетов (двойных символов) без учета поля SCA.
Далее передается полученное выше сообщение, которое заканчивается Ctrl/z (см. текст программы).
Сформировать SMS сообщение можно и автоматически, например, как предлагает сайт http://www.twit88.com/home/utility/sms-pdu-encode-decode
4. Программа на Си,
реализующая работу устройства
Ниже представлен текст программы, который написан для компилятора CodeVision AVR фирмы HP InfoTech:
/*****************************************************
This
program was produced by the
CodeWizardAVR V1.25.8 Professional
Automatic
Program Generator
© Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version :
Date : 18.12.2012
Author : F4CG
Company :
F4CG
Comments:
Chip
type : ATmega8
Program
type : Application
Clock
frequency : 7,372800 MHz
Memory
model : Small
External
SRAM size : 0
Data Stack
size : 256
--------------------------------------------------------------------
SMS не посылаются (климатическая установка ...), если горит PC1. Переключается нажатием кнопки PB1. В исходное состояние переводится нажатием RESET.
Концевой выключатель двери соответствует нажатию кнопки PB2.
Порты PB0, PD6, PD7 работают на вход, резисторами до 5 вольт не подтягиваются.
В мобильном телефоне включен автоответ!!!
К порту PB2 подключается концевой выключатель двери.
15 вывод микросхемы ВТ8870 подключается к порту PB0, а 11, 12 выводы соответственно к портам PD6, PD7.
Порт PC2 подключается к базе транзистора исполнительного устройства.
Устройство выполняет функции:
1. При открывании двери посылается на телефон +380932296723 SMS - "Сработал концевой выключатель входной двери".
2. После дозвона на телефон +380632079201 и при нажатии клавиши 1 на телефон с номером +380932296723 отправляется SMS - "Температура 24 град. Кнопки 2- включить, 3-выкл. климат. устройство"
3. После дозвона на телефон +380632079201 и при нажатии клавиши 2 на телефон с номером +380932296723 отправляется SMS - "Климатическая установка включена". Сработает исполнительный механизм.
4. После дозвона на телефон +380632079201 и при нажатии клавиши 3 на телефон с номером +380932296723 отправляется SMS - "Климатическая установка выключена". Исполнительный механизм отключится.
5. При нажатии на кнопку PB1 последние два SMS сообщения не отправляются. Для перехода в исходное состояние необходимо нажатие на кнопку RESET.
6. Светодиод, подключенный к порту PC5, мигает каждую секунду.
*****************************************************/
#include
<mega8.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<delay.h>
#include
<1wire.h>
#include
<ds18b20.h>
unsigned int s=0; // Секунды
unsigned int m=0; // Минуты
unsigned int h=0; // Часы
unsigned int ki=0;
unsigned int pb1=0; // Переменная, фиксирующая нажатие кнопки PB1
// Присваивание строке st1[]: SMSC +380639010000; Получатель +380932296723; Тип номера - интернациональный; Представление данных в коде UCS2(кириллица); Время действия сообщения - 4дня;
// Текст сообщения - "Температура "
char st1[]="079183609310000011000C918390239276320008AA8404220435043C043F04350440043004420443044004300020";
// Текст сообщения - " град. Кнопки 2-включить, 3-выкл. климат. устройство"
char st2[]="00200433044004300434002E0020041A043D043E043F043A043800200032002D0432043A043B044E044704380442044
C002C00200033002D0432044B043A043B002E0020043A043B0438043C04300442002E00200443044104420440043E04390441044
20432043E";
unsigned int temp=0; // Температура
char u_t[]="00";
char
un[]="0020"; // Пробел
char una[]="0020";
// Присвоение чисел от 0 до 9 в формате UCS2.
char
un0[]="0030",un1[]="0031",un2[]="0032",un3[]="0033",un4[]="0034",un5[]="0035",un6[]="0036",un7[]="0037",un8[]="0038",un9[]="0039";
#asm
.equ __w1_port=0x15 ;PORTC
.equ __w1_bit=0
#endasm
// Подпрограмма обработки прерывания в случае совпадения с регистром A для счетчика – таймера 1
interrupt
[TIM1_COMPA] void timer1_compa_isr(void)
{
TCNT1H=0;
TCNT1L=0;
PORTC.5=0; // Включить светодиод 5
delay_ms(50);
// Увеличиваем секунду на 1 в случае появления
// в регистре A числа 7200
s++;
// Горит светодиод на порту PC1, если SMS не посылается
if ( PINB.1==0 && pb1==0 ) // Если нажата кнопка PB1
{
pb1=1;
PORTC.1=0; //Включить PC1, если не посылаются SMS
}
// Условия часов
if(s==60) // Если число секунд = 60
{ m++; s=0;} // к минутам добавляется 1
if(m==60) // Если число минут = 60
{h++; m=0;} // к часам добавляется 1
if (h==24) // Если число часов = 24
{ h=0;m=0;s=0;} // к дням добавляется 1
PORTC.5=1;
// Выключить светодиод 5
if ( s==0 ||
s==15 || s==30 || s==45 )
{ temp=ds18b20_temperature(0);
}
sprintf(u_t,"%2d",temp);
}
void
main(void)
{
// Установка портов
PORTB=0xFE;
DDRB=0x00;
PORTC=0xFA;
DDRC=0xFE;
PORTD=0x3F;
DDRD=0x3F;
//
Timer/Counter 0 initialization
TCCR0=0x00;
TCNT0=0x00;
//
Timer/Counter 1 initialization
// Clock
source: System Clock
// Clock
value: 7,200 kHz
// Mode:
// OC1A
output: Discon.
// OC1B
output: Discon.
// Noise Canceler: Off
// Input
Capture on Falling Edge
// Timer 1
Overflow Interrupt: Off
// Input
Capture Interrupt: Off
// Compare
A Match Interrupt: On
// Compare
B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x1C;
OCR1AL=0x20;
OCR1BH=0x00;
OCR1BL=0x00;
//
Timer/Counter 2 initialization
// Clock
source: System Clock
// Clock
value: Timer 2 Stopped
// Mode:
// OC2
output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External
Interrupt(s) initialization
// INT0:
Off
// INT1:
Off
MCUCR=0x00;
//
Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x10;
// USART
initialization
//
Communication Parameters: 8 Data, 1 Stop, No Parity
// USART
Receiver: On
// USART
Transmitter: On
// USART
Mode: Asynchronous
// USART
Baud Rate: 19200
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x17;
// Analog
Comparator initialization
// Analog
Comparator: Off
// Analog
Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// Глобально разрешить прерывания
#asm("sei")
w1_init();
while (1)
{
if (PINB.0==1) // PINB.0=1 до тех пор, пока нажата кнопка на телефоне абонента
{
delay_ms(500); // Кнопка должна удерживаться более 0.5 секунд
if (PIND.6==1 && PIND.7==0) // Формирование SMS сообщения о текущей температуры в зоне устройства
{
printf("ATH\r"); // Положить трубку
delay_ms(500);
printf("at+cmgf=0\r"); // Перевести в режим PDU
delay_ms(500);
printf("at+cmgs=146\r"); // Передать 146 октетов
delay_ms(500);
// Глобально запретить прерывания
#asm("cli")
// Выделение старшего разряда температуры (десятки) и преобразование его в UCS2 код
if(u_t[0] == '0') strcpy(un,un0);
if(u_t[0] == '1') strcpy(un,un1);
if(u_t[0] == '2') strcpy(un,un2);
if(u_t[0] == '3') strcpy(un,un3);
// Выделение младшего разряда температуры (единицы) и преобразование его в UCS2 код
if(u_t[1] == '0') strcpy(una,un0);
if(u_t[1] == '1') strcpy(una,un1);
if(u_t[1] == '2') strcpy(una,un2);
if(u_t[1] == '3') strcpy(una,un3);
if(u_t[1] == '4') strcpy(una,un4);
if(u_t[1] == '5') strcpy(una,un5);
if(u_t[1] == '6') strcpy(una,un6);
if(u_t[1] == '7') strcpy(una,un7);
if(u_t[1] == '8') strcpy(una,un8);
if(u_t[1] == '9') strcpy(una,un9);
for(ki=0; st1[ki] != '\0'; ki++) putchar(st1[ki]); // Передача первой части сообщения в телефон
for(ki=0;un[ki] != '\0';ki++) putchar(un[ki]); // Передача старшего разряда температуры
for(ki=0;una[ki] != '\0';ki++) putchar(una[ki]); // Передача младшего разряда температуры
for(ki=0;st2[ki] != '\0';ki++) putchar(st2[ki]); // Передача второй части сообщения в телефон
putchar(26); // Передача символа завершения сообщения (Ctrl/z)
// Глобально разрешить прерывания
#asm("sei")
delay_ms(7000); // Даем возможность телефону передать сообщение
printf("ATH\r"); // Положить трубку
delay_ms(500);
}
if (PIND.6==0 && PIND.7==1) // Формирование SMS сообщения на включение климатической установки
{
PORTC.2=1; // Включить установку (подать 5 вольт на базу транзистора с порта PC2)
if (pb1==0)
{
printf("ATH\r"); // Положил трубку перед передачей SMS
delay_ms(500);
printf("at+cmgf=0\r"); // AT+CMGF Перевести в
режим PDU
delay_ms(500);
printf("at+cmgs=78\r"); // at+cmgs=78 - количество переданных байт в десятеричной системе
delay_ms(500);
// Текст сообщения в формате PDU printf("079183609310000011000C918390239276320008AA40041A043B0438043C043004420438044704350441043A04300
44F00200443044104420430043D043E0432043A043000200432043A043B044E04470435043D0430\x1A");
delay_ms(7000);
}
printf("ATH\r");
// Положить трубку
delay_ms(500);
}
if (PIND.6==1 && PIND.7==1) // Формирование SMS сообщения на выключение климатической установки
{
PORTC.2=0; // Выключить установку (подать 0 вольт на транзистор)
if (pb1==0)
{
printf("ATH\r");
delay_ms(500);
printf("at+cmgf=0\r");
delay_ms(500);
printf("at+cmgs=80\r");
delay_ms(500); printf("079183609310000011000C918390239276320008AA42041A043B0438043C043004420438044704350441043A0430044
F00200443044104420430043D043E0432043A043000200432044B043A043B044E04470435043D0430\x1A");
delay_ms(7000);
}
printf("ATH\r");
// Положить трубку
delay_ms(500);
}
}
if (PINB.2==0) // SMS - СРАБОТАЛ КОНЦЕВОЙ ВЫКЛЮЧАТЕЛЬ ДВЕРИ
{
delay_ms(500);
if (PINB.2==0)
{
printf("ATH\r");
delay_ms(500);
printf("at+cmgf=0\r");
delay_ms(500);
printf("at+cmgs=100\r");
delay_ms(500); printf("079183609310000011000C918390239276320008AA560421044004300431043E04420430043B0020043A043E043D044
604350432043E043900200432044B043A043B044E0447043004420435043B044C002004320445043E0434043D043E04390020
04340432043504400438\x1A");
delay_ms(7000);
}
}
};
}
Основой
лабораторного стенда является украинский отладочный комплекс AVR – EASY, который был
дополнен монтажной платой декодера двух
тонального многочастотного сигнала DTMF, платой реле исполнительного механизма, а также платой
подключения мобильного телефона к устройству (рис.5).
Рис.5.
Фотография устройства
Необходимо отметить, что вместо мобильных телефонов, как правило, устаревших конструкций, можно использовать современные бюджетные GSM модули. Например, модуль SIM900D, работу с которым можно посмотреть здесь http://avrproject.ru/publ/kak_podkljuchit/gsm_modul_sim900d/2-1-0-74
5. Задание для
самостоятельной работы
1. Модернизировать схему устройства и программу к нему так, чтобы текущее время и температура высвечивались на LCD индикаторе. Установка времени должна выполняться через порты PA0, PA1. Светодиод, подключенный к порту PC5, должен быть удален.
2. При открывании двери (порт PB2) вместо посылки SMS сообщения должен выполняться один дозвон на телефон абонента.
3. Представить подробный отчет в виде html документа и поместить его на сервере под своим логином.
4. Факультативное задание: Реализовать установку времени на устройстве через SMS сообщение с телефона абонента.