Светить всегда, светить везде. Начало

db80180a758d48a393c34a5c6ba39fee.jpg

Наверное, это такое психическое расстройство — стремление во что бы то ни стало реализовать что-то свое, желательно с нуля. Особенно приятно предварительно разрушить до основания сделанное предшественниками. Неуемное желание построить собственный велосипед объясняется и тем, что все существующие на текущий момент решения обязательно обладают фатальными недостатками — слишком мало колес, чрезмерное количество педалей, неудобно рулить при посадке задом наперед и так далее. Тут включается буйная фантазия, и через некоторое время мировая общественность оказывается осчастливлена принципиально новым транспортным средством, эксклюзивно адаптированным для двух рептилоидов и одного енота.

Это я собственно к тому, что мне всегда хотелось построить свою систему домашней автоматизации. Наподключать кучу датчиков и исполнительных устройств, настроить нужную непосредственно мне логику работы, и наслаждаться затяжным отловом интересных багов. Конечно, можно воспользоваться готовыми решениями. Сейчас на рынке немало интересных устройств для «умного дома», а уж если подходить к вопросу монументально, то почему бы не построить систему на базе промышленных ПЛК и модулей ввода-вывода? Завести все это добро в SCADA-систему… Довольно заманчиво. Но творческий зуд не позволяет воспользоваться многолетними наработками сотен и тысяч других людей, именно так начинается капоэйра на граблях.

Немного здравого смысла у меня еще осталось. К тому же, из шкафов и с полок на меня периодически с немым укором посматривают незаконченные устройства, до которых я должен добраться «когда-нибудь». Так что, надо поставить себе относительно реальную задачу, решение которой можно довести до логического завершения. Итак, начнем с управления освещением в небольшой городской квартире.

Отталкиваюсь от следующих тезисов:

1) Капитальный ремонт. В плане силовой и слаботочной проводки руки полностью развязаны.
2) Хребет системы — только проводной. Ни на Wi-Fi, ни на 433 МГц в критичных областях не полагаюсь.
3) Минимальное использование готовых устройств и блоков. Для самообразования, прокачки навыков разработки, монтажа, программирования.

Теперь конкретизирую.

1) Основное освещение — светодиодная лента. Лампочки отправляем на свалку истории. Дополнительное освещение — люминесцентные лампы. Это для птичек. Их зрение от нашего изрядно отличается, поэтому для того, чтобы им было хорошо и комфортно, применяются полноспектральные лампы с некоторым количеством ультрафиолета.
2) Включение-выключение (для всех осветительных приборов) и регулировка яркости (для лент) должны осуществляться как вручную, так и программно.
3) Для нештатных ситуаций необходим «железный» обход системы. Грубо говоря, «мозги» отрубились — переходим на ручное управление.

Сейчас я сосредоточен на втором пункте. Здесь выделены следующие задачи:

1) Формирование списка исполнительных устройств. Всего два. Драйвер светодиодной ленты и «реле». В кавычках — потому что по факту оно симисторное.
2) Список управляющих устройств. Тоже два. Регулятор с кнопкой и просто кнопка.
3) Выбор способа связи. На нем нужно остановиться подробнее.

Раз уж я решил, что будут использоваться провода, то вариантов немного. Можно использовать Ethernet. Одна сеть, все на TCP/IP. Заманчиво. Но когда я себе представил микроконтроллер с Ethernet и единственной кнопкой, мне стало немного грустно. Идем дальше, в сторону уменьшения количества проводов и минимизации требований к железу. Готовое решение — DMX512. На низком уровне RS-485, все достаточно просто в реализации, но нет обратной связи. Что еще? CAN? Хороший промышленный вариант, но хочется еще проще. Modbus по RS-485? Уже теплее. Но как же велосипедостроение? К тому же, я уже настроился на использование дешевых микроконтроллеров с минимальной обвязкой. И вот оно, решение. Возьму-ка я RS-485, да придумаю для него свой эрзац-протокол. При этом, правда, надо оставить путь к отступлению. Если закопаюсь, то снова вернусь к рассмотрению Modbus.

Так что, сеть RS-485, мастер — компьютер (малинка, скорее всего), все остальные устройства — ведомые. В плане железа — ATmega328 + MAX485. Контроллер именно такой по причине наличия нескольких штучек, при удачном раскладе в «серийном» устройстве заменяется на ATmega8. Пакет состоит из пяти байт. Адрес устройства, код команды, два регистра данных и контрольная сумма. Ведущий отправляет пакет, все ведомые его принимают и разбирают. Если адрес совпадает и контрольная сумма верная — выполняются определенные действия и отправляется подтверждение. По-моему, проще уже некуда.

За дело я решил взяться «с середины». Силовая разводка и всякие устройства защиты — это потом, поскольку тут все относительно понятно. А вот в проектировании и отладке новых для меня устройств будет много веселых открытий, поэтому я начинаю с железа. А точнее — с двух устройств, регулятора и драйвера светодиодной ленты.

