РадиоКот :: Концепт рукотворного умного дома на примере трех конкретных устройств
Например TDA7294

РадиоКот >Статьи >

Теги статьи: Добавить тег

Концепт рукотворного умного дома на примере трех конкретных устройств

Автор: axill
Опубликовано 02.09.2013
Создано при помощи КотоРед.
Участник Конкурса "Поздравь Кота по-человечески 2013!"

Преамбула

Умный дом – что же это такое? Обратимся к Wikipedia и найдем вот такой перевод англоязычного описания:

Переводя на простой кошачий язык и несколько упрощая скажу, что умный дом – это набор заметных и не очень заметных устройств которые делают нашу жизнь дома удобнее, комфортнее и безопаснее.

Причем чем незаметнее устройство и чем оно меньше требует к себе внимания - тем лучше. Построить такой дом на независимых друг от друга устройствах не возможно. Как правило каждая система умного дома имеет некий свой стандарт проводного или беспроводного (или даже комбинированного) обмена данными и событиями между устройствами. Так же как правило система умного дома подразумевает наличие одного или несколько центральных устройств или так называемых контроллеров.

На сегодня существует несколько распространенных систем умных домов. Я обращу внимание на две из них – Z-wave и Zigbee.

Системы эти выделяю по тому, что они наиболее доступны для самостоятельной установки, наверно самые доступные по цене (что не значит, что они дешевые, просто другие дороже), а так же имеют схожие возможности. Обе характеризуются наличием центральных устройств и использованием радио для обмена между компонентами системы. Радио организовано в так называемую mesh есть – это когда передача может осуществляться не только напрямую между двумя устройствами, но и по маршруту на котором другие устройства выступают посредниками. Таким образом системы позволяют на базе маломощных устройств (как правило два устройства напрямую могут общаться на удалении не более 30м без препятствий) можно организовывать сеть теоретически неограниченную геометрическими размерами.

В то же время между системами есть принципиальные отличия. Z-wave закрытый стандарт, а Zigbee opensource. Что это значит? Это значит, что если вы хотите заняться разработкой устройств, то в случае с Z-wave вам сначала нужно стать членом Z-wave Альянса, т.е. если вы простой кот то вам не удастся создать новое устройство для Z-wave. Сейчас правда появились «конструкторы» в виде полу-готовых модулей, но они уже пред-настроены и использовать их можно только в рамках этих настроек. Другая ситуация с ZigBee. Что угодно можно разработать на этом стандарте под себя. Есть удобные для применения модули Xbee-Zigbee от компании Digi.

Плюс Z-wave – готовность к установке конечным пользователем, который не хочет связываться с разработкой устройств. Минус – применять можно только те устройства, которые есть на рынке, что-то специальное или специфичное не получится ни купить ни разработать самому.

Плюс Zigbee – можно создать свое устройство, теоретически какое угодно. Минус – практически отсутствие на рынке готовых устройств.

В свое время, три года назад, меня заинтересовала тема умного дома и так как на тот момент я уже много лет не держал паяльника в руках, выбор был сделан в пользу Z-wave. На базе одного из лучших контроллеров Vera3 от Micasaverde я установил умный дом. В течении года я его строил по кубикам пока не дошел до состояния когда то, что хотелось сделать еще уже сделать на Z-wave нельзя – нет таких устройств. Тема это отдельная, сейчас не об этом. В итоге я пришел к необходимости нарастить мой умный дом кастомизированными устройствами. Тогда-то я и взялся снова за паяльник! :)

Начал я конечно с идеи применения ZigBee и благополучно сделал интеграцию системы против протечки и водяных счетчиков на кухне с моим умным домом применяя Xbee-Zigbee. Но мы же не ищем легких путей! Хотелось сделать что-то более рукотворное (или лапотворное?:) ) Да и цена на продукцию Digi (модули Xbee) не сильно радовала. В какой то момент я обратил внимание на радио модули на базе чипа NRF24L01+.

Не буду вдаваться в описание NRF24L01+ - в интернете достаточно проектов и статей. Модули имеют хорошие характеристики и решают значительную часть обмена на уровне самого чипа, оставляя МК только логику приложения.

