Самодельная GSM сигнализация. Пишем управляющую программу.
Содержание
Здравствуйте дорогие друзья, вот, наконец, настают выходные дни, а это значит, что у меня есть немного свободного времени для написания нового интересного поста.
Данная статья, как вы, наверное, уже догадались, будет продолжением одной из моих прошлых статей. Помнится, в той статье я рассказывал о конструкции простой gsm сигнализации.
В этой конструкции основой является управляющая плата с подключенным к ней сотовым телефоном. Впрочем, вернуться к ней не сложно, нужен лишь один клик по ссылке. Так что останавливаться здесь не буду.
Как я и обещал, настало, наконец, время вдохнуть жизнь в бездушный «кусок текстолита» и посмотреть, что же из всего этого получится. Чем мы сейчас и займемся.
Нашей задачей является написать программу для управляющей платки gsm сигнализации. Писать мы ее будем на ассемблере, ибо только ассемблер дает нам полное понимание работы микроконтроллера, ИМХО конечно же.
Что мы имеем
Значит так, в нашем распоряжении текстолитовая печатная плата и старенький, отслуживший свое, сотовый телефон марки siemens. Телефон мы пока отложим в сторону, а вот над платкой будем колдовать. Наша плата имеет входы и выходы. Входные сигналы у нас подаются с кнопки и шлейфного датчика, а на выходе у нас будут соответствующие сигналы с ножек контроллера.
Однократное нажатие на кнопку устанавливает сигнализацию в режим «охрана», повторное нажатие на кнопку переводит нашу сигналку в режим «отбой» или проще говоря снимает ее с охраны. О каждом режиме можно судить по состоянию светодиода. При включении режима «охрана» светодиод загорается, при снятии с охраны (режим «отбой»), светодиод гаснет.
Хочу добавить только то, что должно обязательно срабатывать условие — режим охраны может быть установлен только при цельном шлейфном датчике.
В режиме «охрана» происходит постоянный мониторинг состояний шлейфного датчика, а также контролируется кнопка.
При обрыве шлейфного датчика, мирно горящий светодиод начинает весело мигать, сигнализируя о тревожном событии. На выходе появляются два сигнала: один поступает через транзисторный ключ на динамик, второй воздействует на клавишу сотового телефона. Я пока динамик подключать не буду, а вот с телефоном немного поэкспериментирую.
С составом и устройством платы, все понятно, а вот как написать программу? На этот вопрос нам поможет ответить блок-схема. С блок-схемой мы построим логику работы нашей программы, а там и до программы не далеко.
Логика
Логика нашей программы будет следующей:
Такая получилась у меня блок-схема. Я конечно могу что-то и упустить, так что если есть какие-то неточности то пишите в комментариях, исправлю. Но общий смысл должен быть понятен. Здесь логика состоит в периодической проверке то шлейфа, то кнопки и в зависимости от результата выполняется то или иное действие.
При обработке кнопки программа выполняет задержку, это программная реализация антидребезга контакта при нажатии кнопки.
При подаче питания на микроконтроллер, программой проверяется состояние шлейфного датчика. Задумка состоит в том, что сигнализацию будет невозможно поставить на охрану с разорванным шлейфом. Нажатие на кнопку просто не будет обрабатываться программой. В случае разрыва рабочая точка программы будет возвращаться в начало до тех пор пока шлейф не будет восстановлен.
Если шлейф у нас цел то программа идет на обработку кнопки. И если она не нажата, то рабочая точка также возвращается восвояси, то есть в самое начало. При нажатии кнопки происходит один неприятный момент. Контакт кнопки не может мгновенно замкнуться или разомкнуться. Поэтому возникает контактный дребезг. Серия включений и выключений за короткий промежуток времени, буквально миллисекунды. Для нашей скоростной программы этого может оказаться достаточным чтобы распознать нажатие — отжатие кнопки.
Чтобы это избежать приходится искусственно вносить в программу тормоза, зато кнопочка будет правильно обработана.
Шлейф цел и кнопка нажата? Значит пора зажигать наш светик — все теперь наша охранная система находится в режиме «охрана». А рабочая точка программы идет на следующие рубежи. И теперь нам нужно опять проверить кнопку. Ведь повторное нажатие в нашей программе означает снятие с охраны. Циклы задержки также сопутствуют обработчику кнопки. Теперь нажатие кнопки гасит светодиод и рабочая точка возвращается в самое начало.
Допустим кнопку мы не трогали,а это означает что пришло время судорожно сканировать шлейфовой датчик на случай внезапного вторжения непрошеных гостей. Шлейф цел — программа возвращается к кнопочке и так далее по нашей блок-схеме. При обрыве, на данном участке нашей логики, идет проверка на нажатие кнопки. Кнопка нажата — уходим домой, но если нажатия нет , а обрыв шлейфа зафиксирован, то производится дозвон абоненту и включается мерцание светодиода. И это продолжается до тех пор пока хозяин не нажмет на кнопку и тем самым не отключит «тревогу».
Из алгоритма работы программы понятно , что в устройстве охранной сигнализации кнопка должна быть скрытой от посторонних глаз, эдакая секретка.
Так с логикой разобрались, теперь осталось написать управляющую программу.
Пишем программу
Как я и писал выше программа у нас представляет из себя ассемблерный код, написанный для Attiny45-20. Оформление может и так себе но что есть то есть. В тексте встречаются макросы, они конечно же будут расшифрованы. Еще в программе применяются таймеры и прочие штуки. На комментарии прошу не обращать внимания, все подробности будут дальше по тексту. Хочу лишь добавить что в структуру команд и прочие особенности языка асма я не вдаюсь. Это тема слишком обширна и всего рассказать здесь не смогу.
Итак выкладываю программу по кускам:
;=================================================
;== Программа GSM сигнализации ===
;== Используемый контроллер Attiny45-20PU ===
;==================================================
.include "tn45def.inc" ; Используем Attiny 45 - 20PU
;= Start macro.inc ========================================
; Тут будут наши макросы, потом.
.macro naj //макрос мониторинга нажатия кнопки
clt
in r16, pinb
sbrs r16, 4
set
.endm
.macro otj //мониторинг отжатия кнопки
clt
in r16, pinb
sbrc r16, 4
set
.endm
Строки 1-4. На этом участке кода расположена общая информация о программе. Это позволит нам вспомнить о чем была программа через некоторое время. Кому ассемблер знаком не по наслышке, наверное все это и так понятно, но начинающим думаю будет важна любая информация по теме.
В строке 5 я подключаю библиотеку tn45def.inc. В этом файле расписаны все команды относящиеся к Attiny45. Располагается данный файл в дебрях папок вашего симулятора AVR Studio или какого другого.
В строках 9-21, спрятаны небольшие макросы. В моей программе они участвуют в обработке кнопки, тем самым избавляют от написания повторяющихся участков кода. В дальнейшем, по тексту программы, я могу указывать лишь сами макрокоманды (naj, otj). В тексте программы, (ссылку на которую вы увидите в конце статьи) есть еще парочка макросов, но на них внимания обращать не стоит, они применялись в другом проекте, а здесь они висят мертвым грузом. Вообще полезно накапливать библиотеку макросов и выводить их в отдельный файл, подключая из проекта в проект. Это может значительно облегчить жизнь кодера.
.list ; Включение листинга
.def temp=R16 ; Определение главного рабочего регистра
.def loop=R17 ; определение регистра организации цикла
.def loop1=r18 ;определение регистров
;организации цикла задержки
;для переключения светодиода
.def loop2=r19
.def loop3=r20
.def rab=r21
.def dat=r22
.equ kdel=20
.equ kdel1=1
В этом участке кода первая строка включает листинг. Честно говоря, не знаю для чего он мне нужен, ну да ладно, я его и так не использую. В следующих строчках посредством оператора .def мы привязываем безликим регистрам типа r16, r17 осмысленные имена — повышаем читаемость кода. Регистр temp, будет у нас наиболее эксплуатируемым, заюзаем его под различные промежуточные действия.
Оператор .equ позволяет нам присвоить числовым константам символические метки. И в дальнейшем, применяя эту метку мы можем убивать зайцев в массовом порядке. Так если мы хотим поменять значение константы во всем тексте программы, нам достаточно изменить лишь одну строчку, например .equ kdel=20.
.DSEG ; Сегмент ОЗУ
; FLASH ===================================================
.CSEG ; Кодовый сегмент
.ORG $000 ; Установка текущего адреса на ноль
RJMP Reset ; (RESET)
;вектора прерывания смотрим именно для своей модели микроконтроллера
.ORG $001
RETI ; (INT0) Внешнее прерывание 0
.ORG $002
RETI ; (PCINT) Прерывание 0 по изменению состояния выхода
.ORG $003
RETI ; (TIMER1 COMPA) Совпадение А таймера/счетчика Т1
.ORG $004
RETI ; (TIMER1 OVF) Переполнение таймера /счетчика Т1
.ORG $005
RETI ; (TIMER0 OVF) Переполнение таймера /счетчика Т0
.ORG $006
RETI ; (EE_RDY) EEPROM готово
.ORG $007
RETI ; (ANA_COMP) аналоговый компаратор
.ORG $008
RETI ; (ADC) Преобразование АЦП завершено
.ORG $009
RETI ; (TIMER1 COMPВ) Совпадение В таймера/счетчика Т1
.ORG $00A
RETI ; (TIMER0 COMPА) Совпадение А таймера/счетчика Т0
.ORG $00B
RETI ; (TIMER0 COMPB) Совпадение B таймера/счетчика Т0
.ORG $00C
RETI ; (WDT) Тайм-аут сторожевого статуса
.ORG $00D
RETI ; (USI START) состояние старт USI
.ORG $00E
RETI ; (USI OVF) переполнение USI
На этом участке кода все просто. Рабочая точка стартует с .ORG $000 и сразу улетает по метке reset, пропуская таблицу векторов прерывания. Ведь у нас еще не вся периферия прошла инициализацию. А вектора прерываний нам в этой программе не понадобятся.
Идем дальше…
; Инициализация памяти, стека, регистров========================================
reset: LDI R16,Low(RAMEND) ; Инициализация стека
OUT SPL,R16 ; Обязательно!!!
LDI R16,High(RAMEND)
OUT SPH,R16
RAM_Flush: LDI ZL,Low(SRAM_START) ; Адрес начала ОЗУ в индекс
LDI ZH,High(SRAM_START)
CLR R16 ; Очищаем R16
Flush: ST Z+,R16 ; Сохраняем 0 в ячейку памяти
CPI ZH,High(RAMEND+1) ; Достигли конца оперативки?
BRNE Flush ; Нет? Крутимся дальше!
CPI ZL,Low(RAMEND+1) ; А младший байт достиг конца?
BRNE Flush
CLR ZL ; Очищаем индекс
CLR ZH
CLR R0
CLR R1
CLR R2
CLR R3
CLR R4
CLR R5
CLR R6
CLR R7
CLR R8
CLR R9
CLR R10
CLR R11
CLR R12
CLR R13
CLR R14
CLR R15
CLR R16
CLR R17
CLR R18
CLR R19
CLR R20
CLR R21
CLR R22
CLR R23
CLR R24
CLR R25
CLR R26
CLR R27
CLR R28
CLR R29
Строки 1-6. Далее выполняем одну важную вещь — инициализируем стэк. Стэк это своеобразная оперативная память, устроеннная в контроллере особым образом. Операции со стэком в АВРках используются частенько.
После этого следует глобальная очистка памяти. Ведь никто не гарантирует, что в момент включения, контроллер будет иметь в ячейках своей памяти нули. В ячейках памяти контроллера могут остаться какие-либо значения, поэтому лучше подстраховаться. Очищаем всю оперативную память, включая регистры общего назначения. Теперь можно спать спокойно, точнее будем двигаться дальше.
;Инициализация компаратора====================================
ldi temp, 0x80 ; заносим 0x10000000 в регистр temp
out ACSR, temp ; выключаем компаратор
;Инициализация портов ВВ=====================================
start: LDi temp, 0b11101110 ;записываем число в регистр temp (0b11101111 - порт пб0 на вывод)
out DDRB, temp ;ставим вывод PB4 на ввод, все остальные на вывод
LDi temp, 0b00011001 ;записываем число в регистр temp
out PORTB, temp ;PB0 -> порт на ввод включен подтягивающий резистор (если на вывод т вывод лог 1)
;PB1 -> порт на вывод лог 0
;PB2 -> порт на вывод лог 0
;PB3 -> порт на вывод лог 1
;PB4 -> порт на ввод, включен подтягивающий резистор
;Инициализация таймера Т1=======================================
ldi temp, 0xf;C;b;1
out TCCR1, temp
Инициализируем периферию. В первую очередь отключаем компаратор (строки 2-3), здесь он нам ни к чему. Затем инициализируем порты ввода/вывода. Порты завязанные на обработку кнопки и шлейфного датчика, настраиваем на ввод, остальные послужат нам для вывода информации, будь то светодиод, или вывод на динамик. В строках 16,17 мы инициализируем аппаратный таймер. На таймере будем реализовывать задержки.
С команды rcall opros рабочая точка программы ныряет в подпрограмму обработки шлейфа. В полном соответствии с нашей блок-схемой.
opros:
push dat
clt ;сбрасываем флаг Т
sbic pinb, 0 ;проверка нулевого бита, если бит сброшен (0)то выходим из подпрограммы
;вариант проверки установленного бита -> sbrs temp, 0
;Если бит установлен => шлейф разорван то поднимаем флаг Т
set
pop dat
ret
Если событие есть то поднимаем флаг, если нет то нет. Подпрограмму опроса шлейфа мы разместим в конце нашей программы. Там будут и другие подпрограммы.
Сейчас я вам покажу основной цикл программы. Думаю что основная суть понятна из комментариев и нашей блок-схемы, приведенной выше.
;Начало основного цикла=======================================
nachalo:
rcall opros ;переход в подпрограмму опроса шлейфа
BRTs nachalo ;если обрыв то в начало
naj ;мониторинг кнопки на нажатие
brtc nachalo ;если не нажато то в начало иначе
c: rcall wait ; задержка
otj ;мониторинг кнопки на отжатие
brtc c ; если не отжато то задержка и снова проверка
cbi portb, 3 ;если отжато то сбрасываем бит PB3(зажигаем светодиод)
nop
kn: naj ; мониторим кнопку на нажатие
brtc c1 ; если не нажата то переходим к проверкам шлейфа
c2: rcall wait ; иначе задержка
otj ; мониторинг кнопки на отжатие
brtc c2 ; если не отжато то задержка и снова проверка
rjmp start ; если отжато то в начало
c1:
rcall opros ;переход в подпрограмму опроса шлейфа
BRTc kn ;если не оборван то повторяем мониторинг кнопки сначала
naj ;мониторим кнопку на нажатие
brtc c3 ;если не нажата то переход в с3
c4: rcall wait ; иначе задержка
otj ; мониторинг кнопки на отжатие
brtc c4 ; если не отжато то задержка и снова проверка
rjmp start ; если отжато то в начало
c3:
В строке 4 — вызываем подпрограмму опроса шлейфа, где ставится нужный флаг. Затем в строке 5 анализируется состояние флага.
Далее идет обработка кнопки, но это мы тоже проходили,здесь обработчик спрятан в макрос. Нужные телодвижения, будь то временная задержка или опрос датчика выполняются прыжком в подпрограммы командой rcall.
Ладно, на этом я пожалуй закончу описательную часть кода программы. Основные моменты я показал, так что если есть вопросы или замечания, то прошу писать в комментариях. А здесь я оставлю ссылочку на текст программы, скачать ее можно [urlspan]тут.[/urlspan]
Ах да для зашивки программы в контроллер вам понадобится программатор. Могу посоветовать программатор громова, почитайте о нем, самый простой и практичный программатор.
Также по просьбе читателей размещаю [urlspan]материалы проекта[/urlspan], нарисованные в программе Eagle CAD. В архиве лежит рисунок платы и схема. Рисунок платы немного довел до ума, но пока не изготавливал.
А сейчас я хочу вам показать работу gsm сигнализации в действии, так что смотрим видео…
По-моему получилось не плохо для первого раза, раньше мне видео снимать не приходилось.
Хочу добавить, что данная программа, так же как и проект gsm сигнализации будет постепенно дорабатываться, модернизироваться. Чтобы не пропустить выход новых статей предлагаю подписаться по [urlspan]rss[/urlspan] или по[urlspan] email[/urlspan].
Ну что же дорогие друзья, на этом у меня все. Желаю вам успехов во всем и прекрасного настроения, а всех дам с праздником 8 марта. До встречи.
С уважением, Владимир Васильев.
P.S. Друзья, обязательно подписывайтесь на обновления! Подписавшись вы будете получать новые материалы себе прямо на почту! И кстати каждый подписавшийся получит полезный подарок!
Лучший способ сказать СПАСИБО автору это отправить донат!
Прикольно сделал почитал, очень интересно!! Видео оригинально!!!
Дак я старался, пять дублей записал прежде чем получилось 🙂
Здравствуйте.Я новичок в этих делах.Перерыл разные сайты и из многих именно Ваше устройство мне показалось самым простым в исполнении под мои нужды.Интересуют вопросы:как и чем залить программные файлы в контроллер?все ли файлы из архива будут участвовать в прошивке контроллера?подойдет ли написанная Вами программа под другие контроллеры?если да-то еще под какие (чтоб если что в магазине аналог имеющийся можно было купить)?можно ли взамен разрыва шлейфа установить чувствительный микрофон?Заранее благодарю за ответы.
Это устройство я сварганил из того что было под рукой. Рад что статья заинтересовала. Чтобы залить программу в контроллер, тебе понадобится программатор. Поройся в интернете, есть простые схемы программаторов. Я эту тему только планирую осветить. Для прошивки достаточно файла с расширением .hex.
К сожалению эта прога подойдет только для Аттини 45, впрочем как и все ассемблерные программы затачиваются, как правило, под конкретный камень.
По части микрофона -врятли, так как микрофон аналоговая вещь. Здесь нужен датчик работающий по принципу замкнуто/разомкнуто.
Конструкция, ПО, реальное воплощение в жизнь — на отлично с плюсом!!!!!
Одно «НО», нет номиналов резисторов на сх. А для начинающих — это тёмный
лес.
Всего доброго, успехов. АНДРЕЙ.
Спасибо за комментарий. Изначально при написании этой статьи не стояла задача выложить конструкцию готового устройства доступного для повторения.
Задача была заинтересовать человека, чтобы читатель загорелся и у него появилось желание разобраться в конструкции самостоятельно.
А одноразовое повторение конструкции …это нет.
Не плохо. подпишусь