Для управления сценарным освещением, шторами, жалюзи, ролетами и другими элементами «умного дома» используются кнопочные панели.
За основу разработки взята схема и программа описанная здесь, с небольшими изменениями.
Схемы электрические принципиальные.
Оба типа панелей собраны на микроконтроллере ATmega 48. Тактируются микроконтроллеры от внешнего кварцевого резонатора с частотой 14,7456 МГц. Частота выбрана исходя из наименьшего процента ошибок работы модуля USART при различных скоростях передачи данных. Основное отличие этих панелей от описанных выше заключается в использовании драйвера сети RS-485 вместо входных цепей сети 1-wire.
Устройства подключаются к ведущему контроллеру по сети, через разъем XS1. Поскольку, изначально я заложил для кнопочных панелей один кабель «витая пара», а разводка сетей RS-485 не допускает схему типа «звезда», "входящие" сигналы приходят по бело-оранжевой паре, а "исходящие" по бело-зеленой. Кроме того, по бело-синей паре подается плюс 12В напряжения питания, а бело-коричневая пара является общим проводом – «землей». В распределительной коробке устанавливается двойная компьютерная розетка, и линии подключаются по следующей схеме:
Для получения напряжения +5В, необходимого для питания микроконтроллера в устройствах применен интегральный стабилизатор DA1. Напряжение на него подается с ножек 4, 5 разъема через диод VD1, установленный для защиты от переполюсовки напряжения.
Для работы по сети используется драйвер интерфейса RS-485 DA3. Его линии подключены к ножкам USART микроконтроллера. Управляется драйвер (переключение на прием/передачу) с выхода 32 микроконтроллера.
В 8-ми кнопочной панели кнопки подключены к микроконтроллеру по схеме матрицы 2х4. При этом ножки портов PB0, PB1 являются сканирующими выходами, а ножки PB2-PB5 являются сканируемыми входами, на этих портах разрешено прерывание PCI – прерывание по изменению уровня на входе. Это позволяет избавиться от постоянного сканирования клавиатуры, и запускать определение состояния кнопок только при их нажатии и отпускании.
В 4-х кнопочной панели, кнопки подключены непосредственно к портам микроконтроллера на входы прерывания PCI.
Номер нажатой кнопки передается на ведущий контроллер по сети.
Для индикации нажатой кнопки и режима работы системы в устройствах используется светодиоды зеленого и желтого цветов. Для экономии используемых ножек микроконтроллеров, светодиоды подключены по схеме описанной здесь. В 8-ми кнопочной панели установлено 16 светодиодов, в 4-х кнопочной – 8. Включением одного из светодиодов управляет ведущий контроллер по сети.
Для сигнализации о нажатии кнопок, переключении режимов работы, получения команд от ИК ПДУ и т.д. используется звуковой излучатель со встроенным генератором. Формой сигнала управляет ведущий по сети.
Для приема команд от ИК пульта в оба типа панелей встроен ИК приемник DA2. Он может принимать команды от ПДУ, описанного здесь. Подключен приемник к порту PD3 микроконтроллера, на вход прерывания INT1.
Программа микроконтроллера декодирует полученные сигналы по протоколу RC5, выделяет номер системы и команду, и передает их на ведущий контроллер по сети.
Краткое описание программы микроконтроллера.
Все блоки программы микроконтроллера работают на прерываниях, поэтому главная программа представляет собой бесконечный замкнутый цикл.
В главном файле button.asm подключены все файлы программы. Все переменные, используемые в программе, имена портов, команды сетевого обмена и имена регистров определены в файле define.inc. Таблица векторов прерываний и распределение памяти микроконтроллера определенны в файле vectors.inc. Инициализация периферии микроконтроллера находится в файле init.inc. Обработчики прерываний находятся в файле interrupt.inc. Подпрограммы, используемые для вычисления контрольной суммы, сканирования клавиатуры, переключения светодиодов и т.д. находится в файле subr.inc. Макросы описаны в файле macro.inc, а все таблицы хранятся в файле tables.inc.
Распределение памяти.
Для нужд программы в RAM организован буфер обмена размером 9 байт. Поскольку место каждого байта определено, удобно выделить не буфер целиком, а именовать каждый байт отдельно.
Addr_data: .byte 1 ; бит адреса ведущего
Type_data: .byte 1 ; бит типа панели
Button_data: .byte 1 ; бит состояния кнопок
Sus_ir_data: .byte 1 ; бит IR системы
Com_ir_data: .byte 1 ; бит IR команды
Led_data: .byte 1 ; бит управления светодиодами
Sound_data: .byte 1 ; бит управления звуком
Ask_data: .byte 1 ; бит подтверждения приема
CRC_data: .byte 1 ; бит контрольной суммы
При включении питания микроконтроллера, после инициализации периферии, происходит начальная загрузка данных в буфер обмена. Записывается байт адреса ведущего контроллера, тип панели (эти данные в дальнейшем не изменяются), байт подтверждения успешного приема данных и вычисляется контрольная сумма 8 первых байтов буфера.
Кроме того, в RAM выделено два байта для временного хранения данных получаемых по сети.
Область EEPROM в устройствах не используется.
Работа по сети.
Протокол обмена.
В общем виде протокол обмена по сети выглядит следующим образом:
Для запроса данных от кнопочных панелей, ведущий контроллер посылает следующую посылку:
В ответ, адресуемая кнопочная панель передает содержимое своего буфера обмена:
Для случая, если необходимо изменить только один байт данных, например, включить звуковой сигнал не изменяя номер включенного светодиода, предусмотрена команда игнорирования получаемого байта IGN – hFF. То есть если нужно подать два длинных звуковых сигнала не переключая при этом светодиод, ведущий подает команду:
Для записи данных в кнопочную панель, ведущий контроллер посылает в шину следующую посылку:
При приеме данных устройство проверяет входящие данные на ошибки, со стороны интерфейса RS-485 (кадрирование, контроль четности, переполнение), со стороны протокола (номер включенного светодиода не должен превышать 16 для 8-ми кнопочной панели и 8 для 4-х кнопочной панели) и целостность данных по соответствии контрольной суммы. Если ошибок нет, устройство устанавливает в буфере обмена байт Ask = h21 ("!"), иначе, устройство не изменяет состояние регистров данных буфера, а байт Ask = h3F("?"). В ответ на запрос на запись, устройство передает содержимое своего буфера обмена
Для работы с сетью RS-485 используется модуль USART микроконтроллера в полудуплексном режиме (включен либо приемник, либо передатчик). Выводы USART подключены к драйверу сети. Управление драйвером производится с ножки 32 микроконтроллера, настроенного по умолчанию как выход с низким логическим уровнем. При приеме данных на входы управления драйвером подается низкий логический уровень, при передаче – высокий логический уровень.
Прием/передача данных обрабатывается прерываниями USART. Модуль работает в режиме мультипроцессорного обмена, передает/принимает 9 бит данных с включенным контролем четности.
При приеме байта по сети, вызывается обработчик прерывания RX_Ok. В начале обработчика проверяются ошибки при приеме со стороны интерфейса RS-485 (ошибка кадрирования, ошибка переполнения и ошибка контроля четности). Если возникает хотя бы одна ошибка, программа включает светодиод ошибки, устанавливает в буфере обмена признак ошибки приема данных – байт Ask = h3F («?»), включает мультипроцессорный режим и выходит из обработчика прерывания.
Обработка байта адреса устройства.
При отсутствии ошибок, программа проверяет состояние 9 бита и, если он установлен (получен байт адреса), происходит сравнение полученного адреса с собственным адресом устройства. Если адрес не совпадает, происходит выход из обработчика с предварительным включением мультипроцессорного обмена. Если полученный по сети адрес совпадает с собственным адресом устройства, программа выключает светодиод ошибки, включает светодиод приема данных, сбрасывает флаг мультипроцессорного режима, вычисляет контрольную сумму для полученного байта адреса, сбрасывает счетчик переданных/принятых байтов и выходит из обработчика прерывания.
Обработка данных.
Если при проверке, 9 бит данных сброшен (получен байт данных), программа проверяет флаг мультипроцессорного режима. Если флаг установлен, происходит выход из обработчика прерывания, иначе программа обрабатывает полученные данные.
Далее вычисляется контрольная сумма для полученного байта и, в зависимости от состояния счетчика байтов, происходит переход либо к определению полученной команды, либо к обработке данных.
Проверка команд.
Если счетчик байтов равен нулю, программа определяет полученную команду, сравнивая полученный байт данных с командами, определенными в файле define.inc. Если получена команда запроса данных – RD (h3C), программа устанавливает счетчик принятых байтов = 1, ожидает прихода только одного байта – контрольной суммы и выходит из обработчика.
Если получена команда записи данных – WD (h3E), программа устанавливает флаг приема данных, устанавливает счетчик принятых байтов = 3, и выходит из обработчика.
Если будет получен любая другая команда, программа перейдет к обработке ошибки, установить флаг мультипроцессорного обмена и установит признак ошибки Ask = h3F (?).
Обработка команды RD.
При получении команды RD – (запрос на передачу данных) программа проверяет флаг приема данных, и поскольку он не установлен, переключается на передачу. При этом:
- выключается светодиод ошибки;
- включается светодиод передачи данных;
- исправляется контрольная сумма данных буфера обмена;
- сбрасывается счетчик байтов;
- выключается приемник USART;
- драйвер сети RS-485 переключается на передачу;
- включается передатчик USART;
- устанавливается флаг мультипроцессорного обмена;
- происходит выход из обработчика.
Далее, вызывается обработчик прерывания Udr_Ok и данные из буфера обмена передаются по сети. При этом вначале проверяется номер передаваемого байта, если он равен 0 (передается адрес), программа устанавливает 9 бит данных (флаг TXB80 регистра UCSR0B), иначе этот бит, равен 0. Затем происходит вычисление смещения по буферу обмена, относительно счетчика переданных байтов. Данные считываются из RAM и переписываются в USART. Счетчик переданных байтов увеличивается, и проверяется, все ли байты переданы. Если переданы не все байты, происходит выход из обработчика. При передаче последнего байта программа запрещает прерывание по опустошению буфера от USART и разрешает прерывание по окончанию передачи. При срабатывании этого прерывания программа выключает светодиод передачи, выключает передатчик USART, переключает драйвер шины RS-485 на прием и включает приемник USART.
Обработка команды WD.
При получении команды WD – (прием данных), программа проверяет флаг приема данных, и поскольку он установлен, программа определяет, какие данные приняты, по счетчику байтов.
Если счетчик байтов = 3 (принят байт переключения светодиода), программа уменьшает счетчик байтов и проверяет получение команды IGN. Если получена эта команда, программа выходит из обработчика, не выполняя никаких действий. Иначе, происходит проверка на допустимое значение полученных данных. Если номер светодиода больше допустимого (16 – для 8-ми кнопочной панели и 8 – для 4-х кнопочной панели), программа перейдет на обработку ошибки, установит флаг мультипроцессорного обмена и установит признак ошибки Ask = h3F ("?"). Иначе, программа запишет полученные данные в RAM, в ячейку временного хранения данных светодиодов - Temp_Led.
Если счетчик байтов = 2 (принят байт формы звукового сигнала), программа уменьшает счетчик байтов и проверяет получение команды IGN. Если получена эта команда, программа выходит из обработчика, не выполняя никаких действий. Иначе, программа запишет полученные данные в RAM, в ячейку временного хранения данных формы звука - Temp_Sound.
Данные не записываются в буфер обмена, до тех пор, пока не придет байт контрольной суммы. При приеме последнего байта и вычислении контрольной суммы при наличии ошибок в данных регистр контрольной суммы CRC8 (r20) не будет равен нулю и программа перейдет на обработку ошибки, установит флаг мультипроцессорного обмена и установит признак ошибки Ask = h3F ("?"). Если данные были приняты без ошибок, регистр контрольной суммы CRC8 (r20) будет равен нулю. При этом:
- данные из ячеек RAM переписываются в регистры буфера обмена;
- обрабатываются данные в подпрограмме Proc_RecRam;
- устанавливается признак правильного приема данных Ask = h21("!");
- выключается светодиод приема;
- устанавливается флаг мультипроцессорного режима;
- происходит выход из обработчика прерывания.
Обработка принятых данных.
Обработка принятых данных по сети происходит в подпрограмме Proc_RecRam которая находится в файле subr.inc.
Сначала переключаются светодиоды:
- загружается адрес таблицы переключения светодиодов, которая находится в файле tables.inc;
- читается байт данных светодиода из буфера обмена;
- вычисляется смещение по таблице;
- данные из таблицы переписываются в порты управления светодиодами (LedPort – порт DDRC и LedPin – порт PortC).
Далее происходит обработка звука:
- устанавливается счетчик битов звукового сигнала;
- запускается таймер-счетчик 1 (обработка всех следующих битов происходит по прерыванию от переполнения этого таймера);
- читается байт данных формы звукового сигнала из буфера обмена;
- данные сдвигаются вправо через флаг С регистра состояния;
- новые данные сохраняются обратно в RAM;
- в зависимости от состояния флага С либо включается либо выключается звуковой сигнал;
- уменьшается счетчик битов звукового сигнала;
- проверяется, все ли биты обработаны;
- если счетчик битов звука не равен нулю – происходит выход из подпрограммы, иначе, останавливается таймер-счетчик 1, однозначно выключается звуковой сигнал и очищается байт данных звукового сигнала в буфере обмена.
Сканирование клавиатуры.
В обоих типах панелей кнопки подключены ко входам микроконтроллера с прерыванием PCI – прерывание по изменению уровня. Но в 8-ми и 4-х кнопочных панелях процедура определения нажатой/отпущенной кнопки различается.
Обработка нажатия/отпускания кнопок в 8-ми кнопочной панели.
При инициализации периферии микроконтроллера, ножки портов PB0 и PB1 (сканирующие порты) настраиваются как выход с низким уровнем, а ножки PB2 - PB5 (сканируемые порты) настраиваются как входы с подтяжкой. Пока не одна кнопка не нажата, за счет внутренних подтягивающих резисторов на сканируемых входах сохраняется высокий уровень. Кроме того на портах PB2 - PB5 разрешается прерывание по изменению уровня на входе – PCI.
При нажатии любой кнопки, уровень на соответствующем входе сканируемого порта изменяется с высокого на низкий, и вызывается обработчик прерывания PCI. При отпускании кнопки уровень с низкого изменяется на высокий и повторно вызывается обработчик прерывания.
Обработка прерывания PCI происходит по метке Key_Ok.
В этом прерывании включается программное гашение «дребезга» контактов. Для этого используется таймер счетчик 0, который так же используется для работы с ИК приемником:
- запрещается прерывание PCI (таким образом при «дребезге» прерывание не вызывается повторно);
- в счетчик циклов ожидания заносится количество циклов, вычисляемое в файле define.inc (переменная Wait_Key, вычисляемая из времени ожидания гашения дребезга контактов - Time_Wait_Key);
- переключается прерывание таймера 0 с переполнения на совпадение канала А;
- запускается таймер 0;
- на обеих сканирующих линиях матрицы кнопок устанавливается высокий уровень;
- в флаговом регистре устанавливается флаг сканирования клавиатуры;
- запрещается прерывание от ИК приемника (INT1), это сделано для того, чтобы управление с кнопок имело приоритет над управлением ИК ПДУ;
- в буфере обмена очищаются данные номера системы и номера команды, полученные от ИК пульта.
Далее периодически вызывается прерывание по совпадению канала А таймера 0. При обработке этого прерывания уменьшается счетчик Wait_Key и проверяется значение счетчика. Пока счетчик не равен нулю, происходит выход из обработчика прерывания, когда счетчик обнуляется, программа останавливает таймер 0, переключает работу таймера по прерыванию при переполнении, и проверяет флаг обработки кнопок – Keyв флаговом регистре flag_reg. Поскольку этот флаг установлен, происходит процесс сканирования клавиатуры:
- на сканирующей линии PB0 устанавливается низкий уровень;
- загружается адрес таблицы определения нажатой кнопки;
- читается состояние сканируемого порта клавиатуры;
- загружаются данные из таблицы сканирования клавиатуры;
- происходит проверка на окончание таблицы;
- если данные из таблицы не соответствуют окончанию таблицы данных – происходит сравнение состояния порта клавиатуры с данными полученными из таблицы;
- если данные не совпадают, считываются следующие данные из таблицы и цикл повторяется сначала;
- если программа перелистает все данные таблицы и не найдет совпадения, происходит переключение сканирующих портов клавиатуры (при этом на порте PB0 устанавливается высокий уровень, а на порте PB1 – низкий);
- повторяется считывание данных из таблицы сканирования клавиатуры;
- если данные совпадут, из таблицы считывается номер нажатой кнопки и переписываются в буфер обмена и сбрасывается флаг обработки клавиатуры;
- если данные из таблицы не совпадут (нажато несколько кнопок или кнопка отпущена) флаг обработки клавиатуры остается установленным;
- если после сканирования клавиатуры номер кнопки не определен, и флаг Key установлен, байт нажатой кнопки в буфере обмена обнуляется, иначе происходит выход из обработчика прерывания;
- разрешается прерывание от приемника ИК команд;
- на обоих сканирующих линиях устанавливается низкий уровень;
- разрешается прерывание PCI.
Такой алгоритм очень удобен тем, что нет необходимости постоянно сканировать клавиатуру, и при разводке печатной схемы можно подключать кнопки к любому порту как угодно, а затем присвоить свой номер любой кнопке в таблице.
Обработка нажатия/отпускания кнопок в 4-х кнопочной панели.
Так как используется только 4 кнопки, процедура определения нажатия отпускания кнопки проще, чем в 8-ми кнопочной панели.
При инициализации периферии микроконтроллера, ножки PB0 - PB3 (сканируемые порты) настраиваются как входы с подтяжкой. Пока не одна кнопка не нажата, за счет внутренних подтягивающих резисторов на сканируемых входах сохраняется высокий уровень. Кроме того на портах PB0 - PB3 разрешается прерывание по изменению уровня на входе – PCI.
При нажатии любой кнопки, уровень на соответствующем входе сканируемого порта изменяется с высокого на низкий, и вызывается обработчик прерывания PCI. При отпускании кнопки уровень с низкого изменяется на высокий и повторно вызывается обработчик прерывания.
Обработка прерывания PCI происходит по метке Key_Ok. В этой процедуре как и в 8-ми кнопочной панели запускается гашение дребезга контактов. По окончании времени гашения дребезга происходит определение нажатой/отпущенной кнопки:
- загружается адрес таблицы определения нажатой кнопки;
- читается состояние сканируемого порта клавиатуры;
- далее из таблицы считываются данные и сравниваются с данными состояния сканируемого порта;
- при совпадении данных из таблицы считывается номер нажатой кнопки (либо 0 – не нажата не одна кнопка) и переписывается в буфер обмена;
- разрешается прерывание PCI;
- происходит выход из обработчика прерывания.
Программа декодирования ИК команд взята отсюда с небольшими переделками.
Печатные платы, проекты в AVR Studio лежат в архивах, так же выложен проект в Proteus.
4-х кнопочная панель
8-ми кнопочная панель
Проект в Proteus