Коротко лишь расскажу про свои предварительные изыскания. Чтобы научиться делать устройства общающиеся по радио потребовалось изучить материальную и программную часть. Наиболее продвинутая библиотека для модуля есть для Arduino, написанная maniacbug (https://maniacbug.github.io/RF24/index.html, здесь публикации о применении) . Она была основана на очень старой библиотеки для AVR от Stefan Engelke (https://www.tinkerer.eu/AVRLib/nRF24L01). Искал свежие библиотеки для AVR, пробовал разные пока не нашел два рабочих варианта. Первый – это порт на AVR библиотеки miniacbug сделанную jaseg (https://github.com/jaseg/RF24/tree/avrlibc) и вторая самая свежая но более простая по возможностям - https://github.com/kehribar/nrf24L01_plus от kehribar. Вторая не имеет настройки ряда параметров и совместима по радио с устройствами на Arduino с RF24 только после изменения на Arduino 16 битной контрольной суммы на 8-ми битную. Обе можно использовать, вторая легче портируется (уже содержит программный SPI и достаточно только описать доступ к изменению пинов МК) и чуть меньше по размеру кода. Первая имеет расширенные возможности и привязана к железному SPI atmega (переделать думаю не так сложно).

Все это было вступление, к чему же все это?

Ах да, мы переходим к проекту трех устройств на которых я хотел отработать уже практическое применение. Проект очень специфичен. Как раз это позволяет отработать решения для создания в будущем любого типа устройств.

И так опишем практическую задачу, она относится к автоматизации кухни.

Практическая задача

- полная автоматизация работы вытяжки. Изначально на вытяжке было 4 кнопки для управления подсветкой и тремя режимами вентилятора. Новое устройство должно было быть без кнопок, автоматически включающее подсветку слева/справа (отдельно или вместе) и один из трех режимов вентилятора. Так как старые кнопки теряли смысл, они были убраны, а на их место решено было установить семи-сегментный индикатор с часами;

- безопасная эксплуатация кухни. Был такой инцидент который хорошо закончился, когда забыли на плите кастрюлю. После чего умному дому была поставлена задача обесточивать плиту когда все уходят из дома. Это несколько не удобно – плита после каждого включения по приходу домой думает, что ее только что подключили и просит заново настроить. Задача – сделать логику отключения более «умной». Плита будет обесточиваться только в том случае, если потребление тока её выше порога при том, что умный дом говорит, что «все ушли». Это будет «аварийной» ситуацией о которой тут же можно сообщить владельцу. В противном случае плита всегда будет подключена к сети на что она и рассчитана.

Из задания родились три устройства:

- (1) гейт из сети Ethernet в сеть NRF24. Он потребовался для связи умного дома с двумя следующими устройствами. Статус «все ушли» транслируется на устройство (2). Бонусом в нем появились часики на DS1307, которые по расписанию синхронизируются с NTP сервером через Интернет, а дальше могут служить источником точного времени для устройств в сети NRF24;

- (2) контроллер плиты. Он ставится за плитой, содержит силовые симисторы для управления тремя каналами (плита, левая и правая сторона варочной поверхности). На каждом канале стоит ACS712-20 для измерения тока. Вся измеренная информация передается по радио на устройство (3). Токи управления большие (до 20А в пике, до 15А при эксплуатации), симисторы были установлены на радиаторы с принудительным обдувом. Вентилятор управляется 16-ти уровневым ШИМом, температура так же передается по радио для визуального контроля. Предусмотрено аварийное отключение по превышению температуры;

- (3) контроллер вытяжки. Как вы уже поняли бонусом в нем часы – они синхронизируются по радио с (1). Основная же задача – управления 5-ю силовыми реле в зависимости от того какие параметры прилетели по радио от (2) (два реле для правого и левого светильника и три реле для трех режимов вентилятора).

Ниже схематично показана топология устройств участвующих в проекте:

Подробнее о конструкции устройств. Железо.

(1) Гейт.

Основой для гейта была выбрана Arduino Mega2560 с тремя шилдами – Arduino Ethernet, Arduino TFT и самодельный шилд с DS1307 и сокетом для установки модуля NRF24L01+. Почему ардуино? Наверно по личным причинам. Расширение предполагается значительное, что требует ресурсов (на момент написания статья размер кода 74кБ, в основном пока за счет библиотек). Сам я пока пайку TQFP100 и выше не освоил. Кроме того выбор arduino платформы позволило сэкономить время на разработке для ethernet сети и TFT – есть готовые решения которые работают что называется из коробки.

TFT используется для отображения основных параметров работы, на нем же отображается лог работы – можно увидеть что происходит, какие сообщения обрабатываются и т.д. Управлять гейтом можно через WEB запросы к нему. IP адресс в сети получается по DHCP и отображается на TFT. Все схемы стандартны кроме моего кастомного шилда. Кстати именно этот шилд приведен в пример в моей статье про сверление плат на ЧПУ. Схема шилда простая, приведена ниже.

Стоит обратить внимание на питание. Все платы ардуино мало рассчитаны на питание каких-то внешних цепей по пинам +5В и +3.3В. +5В востребованы как arduino ethernet так и TFT дисплеем. Если использовать встроенный на arduino mega 2560 стабилизатор, то он будет чрезмерно греться. Решается просто - к пину 5В подключаем внешний импульсный Setup-down преобразователь. В моей схеме речь идет о 400-600мА постоянного потребления по цепи +5В. Тоже относится к пину +3.3В - имеющийся на плате меги стабилизатор не в состоянии питать радио-модуль - нужно ставить отдельный стабилизатор, в моем случае он стоит на кастомном шилде. На отладке (без крышки) выглядит устройство так (SIM900 для будущего развития - для уведомлений по SMS):

[2] Контроллер плиты

За основу контролера взят atmega8 с внешним кварцем на 16Мгц. Частота выбрана высокая так как есть необходимость частых измерений значений токов на трех каналах – для этого настроен постоянный цикл измерений ADC с циклическим переключением каналов измерения. Дисплей нокия установлен что называется «для себя», чтобы во время разработки и отладки контролировать весь процесс. Но и в уже готовом устройстве можно увидеть текущий статус, что удобно. Можно ставить, можно не ставить.

Схема разбита на две части – часть МК и часть силовая. Отдельно на третьей плате сделан БП на 12В на базе LNK306 по схеме даташита.

Схема с МК:

Схема с силовыми симисторами и датчиками тока по трем каналам:

Фото в процессе сборки и отладки, видна внутренняя конструкция с радиаторами и вентилятором, виден радио-модуль (справа):

Фото на месте установки за/под плитой, слева сверху торчит черное пятнышко на крышке - это ISP6 для прошивки МК, на дисплее видны все основные параметры, часы сверху по центру считают время в часах/днях/минутах от подачи питания:

[3] Контроллер вытяжки

За основу взят atmega8L с внутренним осциллятором на 8Мгц. Индекс может быть любой, просто нужно было куда то L пристроить :). Для отображения используется свой дисплей – отдельная плата где скомбинирован семи-сегментный часовой индикатор с 4-мя цифрами и четыре RGB светодиода. Три светодиода используются для отображения статуса плиты и двух половин варочной поверхности (зеленый – включены, но нет потребления, голубой – включены и есть потребление, красный – выключены). Один светодиод отображает статус самого контроллера (3) (зеленый – включен свет, голубой – включен вентилятор, красный моргает – пришло сообщение по радио). RGB светодиоды включены с семи-сегментным индикатором в одну матрицу 8 сегментов на 8 цифр и управляются MAX7219. Кроме платы индикатора есть еще две платы – плата с МК и плата силовая с блоком питания. Блок питания тоже сделан на LNK306, но настроен на 5В.

