В этой статье мы расскажем, как создаются устройства Z-Wave. С точки зрения схемотехники и программирования разработка Z-Wave устройства не сильно отличается от разработки устройства на базе Arduino, AVR или PIC. Однако есть в Z-Wave свои нюансы. О них-то и пойдёт речь под катом.


О протоколе Z-Wave я уже писал. Поэтому не буду подробно описывать детали протокола, а пройдусь по аппаратной платформе. Говорить будем только о последнем 5ом поколении чипов и модулей, которые были представлены более двух лет назад.

Железо


Итак, с железной точки зрения чипы и модули Z-Wave — это модернизированное ядро 8051. Чип выполнен в формате SoC, со следующей периферией:
  • 128 КБ флэш памяти для вашего кода,
  • 16 КБ оперативной памяти (XRAM) и 256 байт (IRAM), куда мапятся SFR-регистры,
  • 256 байт NVR (там же хранятся калибровочные данные кристалла и lock bit),
  • 30 GPIO,
  • 2 UART,
  • 2 SPI (Master и Master/Slave),
  • 1 USB (только для Serial),
  • 4 АЦП 12/8 бит,
  • 1 сканер на 88 клавиш (с возможностью сканирования в режиме глубокого сна),
  • 1 TRIAC-контроллер генератор с ZEROX-детектором,
  • 5 ШИМ с разрешением 16 бит,
  • 4 ИК-контроллера и 1 ИК декодер для обучения,
  • загрузчик (включается по пину RESET или из кода записью в соответствующий SFR регистр) для перепрошивки по SPI или UART, а также возможность перепрограммировать себя (перезапись флэш-памяти используется для OTA-перепрошивки),
  • встроенный криптоускоритель для 128-битного шифрования AES,
  • монитор питания (для оценки заряда батарейки).

Питание чипа 2.3–3.6 В. Потребление составляет порядка 15 мА в режиме работы, 35 мА в режиме приёма и до 45 мА в режиме передачи. Также имеется режим глубокого сна с потреблением 1 мкА (пробуждение от INT1) и WUT (+0.7 мкА).

Очевидно, многие функции и ноги пересекаются и недоступны одновременно.

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

Но главное, в чип встроен радио трансивер. Однако доступ к нему осуществляется только через библиотеки Sigma Designs (об этом ниже). Потому много про него неизвестно. Скажем лишь, что
  • чувствительность на рабочей частоте Z-Wave составляет -104dBm,
  • выходная мощность 5dBm,
  • рабочий диапазон 850–940 МГц. (Мы уверены, что больше, но описание RF части вообще отсутствует, потому доступной информации об ином использовании радио трансивера нет. Очевидно, что это типичный SDR-чип, и велосипед Sigma Designs тут не изобретала).

Минимальный «обвяз» для Z-Wave требует лишь кварца (входит в модули), согласование антенны, несколько конденсаторов для стабилизации питания и подтяжка ноги RESET. Большинству устройств Z-Wave ещё требуется минимум 16 КБ EEPROM (для OTA обновления прошивки требуется 128 КБ).

Поставщики

Чипы производятся только Sigma Designs и по лицензии японской Mitsumi. На данный момент выпускается уже 5ое поколение чипов. Очень важным аспектом в развитии Z-Wave является обратная совместимость. Причём не только на программном уровне, но и в плане форм-фактора и характеристик чипов. В линейке новых модулей есть pin-to-pin совместимые со всеми предыдущими поколениями. Это позволяет быстро модернизировать уже производимые устройства без изменения схем и переразводки плат.

Варианты доступных чипов

Z-Wave чипы доступны в двух вариантах:
SD3502, 48-QFN 7x7 мм,
SD3503, 32-QFN 5x5 мм (урезанная версия по сравнению с SD3502).

Также доступны следующие SiP модули, включающие в себя кварц и минимальную обвязку для работы чипа:
ZM5101, 56-QFN 8x8 мм, совместим с ZM4101 (4ое поколение),
ZM5202, PCB 12.5x13.6 мм, на базе SD3502, совместим с ZM3102 (3ее поколение),
ZM5304, PCB 27x15.2 мм, на базе SD3503, включает память EEPROM, SAW-фильтр, спиральную антенну и защитный экран (предназначен для «модемов», т.е. для контроллеров Z-Wave),


И серия от Mitsumi:
WML-C84, 56-QFN 8x8 мм, полный аналог ZM5101,
WML-C85, 56-QFN 8x8 мм, по сравнению с C84 имеет встроенный SAW-фильтр,
WML-C86, 56-QFN 15x15 мм, встроенные SAW-фильтр и EEPROM, увеличенные мощность TX и чувствительность RX, защитный экран,
WML-C87, 56-QFN 15x15 мм, встроенные SAW-фильтр и EEPROM, увеличенная чувствительность RX, защитный экран.


У разных вариаций модулей «отрезаны» разные ноги и функции. Выше были указаны доступные функции «полной» версии, т.е. SD3502, а также ZM5101 и WML-C84/C85.

Модули со встроенным SAW-фильтром идут в трёх вариантах в зависимости от региона (т.е. диапазона частот): EU/RU/CN/MY/UAE/IN, US/IL и ANZ/BR/JP/TW/HK/KR.

Многие из этих модулей можно купить даже на DigiKey. Однако чипы Sigma Designs продаёт только на большом объёме по особой договорённости.