Регулятор

7917b7f950694a2091e4ea5798a23e4d.png

Механический энкодер с кнопкой, микроконтроллер, адаптер RS-485. Сначала реализую связь, потом собственно обработку энкодера. Связь работает следующим образом:

1) При включении устройства значения регистров устанавливаются в 0. Позднее будут загружаться из EEPROM. Адрес забит в коде, и тоже в дальнейшем будет храниться в энергонезависимой памяти (заглушка процедуры смена адреса имеется).
2) В процессе инициализации настраивается режимы работы UART и таймера (используется для прекращения приема по таймауту)
3) На соединенных вместе пинах ~RE и DE адаптера MAX485 низкий уровень — это режим приема.
4) Ожидание приема первого пакета. Как дождались — запускаем таймер и принимаем еще четыре байта.
5) В случае успеха приема пятибайтового пакета и корректной контрольной суммы (это действительно просто сумма, не CRC) пакет можно парсить.
6) При совпадении адреса в пакете с адресом устройства проверяем код команды (второй байт пакета), в зависимости от него выполняем требуемые действия (например, записываем в переменные значения третьего и четвертого байта). В рамках описываемой системы я называю эти переменные регистрами устройства.
7) Отправляем подтверждение: на ~RE и DE высокий уровень, разрешение передачи, отправка пакета (с адресом мастера, каким-то кодом команды и текущим значением регистров устройства).
8) GOTO 3

Таймаут приема отслеживается просто: изначально флаг таймаута — 0. По прерыванию таймера он устанавливается в 1. Этот флаг проверяется в цикле ожидания четырех байтов пакета.

Теперь обработка энкодера. Принцип я почерпнул отсюда.

Вкратце — храним текущее состояние энкодера, по прерыванию таймера считываем новое. В зависимости от того, что изменилось — определяем, куда повернулась ручка и нажималась ли кнопка. Так что, в пункт 2 вышеприведенного списка добавляется инициализация Timer2 с расчетом на то, что прерывание будет происходить примерно с частотой 1 кГц. Плюс, чтобы гарантированно не мешать работе UART, в процессе чтения или записи в 0 выставляется флаг разрешения опроса энкодера (проверяется в обработчике прерывания второго таймера).

Собственно, больше ничего регулятору уметь не нужно.

89867d4491af4f5f8d6fd121df4a0cbd.jpg
Я не описываю ошибки в разводке и другие мелкие неприятности. Отмывать плату тоже пока ни к чему — пару тычков паяльником она еще получит

О граблях на данном этапе

С энкодером у меня была только одна неприятность. Она вообще была связана со всеми устройствами. Периодически в сети возникал лишний нулевой байт, который сильно портил картину. При условии наличия отсутствия осциллографа и логического анализатора, проблему пришлось искать теоретически. Оказалось достаточным подтянуть TX к Vcc, чтобы при переключении «прием-передача» не происходило ненужных процессов.

Драйвер

bf09467d04aa4c73852ee0435cb2a0ee.png

Задачу со связью мы уже решили. Берем то, что касается RS-485 из реализации регулятора и добавляем ШИМ на одном выходе посредством Timer2. Первый регистр устройства отвечает за яркость, второй за включение и выключение выхода как такового. В плане железа — использую уже проверенную схему из двух биполярных транзисторов (раньше были BC639 и BC640, сейчас использую SMD BCP53 и BCP56), на выходе — IRF540. Интересных приколов с драйвером не было, если не считать таковым глючный 12-вольтовый источник питания, работа которого приводила к зависанию всей системы разом.

ab1e8d7876894d25adfbbaed3a5102b6.jpg
Тут тоже немало монтажного безобразия. Ранний прототип, что уж там.

Общие замечания по «железу»

Микроконтроллеры тактируются на 8 МГц без внешнего кварца. Обвязка по питанию состоит из единственного конденсатора на 100 нФ. Вывод ~RST подтянут к питанию через резистор в 10 кОм. Я уже упоминал о том, что стабильность работы кардинально улучшилась после подтяжки TX к линии питания. При сооружении регулятора я не стал полагаться на внутренние подтягивающие резисторы (на пинах, к которым подключен энкодер), а использовал внешние. Больше никаких ухищрений (пока?) не потребовалось. Линия RS-485 подтянута к Vcc (A) и GND (B) через резисторы в 560 Ом со стороны ведущего адаптера, с двух концов терминирована резисторами в 120 Ом.

Проект доступен на гитхабе, структура следующая:

— avr-dimmer — прошивка драйвера (проект Eclipse+AVR);
— avr-encoder — прошивка регулятора;
— host — софт мастера сети (Python), о нем в следующий раз;
— в корне лежат схемы (Eagle) и разводки печатных плат (Sprint Layout 6).

В следующий раз я расскажу о том, что происходит на стороне хоста (мастера сети).

© Habrahabr.ru