Схема комбинированного дисплея:

Схема модуля с МК:

Схема блока питания на +5В и блока реле:

Фото на месте установки до установки декоративной панели, пришлось попотеть дремелем по выпиливанию окна для установки - метал сдавался с трудом:

Фото на месте установки с лицевой панелью и в работе:

С железом закончили. Сразу скажу – цель этой статьи не описать подробно устройства для повторения, а поделиться практической идее создания подобных устройств. Поэтому во первых не смотрите на применимость (1)/(2)/(3) в вашем доме – я не об этом, не ждите полного описания для повторения. Здесь идеи для воспроизведения в тех устройствах, которые актуальны именно для вас.

Подробнее о конструкции устройств. Программное обеспечение.

Чтож, пора перейти к программной начинке.

Про библиотеки я написал выше. Их я взял за основу. Для AVR выбрал вариант с портом RF24, а для Arduino – оригинальную RF24.

Так выглядит инициализация сети:


После такой инициализации мы готовы получать и отправлять сообщения на наш/с нашего адреса. Адреса задаются 40-битным кодом, который разработчиком назначается каждому устройству. В моем варианте каждое устройство в сети имеет уникальный адрес и пока я использую один pipe. Сам чип поддерживает до 6-ти pipe каждому из которых можно назначить индивидуальных адрес. Для pipe 1-5 верхние 32 бита адреса должны совпадать, Pipe 0 имеет ту особенность, что перетирается openWritingPipe, поэтому для чтения все же удобнее использовать pipes 1-5, оставив для отправки pipe 0.

Внутри основного цикла программы мы вызываем нашу функцию axnet_update. Идея функции update взята у maniacbug из его библиотеки RF24Network, но логика ее развития предполагается другая - не только поддержка комплексной сети с ретрансляцией, но и полноценная поддержка ряда стандартных функций для устройств (об одной функции написано ниже):

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