Кстати, некоторые производители делают свои модули. Например, Philio Tech делает MD003 (аналог ZM5304 на базе SD3503, но без антенны), MD006 (на базе SD3503) и MD008 (что-то среднее между ZM5101 и ZM5202 на базе SD3502). На КДПВ устройство Philio PST-02 на базе MD008.

DevKit

Sigma Designs также предлагает комплект разработчика. Сюда входит:
  • набор чипов разных форм-факторов в том числе на платах разработчика, которые устанавливаются прямо на программатор (очень удобно для прототипирования),
  • программатор (Z-Wave чипы программируются специальным программатором — на рынке есть выбор: вот этот от Sigma Designs, более подходящий для производства от нас, Z-Wave.Me и совсем промышленный от Equinox),
  • сниффер (для прослушки эфира — просто необходимая вещь при отладке устройств),
  • USB-стик для центрального контроллера,
  • несколько датчиков и исполнителей,
  • ПО под Windows для программатора, сниффера, контроллера, а также всякие вспомогательные утилиты,
  • Z-Wave SDK для создания прошивок для чипов Z-Wave (об этом ниже),
  • всякие провода и блоки питания.

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


Стоимость кита от $1500 до $3500 в зависимости от количества плат разработчика и программаторов и наличия или отсутствия датчиков/исполнителей.

Легальная сторона

Патенты, лицензии и NDA не позволяют использовать чипы и модули Z-Wave для иных целей, кроме как для Z-Wave. Также Z-Wave устройства нельзя делать не на чипе Z-Wave (напомню, два уровня OSI имеют запатентованный функционал, что не даёт возможности создать полноценный стек Z-Wave без разрешения Sigma Designs). Это позволяет Sigma Designs включать стоимость лицензии (т.е. плату за развитие протокола, ПО, утилит, маркетинг) сразу в стоимость чипов и модулей.

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

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


Типичная схема

Вернёмся к железу. Типичная схема подключения ZM5101 выглядит следующим образом:


В роли NVM выступает SPI EEPROM или FLASH память минимум 16 КБ. Она необходима для хранения данных об узлах сети, маршрутах и прочее. Есть возможность создавать устройства без внешней EEPROM (при этом под память используется блок флэш-памяти, что уменьшает пространство для кода). EEPROM занимает один SPI и одну ногу для CS. Ноги SPI можно без проблем использовать как GPIO или для подключения другого SPI Slave, пока CS поднят к 3.3 В. Через этот же SPI происходит программирование чипа Z-Wave, когда RESET подтянут вниз. Именно для этого нужна подтяжка на CS (ZM5101 становится SPI Slave, и второй Slave тут явно не нужен).

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

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

Допустим, мы хотим создать сложное устройство: 3 реле (через сборку дарлингтона ULN2003, так как предельного тока 20 мА с ноги ZM5101 недостаточно для электромагнитного реле, да и это позволит питать реле от 5 В или 12 В), один датчик сухих контактов, датчик освещённости (фоторезистор) и красиво мигающий трёхцветный светодиод. Всё это можно сразу подключить к чипу Z-Wave:
  • 3 входа реле посадим на GPIO, например, P2.0, P2.1, P2.5 (ноги P2.2–P2.4 занимает EEPROM, подключенная по SPI)
  • датчик сухих контактов подключим к INT0 (P1.0), INT1 (P1.1) или любой другой ноге GPIO, если планируется простой опрос, а не ISR-обработчик,
  • датчик освещённости в составе делителя подключим к ADC0, она же P3.4 (второе плечо нужно подобрать так, чтобы уложить все возможные значения в диапазон 0–3.3В),
  • наш трёхцветный светодиод подключим к PWM0–2 (P0.4–P0.6), что позволит плавно менять цвета в режиме новогодней гирлянды.




Заметьте, у нас осталась ещё куча (18) ног! Для сравнения, 3ее поколение чипов и модулей Z-Wave (ZM3202) не позволяло подключить даже такого скромного набора периферии.

Прошивка


GPIO ноги в чипах Z-Wave, как и в других 8051 объединены в порты по 8 штук. Один SFR отвечает за режим (in/out), другой позволяет включить pull-up для режима in, третий для чтения/записи значения. Timer, UART, SPI и другие функции тоже похожи на другие 8051: TMOD/THx/TLx, UARTCON/UARTBUF/UARTSTAT, SPIxCON/SPIxDATA/SPISTAT,… Всяких регистров так много, что в 5ом поколении чипов пришлось ввести регистр SFRPAGE для переключения между страницами маппинга SFR на IRAM. Размер флэш памяти 128 КБ также потребовал использования банков памяти, что существенно усложняет транслированный код, наполняя его множеством переходов из банка в банк через COMMON BANK.

В теории для работы с чипом Z-Wave можно было бы использовать любой компилятор, например, SDCC (под GNU/GPL). Но увы документации на все эти порты, регистры, маппинг внутренней памяти и прочее нет. Вместо этого Sigma Designs выбрала другой путь: поставлять в бинарном виде пре-компилированную библиотеку (а на деле набор библиотек под разные классы устройств: под контроллеры, под датчики/исполнители, под шлюзы). Эти библиотеки, собранные под вполне конкретную версию Keil, предоставляют разработчикам удобный API как для работы с железом (фактически, wrapper'ы для обращения к SFR), так и для более сложных операций с сетью Z-Wave: отправки команд другим узлам, обслуживание сети Z-Wave, обновления маршрутов и прочее. Данная библиотека реализует следующие уровни протокола Z-Wave: PHY (непосредственно кодирование и декодирование на нужной частоте, выбор канала передачи, LBT), MAC (контроль ошибок, адресация в пределах зоны видимости), транспортный (подтверждения, повтор) и сетевой (маршрутизация, ретрансляция, обновление маршрутов, поиск новых маршрутов, включение в сеть, удаление из сети).

Именно Sigma Designs занимается совместимостью на этом уровне, обеспечивая развитие протокола и преемственность. К плюсам такого подхода стоит отнести гарантированную совместимость между Z-Wave устройствами и простоту работы на «верхнем» уровне, к минусам — низкую скорость реакции на найденные ошибки.

Для взаимодействия с сетью Z-Wave пользователю разработчику остаются лишь простые функции для взаимодействия с другими узлами. Однако стандарт требует жёсткой совместимости и на уровнях выше: сеансовом, представительском и прикладном. Эти уровни уже во власти разработчиков конечных устройств. Библиотека позволяет узлу А отправить команду узлу Б. При этом команда должны иметь строго определённый формат, описанный протоколом Z-Wave в разделе Command Classes Specification (около 900 страниц текста). Это позволит узлу Б правильно разобрать команду и выполнить соответствующее действие с периферией.

Библиотеки Z-Wave выполнены в формате «callback». Точка старта (main) находится в библиотеке, а управление пользователю передаётся только в определённые моменты:
  • при старте (две точки входа — сразу после старта чипа для инициализации железа и позже, когда библиотека инициализировалась и можно уже некоторыми её функциями пользоваться — аналог setup() в Arduino,
  • когда библиотека не занята (приёмом/отправкой данных, пересылкой пакетов других узлов сети, ответом на запросы контроллеров) — здесь можно опрашивать кнопки, измерять значение на АЦП и т.д. — аналог loop() в Arduino,
  • когда получена команда (где получатель именно мы, CRC сошлась и отправитель из нашей сети).

Во все функции, требующие времени и работающие «асинхронно», можно тоже передать callback. Например, при вызове функции отправки пакета можно указать обработчик, который получит статус отправки (доставлен, не доставлен и код ошибки). Аналогично выполнена подсистема таймеров (помимо точных на базе TIMER1 и GPT): можно запустить до 5 программных таймеров, которые работают с шагом 10 мс (TIMER0 использовать нельзя, его использует библиотека для внутренних нужд и программных таймеров). Всё это облегчает работу программистам производителя конечного устройства.

Вместе с библиотеками Z-Wave также поставляется огромное множество предопределённых в заголовочных файлах структур и констант, соответствующих стандарту, что существенно упрощает разработку. Также Sigma Designs поставляет два десятка примеров, реализующих простые устройства, например, реле или бинарный датчик или дверной замок, с минимальным функционалом, необходимым для работы и прохождения сертификации Z-Wave Plus. Забавно, но более половины устройств Z-Wave, выпускаемых в поднебесной, основаны на этих примерах без единой изменённой строчки, кроме идентификаторов ManufacturerId, ProductId, ProductTypeId (речь про идентификаторы производителя, серии и модели; они для сертификации должны быть уникальными, так что если бы не это требование, то они бы вообще не отличались ;)

Совокупность всех заголовков, библиотек и sample code составляет Z-Wave SDK или ZDK. ZDK распространяется под NDA. Обычно NDA подписывается при приобретении DevKit.

Как уже было сказано ранее, для разработки собственного устройства нам понадобится ещё Keil C51. Стоит примерно 2600 Евро. Но это ещё не все траты, нас ждёт ещё один этап.

Классы команд и NIF

Помимо программирования логики работы с периферией необходимо объявить список поддерживаемых классов команд создаваемого устройства в NIF, а также реализовать объявленные классы команд (подробней о классах команд читайте в этой статье). Фактически это сводится к написанию кода, обрабатывающего все возможные команды всех поддерживаемых классов.

Например, для класса Switch Binary (ID 0x25) необходимо обработать команду Set (25 01), включив реле или светодиод или что-то там ещё, команду Get (25 02), ответив на неё командой Report (25 03 xx), где xx = 00 или FF в зависимости от текущего состояния реле, лампочки или что у вас там.

Для нашего примера «сложного» устройства это будет выглядеть как-то так
Псевдокод обработчика
NIF будет содержать 0x25 (SwitchBinary), 0x26 (SwitchMultilevel), 0x30 (SensorBinary), 0x31 (SensorMultilevel), 0x60 (MultiChannel) и десяток других служебных классов, нужных лишь для служебных задач и настройки.

switch (pCmd[0]) {
  case COMMAND_CLASS_MULTI_CHANNEL:
    switch (pCmd[1]) {
      case MULTI_CHANNEL_CMD_ENCAP:
        switch (pCmd[4]) {
          case COMMAND_CLASS_MULTI_SWITCH_BINARY:
            // проверить номер канала
            if (pCmd[3] == 1) {
              switch(pCmd[5]) {
                case SWITCH_BINARY_SET:
                  pin_set(P2_0, pCmd[6] ? 1 : 0);
                  break;
                case SWITCH_BINARY_GET:
                  // первые параметры: кто запросил; канал того, кто спрашивал; наш канал; класс команд; команда; ... данные
                  SendMultiChannelReport(srcNodeId, pCmd[2], pCmd[3], COMMAND_CLASS_MULTI_SWITCH_BINARY, SWITCH_BINARY_REPORT, pin_get(P2_0));
                  break;
              }
            }
            if (pCmd[3] == 2) {
              switch(pCmd[5]) {
                case SWITCH_BINARY_SET:
                  pin_set(P2_1, pCmd[6] ? 1 : 0);
                  break;
                case SWITCH_BINARY_GET:
                  SendMultiChannelReport(srcNodeId, pCmd[2], pCmd[3], COMMAND_CLASS_MULTI_SWITCH_BINARY, SWITCH_BINARY_REPORT, pin_get(P2_1));
                  break;
              }
            }
            if (pCmd[3] == 3) {
              switch(pCmd[5]) {
                case SWITCH_BINARY_SET:
                  pin_set(P2_5, pCmd[6] ? 1 : 0);
                  break;
                case SWITCH_BINARY_GET:
                  SendMultiChannelReport(srcNodeId, pCmd[2], pCmd[3], COMMAND_CLASS_MULTI_SWITCH_BINARY, SWITCH_BINARY_REPORT, pin_get(P2_5));
                  break;
              }
            }
            break;
          case COMMAND_CLASS_MULTI_SENSOR_BINARY:
            if (pCmd[3] == 4) {
              switch(pCmd[5]) {
                case SENSOR_BINARY_GET:
                  SendMultiChannelReport(srcNodeId, pCmd[2], pCmd[3], COMMAND_CLASS_MULTI_SENSOR_BINARY, SENSOR_BINARY_REPORT, SENSOR_BINARY_TYPE_GENERAL_PURPOSE /* датчик общего назначения */, pin_get(P1_0));
                  break;
              }
            }
          case COMMAND_CLASS_MULTI_SENSOR_MULTILEVEL:
            if (pCmd[3] == 5) {
              switch(pCmd[5]) {
                case SENSOR_MULTILEVEL_GET:
                  SendMultiChannelReport(srcNodeId, pCmd[2], pCmd[3], COMMAND_CLASS_MULTI_SENSOR_MULTILEVEL, SENSOR_MULTILEVEL_REPORT, SENSOR_MULTILEVEL_TYPE_LUMINESENCE /* освещённость */, 0 /* целое в % */, analog_get(P3_4));
                  break;
              }
            }
          case COMMAND_CLASS_MULTI_SWITCH_MULTILEVEL:
            if (pCmd[3] == 6) {
              switch(pCmd[5]) {
                case SWITCH_MULTILEVEL_SET:
                  pwm_set(P0_4, pCmd[6] > 99? 99 : pCmd[6]);
                  break;
                case SWITCH_MULTILEVEL_GET:
                  SendMultiChannelReport(srcNodeId, pCmd[2], pCmd[3], COMMAND_CLASS_MULTI_SWITCH_MULTILEVEL, SWITCH_MULTILEVEL_REPORT, pwm_current(P0_4));
                  break;
              }
            }
          case COMMAND_CLASS_MULTI_SWITCH_MULTILEVEL:
            if (pCmd[3] == 7) {
              switch(pCmd[5]) {
                case SWITCH_MULTILEVEL_SET:
                  pwm_set(P0_5, pCmd[6] > 99? 99 : pCmd[6]);
                  break;
                case SWITCH_MULTILEVEL_GET:
                  SendMultiChannelReport(srcNodeId, pCmd[2], pCmd[3], COMMAND_CLASS_MULTI_SWITCH_MULTILEVEL, SWITCH_MULTILEVEL_REPORT, pwm_current(P0_5));
                  break;
              }
            }
          case COMMAND_CLASS_MULTI_SWITCH_MULTILEVEL:
            if (pCmd[3] == 8) {
              switch(pCmd[5]) {
                case SWITCH_MULTILEVEL_SET:
                  pwm_set(P0_6, pCmd[6] > 99? 99 : pCmd[6]);
                  break;
                case SWITCH_MULTILEVEL_GET:
                  SendMultiChannelReport(srcNodeId, pCmd[2], pCmd[3], COMMAND_CLASS_MULTI_SWITCH_MULTILEVEL, SWITCH_MULTILEVEL_REPORT, pwm_current(P0_6));
                  break;
              }
            }
            break;
        }
    }
}

Как видно, мы тут обработали 8 каналов разных типов.

(Это сильно упрощённый для понимания код, но основная идея сохранена. Мы, конечно, не так пишем — просто решили вас не пугать и NDA лишний раз не нарушать. Подробности тут.)

Очевидно, все устройства должны более-менее одинаково обрабатывать эти команды. 3 года назад мы неплохо шаблонизировали наш код, создав общую базу кода (code base) наших устройств. Многие наши устройства отличаются только одним .h файлом. Более сложные имеют ещё пару сишников для спец. функционала. С выходом 5-ого поколения чипов Sigma Designs сделала нечто похожее, так что код примеров легко адаптировать под свои нужды.

Сертификация


После того, как вы придумали устройство, сделали опытный образец, написали для него прошивку, необходимо сертифицировать ваше устройство. Процесс сертификации необходим для проверки соответствия вашего устройства протоколу Z-Wave, состоит из двух частей: Technical Certification (проверка самого устройства) и Market Certification, где также проверяется документация (упоминание ключевых терминов Z-Wave), наличие и корректность использования логотипа Z-Wave или Z-Wave Plus.

Z-Wave сертификация проводится одним из трёх центров сертификации: Pepper One в Германии, BuLogics в США или в самой Sigma Designs. Перед сертификацией требуется пройти процесс сертификации самостоятельно (self-certification), что позволяет сразу же обнаружить и устранить многие ошибки, а также уменьшить вероятность фэйла на сертификации. Для этого есть специальная утилита CTT, доступная полноправным членам Z-Wave Альянса. Её же используют сертификаторы. Также существует сертификационная форма (в зависимости от устройства в ней от 100 до 300 пунктов), по которой нужно описать устройство. По этой форме будет проходить сертификация. Для всех пунктов есть подробное описание, как тестируется и что ожидается от устройства. Стоит отметить, что весь процесс достаточно прозрачен — заранее понятно, что и как будут проверять (если все доки заранее прочесть ;)

Сертификация — процесс трудоёмкий и кропотливый. Сертификация также стоит денег: в зависимости от сложности устройства от $3000 до $5500. Тут всё примерно как на экзаменах в ГИБДД: допускается какое-то разумное количество fail'ов, которые требуется устранить в течение месяца (так называемый ad-hoc период). Если фэйлов больше или не получилось исправить, то потребуется повторная сертификация с новой оплатой. Это неплохо стимулирует хорошо проверять свои устройства. Лично мы зафэйлились только один раз, но он сильно подбил наше самолюбие.

Существенные изменения в функционале устройства или поведении в сети Z-Wave требуют повторной сертификации (re-certification, стоит половину цены). Нередко одно устройство без изменений продаётся в разных вариантах и цветах. В этом случае нужно только повторить Market Certification (бесплатно).

Опять же на примере нашего «сложного» устройства, CTT увидит, что мы в классе SwitchMultilevel не обрабатываем команды StartLevelChange и StopLevelChange, необходимые для диммирования. Если мы это не исправим, то сертификацию наше устройство не пройдёт. (Мы просто не хотели увеличивать итак страшный кусок кода обработчика).

Также заметим, что сертификация (и CTT) доступны только полноправным членам Z-Wave Альянаса (Full или Principal Member, но не Affiliate Member). Это ещё $4000 в год.

Отладка


Сразу замечу, что JTAG или иного средства отладки в чипе Z-Wave нет! Это делает жизнь разработчиков ужасной и невыносимой. Поэтому нередко сложный код тестируется и отлаживается сначала на каком-нибудь чипе семейства 8051 от, например, Silicon Labs, которые не поскупились на нормальный JTAG или C2, удобно интегрируемый во встроенный в Keil отладчик. Также части кода мы тестируем, собирая его на Linux с gcc и прогоняя различные тесты (так, например, мы тестируем наш движок очереди пакетов на отправку в устройствах). Это не даёт возможности поймать переполнения свойственные самой архитектуре микроконтроллера (например, вылезание за пределы маленького стека, нехватку регистров при рекурсивных или просто глубоко вложенных вызовах функций) или отладить код, связанный с SFR или аппаратной частью чипа, но базовые «платформо-независимые» проблемы легко отлавливаются. Нередко приходится ковырять ASM-код (d52 наше всё!), а также использовать удобные средства самого Keil с map-файлами.

В остальном приходится довольствоваться отладкой через I2C, SPI или UART (что работает для простых проблем, когда не происходит порчи стека или памяти из далёких кусков кода).

Отдельным упражнением является создание устройств, работающих от батареек — для понижения энергопотребления требуется писать качественный код, учитывающий время работы долгих операций (АЦП, отправка по радио, доступ к EEPROM) и расположение переменных (256 байт XRAM питаются даже в режиме глубокого сна, позволяя при просыпании не читать медленную EEPROM, а быстро принять решение и уйти спать дальше).

Сложные устройства


При создании более сложных устройств, для которых требуется много ног, бывает необходимо использовать несколько чипов, общающихся по UART, SPI или I2C. В этом случае часть функционала работы с периферией (или весь) переходит на второй чип. Очень удобным бывает использование более продвинутого в плане возможностей периферии и энергопотребления Atmel (с пониженной частотой) или Cortex. Такой подход позволяет использовать Z-Wave чип только как «модем».

Z-Wave Serial API

Частным случаем такого подхода является использование Z-Wave чипа совместно с другим CPU с полноценной ОС (например, PC или Raspberry Pi). Дабы не толкать производителей изобретать велосипед, Sigma Designs предложила свой стандарт для обмена данными между CPU и чипом Z-Wave по UART, который называется Z-Wave Serial API. В этом случае прошивка реализует UART обмен данными, отображая почти 1:1 все доступные разработчику функции на Serial API команды от CPU, а возврат значений и callback через команды к CPU. Пример такой прошивки имеется в ZDK и доступен всем разработчикам. Такой подход позволил создать «рынок» USB-стиков Z-Wave отдельно от «рынка» софта для них: множество производителей предлагают взаимозаменяемые стики, в то время как производители ПО создают софт, работающий с любым стиком. Именно такой софт под название Z-Wave PC Controller входит в ZDK (доступен в сурсах).

Кроме того, этот подход способствует распространению технологии: производитель TV-приставки или роутера, создав решение на базе стороннего Z-Wave USB-стика, с ростом объёма продаж может решить заказать партию PCB с установленным Z-Wave модулем, удешевив тем самым решение. В этом случае чаще всего используется модуль ZM5304 (в ZDK есть прошивка для него, реализующая Serial API).

Однако некоторые компании, производящие и железо, и ПО (к ним и мы относимся с нашими стиками UZB, платами расширения RaZberry и нашим ПО Z-Way) предпочитают «привязывать» софт к стикам, так как в этом случае меньше поддержки (мы, например, устраняем многие проблемы кода Sigma Designs и дополняем его своими расширениями) и проще собирать деньги за ПО (стоимость уже включена в стик). Иные (например, Merten) вообще создали свой собственный формат обмена данными отличный от Z-Wave Serial API.

Обучение и поддержка


За каждым регионом закреплены несколько FAE от Sigma Designs. Они помогают новым производителям начать работу с Z-Wave, принимают bug report'ы и помогают со спорными ситуациями в процессе сертификации.

Z-Wave Альянс также активно участвует в жизни производителей, предлагая не только утилиты для тестирования и обучающие материалы. Несколько раз в год в разных частях света Альянс собирает разработчиков на конференции UnPlug Fest для обмена опытом и тестирования своих устройств другими участниками. В этих мероприятиях также принимают участие FAE Sigma Designs. UnPlug Fest всегда сопровождается двухдневным тренингом для новых разработчиков.

Также Z-Wave Альянс организует работу Interoperability Lab в Нью Джерси, США, где можно протестировать свои устройства как на совместимость, так и в специальной радио-лаборатории.

Кроме того в Альянсе есть рабочие группы по развитию протокола Z-Wave. Все разработчики могут предлагать свои идеи и влиять на функционал следующих версий всех классов команд и протокола в целом.

Более подробную информацию можно получить на сайте Z-Wave Альянса.

Ещё немного о деньгах


Вернёмся к вопросу экономики и посчитаем, что сколько нам будет стоить в расчёте на устройство. Я сделаю это очень грубо и оценочно — не судите строго. Детальный финансовый анализ не является целью данной статьи. Для оценки я даже положил €=$ (да простят меня брокеры).

Представим, что мы собираемся выпустить 5000 устройств какого-то типа. Цена единицы будет состоять из BOM и затрат на разработку.

Забудем о нашем «сложном» устройстве и поговорим о, например, простом брелоке (слева плата нашего брелока на 5ом поколении, справа на 3ем). Грубый расчёт показывает, что компоненты (кроме чипа Z-Wave) и PCB со сборкой стоят примерно 7 баксов (речь о мелкосерийном производстве нашей партии, а не про миллион китайских брелоков). Модуль ZM5202 стоит ещё 5 (аналоги стоят примерно 2 бакса, т.е. около 3 ушло на лицензию Z-Wave). Ещё корпус за 1 бакс (да поможет Alibaba!). Итого 13.

Теперь посчитаем затраты на разработку прошивки: 2600 (Keil) + 2500 (DevKit/ZDK) + 4000 (членство в Альянсе на год) + 3500 (сертификация) ? 2.5 бакса на устройство. Причём с производством нескольких моделей первые три слагаемых будут распределяться по всем типам устройств, т.е. цена будет существенно падать.

Также стоит учесть работу программистов. По нашему опыту, на первом устройстве они «сожрут» не менее 10 человеко–месяцев, а то и более. Что для первого устройства выльется в 2–4 бакса (для последующих устройств будет меньше раза в 2–3 благодаря накоплению опыта).

Таким образом ваши первые 5000 (весьма простых) устройств будут стоить по 19.5 баксов. Добавим НДС, транспорт, пошлины (при импорте), сертификацию, маржу себе и продающим партнёрам в канале, минимальный маркетинг и получим три конца примерно 60 баксов. С опытом и ростом объёма производства эта цифра будет уже ближе к 15 баксам, т.е. ближе к 45 в рознице. Это и есть розничная цена устройства здесь. Это к вопросу о том, что сколько стоит, и почему.

Также замечу, что первый опытный сертифицированный образец обойдётся минимум в 20 000 баксов. Меньше ну никак у новичков не получается.

Можно ли сделать дешевле на проприетарном протоколе и каком-нибудь чипе от TI или Silicon Labs? Не факт, если речь идёт не о колхозе на коленках, а о серийном устройстве с хорошей поддержкой. Да, Z-Wave стоит на 20%–30% дороже, но это часто оправдано.

Мораль сей басни


Как видите, процесс создание собственных устройств на базе протокола Z-Wave не таит в себе каких-либо загадок и вполне доступен любой IT-компании, знакомой с микроконтроллерами. Благодаря формату SoC многие устройства можно сделать на чипе Z-Wave и небольшом количестве дополнительных компонентов. Да, вам придётся прочесть около 2000 страниц спецификации и пройти через сертификацию.

Стоит ли во всё это влезать, и зачем вам Z-Wave? Если вы хотите создать только управляемую лампочку и датчик движения, да ещё и подешевле, то Z-Wave вам будет в тягость. Но если вы хотите создать полноценные компоненты умного дома, то вам лучше «вписаться» в существующий хорошо развитый протокол, такой как Z-Wave. Ведь мало компаний на рынке способных самостоятельно выпустить линейку из 30–50 устройств разного назначения: от брелоков и реле до термостатов и дверных замков. Приобщившись к популярному протоколу, вы сможете увеличить продажи своего устройства, вписав его в существующую экосистему устройств умного дома.

Как-то сложно для простого гика...


Вы гик, не согласный платить кучу денег и изучать так подробно внутренности Z-Wave? Но и готовые устройства вас не устраивают? Тогда на правах рекламы расскажем об одном нашем новом устройстве. Встречайте Z-Uno!



О Z-Uno мы на напишем отдельную статью (тут будет ссылка, обещаю). Если кратко, то это маленькая плата, основанная на ZM5101. Почти все ноги этого модуля мы вывели для вас. В этом устройстве специальная прошивка, которая позволяет подгружать пользовательский код, написанный в среде Arduino IDE на привычном для «ардуинщиков» языке. Мы дополнили «синтаксис» Arduino своими макросами, которые позволяют описать Z-Wave функции устройства (до 10 функций) и определить, что отправлять для каждой функции. Таким образом Z-Uno — это клон Arduino (с небольшими оговорками — это не Atmel, а 8051) со встроенной поддержкой Z-Wave. Ждите следующую статью или читайте на z-uno.z-wave.me.

Комментарии (36)


  1. aivs
    07.01.2016 20:25
    +5

    Осилил!!!


  1. GarryC
    07.01.2016 22:04

    Не очень понял, как при этом (покупке Z-Uno) обстоят дела с сертификацией протокольной части? Она переходит с Вашим девайсом?


    1. PoltoS
      07.01.2016 22:07

      Мы сейчас сертифицируем Z-Uno. Т.е. к вы приобретете уже сертифицированное устройство.


  1. Jeditobe
    08.01.2016 00:32
    -2

    Кстати, устройств с поддержкой Z-Wave на рынке уже полно. Цены конечно не копеечные, но на порядок другой дешевле девкита.


    1. aivs
      08.01.2016 01:42
      +2

      Только ссылочка на amazon для России не актуальна, на амазоне устройства под американскую частоту, с российскими устройствами не будут работать (предупреждаю, если кто-то захочет на американском амазоне устройств по дешевке купить).


      1. Jeditobe
        08.01.2016 13:21
        +1

        Это частный случай проблемы.

        Можно брать целиком только американские версии и не париться. Особенно, если устройства нужны для экспериментов.

        Лично я не вижу смысла брать российские версии устройств, которые наверняка будут продаваться дороже.


        1. PoltoS
          08.01.2016 14:24
          +2

          Для экспериментов проще на Алибабе купить.

          А вот для автоматизации не советую. В США приняты частоты 908/916 МГц, а это как раз в диапазоне GSM 900, принятом в Европе и России. В США используется GSM 850, и там как раз 868-869 МГц использовать нельзя.


    1. PoltoS
      08.01.2016 02:05
      +1

      Да и некоторые, что от сети, рассчитаны только на 110 В 60 Гц и красиво дополнят новогодний салют при подключении у вас дома ;)


      1. Jeditobe
        08.01.2016 13:26

        Когда не смотришь параметры блока питания устройства подключаемого в электрическую сеть, то становишься Сам-Себе-Злобным-Буратиной. Я не верю, что на гиковском сайте кто-то делает так.

        Стоит отметить, что там полно автономных устройств, а многие остальные девайсы на самом деле имеют универсальные блоки питания.


  1. resetnow
    08.01.2016 13:50
    +1

    Да, с одной стороны, есть протокол, инфраструктура и софтовая поддержка, с другой — все огорожено и киты по $1500. Дома на коленке не соберешь. Причем если чипы еще можно найти, то с SDK, насколько я понял, совсем все плохо.


    1. PoltoS
      08.01.2016 14:25

      Через пару дней расскажу про нашу Z-Uno. Это то, что вам нужно.


  1. GloooM
    08.01.2016 13:58
    +1

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


    1. PoltoS
      08.01.2016 14:29
      +2

      Может. Для себя — сколько угодно. А вот для бизнеса — нет. Патенты ограждают от таких деяний.

      По поводу безопасности, сразу скажу, что есть шифрование. Есть не во всех устройствах, но там, где есть, сеть безопасна — включить соседу не сможете.

      Там, где нет шифрования, прослушать точно можно, а вот повключать сложнее — нужно знать, как спуфить HomeId сети соседей. Мы знаем ;)


      1. nochkin
        08.01.2016 19:43

        По поводу шифрования:
        То есть, если нет уверенности, то лучше Z-Wave ставить на некритичные узлы типа свет в коридоре и такого плана, но не на замок на двери или гараже?


        1. PoltoS
          08.01.2016 22:36
          +2

          Замки по стандарту не могут быть без шифрования. Т.е. тут всё ок. Мы сами вполне доверяем замкам Z-Wave (его даже отмычкой не просто открыть, а шифрование не взломаете за время жизни/эксплуатации замка!).

          Но даже диммеры и реле, не говоря уже про датчики движения и открытия, уже имеют шифрование на борту. Это тренд — безопасность в IoT — важная тема, и Z-Wave тут один из первых.


          1. nochkin
            08.01.2016 23:50

            Я так понимаю, что шифрование выполняется на уровне закрытого ZDK.
            Есть ли устройства где шифрование опционально и его надо как-то отдельно включать? Или тут если шифрование есть, то оно всегда есть. А если нет, то уже и не включить, так как заложено уже производителем?

            И как мне с точки зрения пользователя понять используется шифрование в конкретном Z-Wave устройстве или нет?


            1. PoltoS
              09.01.2016 01:21
              +1

              Нет, шифрование на уровне открытого кода ZDK (в шаблонах), т.е. оно в имплементации Классов Команд. Это, кстати, существенно повышает к нему доверие.

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

              Некоторые устройства имеют разные кнопки для включения. Например, наши новые устройства в «безопасном» режиме включаются, анонсируют возможность шифрования, но при включении без шифрования (не предложено контроллером) ничего не дают (т.е. устройство хочет всё шифровать, а контроллер не собирается). А в «небезопасном» даже не анонсируют шифрование (даже если контроллер хочет, они не дадут).

              Запутал, да? ;)

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


              1. nochkin
                11.01.2016 03:50

                Примерно понял. Вроде не запутал, но появились другие вопросы.
                Например, у меня есть реле. Производитель решил, что реле может работать без шифрования. Но я это реле поставил на открытие двери гаража, то есть функционально это уже не «реле», а «замок». Я могу сделать так, что бы это реле было только с шифрованием или тут уже от производителя зависит?


                1. PoltoS
                  11.01.2016 11:27

                  Контроллер покажет, используется ли шифрование при общении с устройством.

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


                  1. nochkin
                    11.01.2016 18:08

                    С этой стороны вроде как раз понятно.
                    Мне интересно с другой стороны — если производитель решил, что это «всего лишь реле» и шифрование не включено, то могу ли я (как пользователь) включить обязательное шифрование?


                    1. PoltoS
                      11.01.2016 20:06

                      Если оно вообще недоступно, то, естественно, нет. Если доступно, то устройство анонсирует шифрование, а дальше будет зависеть от контроллера


                      1. nochkin
                        12.01.2016 01:22

                        То есть контроллер может переубедить если технически такая возможность имеется. Это уже что-то. Спасибо за ответы.
                        Как раз скоро получу контроллер и поиграюсь.


                        1. PoltoS
                          12.01.2016 02:55

                          А какой контроллер ждёте?


                          1. nochkin
                            12.01.2016 03:38

                            Дурацкий. D-Link DCH-G021.


                            1. PoltoS
                              12.01.2016 09:26

                              ой. действительно дурацкий. мало поддерживает устройств пока. и логика примитивная. но D-Link обещает расширять функционал в этом году


                              1. nochkin
                                12.01.2016 22:39

                                А есть какие-то контроллеры, у которых есть какой-то API, что бы можно было достучаться до Z-Wave устройств через какой-то свой скрипт?
                                К сожалению, ваш вариант на Pi не очень подходит из-за порога вхождения. Надо что-то такое, что бы я мог сказать кому-то, кто далёк от компьютеров: «купи вот это, подключи питание и нажми вот эти кнопки». MiCaseVerde или типа того?


                                1. PoltoS
                                  13.01.2016 02:14

                                  В Vera и Fibaro тоже есть API. Не такое продвинутое в плане возможностей, но есть, и основные все вещи сделать из него можно. Завтра ссылки дадим на API.

                                  А готовый контроллер на базе Z-Way не пойдёт? rus.z-wave.me/shop/controllers/z-wave.me-razberry-controller
                                  Да, он на Pi, но не все пользователи даже догадываются об этом. А скоро появится в другом форм-факторе на базе роутера


                                  1. nochkin
                                    13.01.2016 03:59

                                    Готовую коробку я не видел. На главном сайте у меня было впечатление, что есть модуль для самостоятельной сборки только.
                                    Продаётся только в России. Когда планируется продавать на том же Амазоне, как тот же модуль? И какая будет цена?


                                1. aivs
                                  13.01.2016 02:49

                                  У RaZberry существует 3 вида API:
                                  1) HTTP LowLevel — для получения исчерпывающей информации о Z-Wave сети
                                  2) HTTP HomeAutomation — для простого управления устройствами и снятия показаний с датчиков (самое простое и популярное)
                                  3) JS — Позволяется писать собственный приложения/сцены/правила автоматизации

                                  Пример:
                                  1) Включить
                                  HTTP LowLevelAPI — 192.168.0.3:8083/JS/Run/zway.devices[2].instances[0].commandClasses[37].Set(255)
                                  HTTP HAAPI (GET) — 192.168.0.3:8083/ZAutomation/api/v1/devices/ZWayVDev_2:0:37/command/on
                                  JS API — 192.168.0.3:8083/JS/Run/controller.devices.get(«ZWayVDev_2:0:37»).performCommand(«on»)

                                  И ссылка с большим количеством примеров:
                                  rus.z-wave.me/shop/z-wave.me-razberry-controller/primery-http-komand


                                  1. nochkin
                                    13.01.2016 04:00

                                    Насколько я понял, пока это кроме как в России не купить.


                                    1. aivs
                                      13.01.2016 12:07

                                      В Европе можете купить, вот тот же контроллер RaZberry под другим брендом www.popp.eu/products/controllers/popp-hub


                                      1. nochkin
                                        13.01.2016 17:34

                                        В Европе европейская частота. Мне нужно 908.42 — «Амазоновская» частота :-)


                                        1. PoltoS
                                          13.01.2016 17:39

                                          Ой, это США. Пока нет ;(


                                          1. nochkin
                                            13.01.2016 18:02

                                            Про «пока нет» я уже догадался. Какие мысли в плане сроков и цен?


                                            1. PoltoS
                                              13.01.2016 18:03

                                              Готовый — даже не думали. Если выведем новый на базе роутера в мир, и он будет успешным, то через годик


    1. PoltoS
      08.01.2016 14:34
      +2

      Кстати, есть университетские проекты, которые, используя лишь открытые спеки ITU-T G.9959, делают упрощённый протокол а-ля Z-Wave без маршрутизации и включения в сеть (там регистрация в сети иначе сделана). В этом смысле даже реверс-инжиниринг не нужен. А вот реверсить весь протокол с маршрутизацией весьма трудозатратно. Был бы смысл.