NRF24L01+ умеет передавать пакеты данных от 1 до 32 байт. Для наших нужд мы определяем структуру с размером 32 байта для максимальных возможностей:

 

 

 

 

 

 

 

 

Поле data мы можем адресовать как массив так и заменить его на какую то специфичную структуру. Например структуру с данными RTC для обмена (1) и (3) или специфичную структуру для обмена (2) и (3). Для этого можно или использовать указатели с преобразованием типа адресуя данные data[20] как другая структура данных либо используя последующее копирования с помощью memcpy().

Логика работы основного цикла (2) такая:

- вызвать axnet_update() и если есть необработанное сообщение то мы смотрим не является ли это сообщение обновлением статуса «все ушли». Если является – меняем. Если другое сообщение – игнорируем. Тип сообщение задается в структуре полем data_type;

- Измерить температуру радиатора охлаждения и задать если нужно режим работы вентилятора. Если температуру превышает критичную – сделать аварийный останов. Измерение тока по трем каналам производится по прерываниям и дополнительных действий в основном цикле не требует. Если статус «все ушли» и токи превышают пороги – сделать аварийный останов. При аварийном останове отправляем сообщение на (1);

- сравнить значения токов и температуры с теми, которые прошлый раз отправили по радио. Если есть заметные изменения – сформировать структуру данных и отправить сообщение на (3). Сообщение отправляется так:

 

 

 

 

 

 

 

 

 

 

- проверить как много времени прошло после последнего получения статуса «все ушли». Если время истекло – сформировать сообщение на (1) с вопросом «какой сейчас статус умного дома?». Полученный потом ответ будет обработан выше по циклу.

Логика работы основного цикла (3) такая:

- вызвать axnet_update() и если есть необработанные сообщения то мы смотрим является ли это сообщением от (2). Если является то проверяем значения токов и температуры на пороги и соответственно управляем лампами и вентилятором, так же отражаем правильный статус на RGB. Инициируем временный показ полученных значений на семи-сегментном индикаторе. Обработка сообщения синхронизации времени уже встроена в axnet_update() и будет обработана автоматически. Так же внутрь axnet_update встроена проверка необходимости периодической синхронизации часов и если нужно – формируется сообщение запрос времени на (1);

- если истекло время показа текущего значения на семи-сегментном индикаторе – переключить на показ следующего значения. При отсутствии информации от (2) показываются по циклу время, дата и год. При поступлении сообщения от (2) последовательно показываются ток плиты (с буквой P спереди и десятичной точкой в амперах), ток левой части варочной поверхности (так же как плиты только буква L), ток правой части варочной поверхности (так же только буква H) и температура (показывается точка градуса на индикаторе справа сверху над третьей цифрой). На время показа параметров яркость MAC7219 повышается;

- проверить не истекло ли время после последнего сообщения от (2). Если истекло, то активируется режим само-отключения - выключается свет, выключается вентилятор и гасятся светодиоды - режим предусмотрен на случай если по какой-то причине (помехи, завис (2) и т.д.) не приходят обновления с (2).

Основной цикл (1) такой


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Я планирую и дальше наращивать библиотеку axnet с тем чтобы программирование конкретного устройства сводилось только к программированию его специфики. Сейчас настройка библиотеки выглядит так:

 

 

 

 

 

 

 

 

AXNET_RADIO активирует работу с nrf24l01+, думаю вряд ли понадобиться когда то ее отключать, но возможность заложена.AXNET_CE_* и AXNET_CSN_* определяют два пина работы с радио-модулем.

AXNET_RTC активирует поддержку часов реального времени на базе DS1307, а так же вставляет необходимую обработку в функцию axnet_update (автоматический запрос синхронизации времени на гейт и далее автоматическая отработка полученных с гейта значений часов).

А вот про AXNET_EEPROM_PARAMS стоит написать отдельно. Это последняя «фича» добавленная перед написанием статьи. Идея концептуальная и думаю будет ключевой в дальнейшем развитии. Если определить AXNET_EEPROM_PARAMS то в библиотеке активируется поддержка управляемых по радио параметрами. Например при каком токе включать третий режим вентилятора на контроллере вентилятора? Изначально это было определено через #define и при изменении требовало перекомпиляции и последующей прошивки. Теперь это иначе. Достаточно в браузере набрать такой линк

http:<(1) IP адрес>/dev//eeparam/setbyname/thr_fun3/120/

Сразу после этого третий режим будет включаться если суммарный ток на двух частях варочных поверхностей достигнет значений 12А (12 умноженное на 10, т.е. параметр задает целым числом с точностью до десятой доли ампера). Что значит этот линк?

- <(1) IP адрес> - IP адресс гейта, т.е. нашего устройства (1). Этот адрес получен по DHCP в домашней сети и отображается на дисплее. MAC адрес задается в программе и может быть привязан к IP на маршрутизаторе (или там где у вас DHCP). Так сделано, чтобы не фиксировать IP в программе;

- dev – это означает, что дальше мы работаем с радио устройствами нашей сети;

- - это шестнадцатеричный идентификатор нашего устройства в сети;

- eeparam – это домен функций, внутри будет несколько функций, данный домен отвечает за работу с параметрами в EEPROM;

- setbyname – название функции в домене eeparam. Суть ее – назначения нового значения параметру используя его имя. В качестве имени используется строка до 8 символов. В будущем будет еще функция setbyindex – установка параметра по его порядковому номеру на устройстве;

- thr_fun3 – собственно имя нашего параметра и 120 – новое значение.

Как же это работает?

В программе устройства мы вставляем такое определение:

 

 

 

 

 

 

 

 

 

 

 

Для удобства я написал два макроса – AXNET_EEPARAM_UINT8 и AXNET_EEPARAM_LIST_UINT8. UINT8 в конце означает, что мы имеем дело с параметром типа uint8_t (на самом деле просто одно-байтный параметр любого типа, хранящийся как uint8_t). Позже будут еще UINT16, UINT32, UINT64 и CHAR8.

Стоит отдельно остановится на каждом макросе.

AXNET_EEPARAM_LIST раскрывается для нашего параметра в такую структуру:

 

 

 

 

AXNET_EEPARAM_LIST_UINT8 раскрывается в структуру типа:

 

 

 

 

 

и заполняется так:

 

 

 

 

 

В итоге в памяти программ мы получаем описание нашего параметра с именем и со ссылками на место хранения как в EEPROM так и в памяти данных.

При старте программы МК устройства мы вызываем:

 

 

при этом значения из EEPROM загружаются в соответствующие переменные в памяти данных. Далее в программе можно использовать значения самих переменных (начинаются на wkee_).

Когда мы вызываем через WEB указанный ранее метод, (1) формирует сообщение со структурой:

 

 

 

 

 

 

 

 

Изначально заложена возможность отправлять уже форматированные данные, для этого используется union. Но на практике гейт не знает формат и сам не может преобразовать строку из браузера в правильное значение. Либо нужно тип указывать в строке браузера либо… ДА! Либо оставить преобразование самому устройству! Оно точно знает какого типа параметр. Это правда требует несколько увеличить код на самом устройстве, зато добавляет универсальности и избавляет от ошибок. В рабочей версии значение параметра передается как строка – поле data.data_char8.

Устройство когда вызывает axnet_update() автоматически делает проверку на наличие сообщение с новым значением параметра. Если оно найдено – параметр автоматически устанавливается, новое значение прописывается в память (переменная wkee_thr_fun3) и в EEPROM (ee_thr_fun3). Все! С этого момента программа работает уже с новым значением параметра и этот параметр сохранится до следующего сообщения либо следующей пере-прошивки EEPROM.

Обратите внимание, что переменные для EEPROM описаны с макросом EEMEM(определен в <avr/eeprom.h>) что означает, что значение по умолчанию которое мы прописали в коде попадает при сборке в файл .eep. Его стоит при программировании загрузить в EEPROM МК.

Демонстрация

Последним штрихом короткое видео работы связки (2) и (3):

Резюме

На конкретном практическом примере можно убедится в жизнеспособности идеи развития "рукотворного" умного дома используя радио-модули на базе чипа nrf24l01+. Последующие устройства приведут как к развитию библиотеки так и к наращиванию функций гейта.

Механизм управления устройствами по радио через WEB позволяет упрощать многие домашние устройства (например часы) и делать их без органов управления (без кнопок и клавиатур) оставив для управления радио и WEB. Конечно без фанатизма, только там, где это удобно.

п.с. идея написать статью родилась спонтанно - изначально я этого не планировал. Очень много потрачено времени на изыскания, я понял для себя, что не поделиться просто нельзя)

п.с. прошу простить мне возможно разноцветный фон изображений - у меня возникли сложности с интерфейсом загрузки файлов в статью и я не смог выровнять цвета фона по всем картинкам.


Файлы:
Изображение


Все вопросы в Форум.




Как вам эта статья?

Заработало ли это устройство у вас?

11 0 0