Как делаются Z-Wave устройства

В этой статье мы расскажем, как создаются устройства Z-Wave. С точки зрения схемотехники и программирования разработка Z-Wave устройства не сильно отличается от разработки устройства на базе Arduino, AVR или PIC. Однако есть в Z-Wave свои нюансы. О них-то и пойдёт речь под катом.
1abcaf8ff36e4d41bb14198f17b95582.png
О протоколе 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 чипы доступны в двух вариантах:

241bb317a2a9445a8a2a37ee260af91b.png
SD3502, 48-QFN 7×7 мм,
42bbd452bddb4bbb93690c156a62be9c.png
SD3503, 32-QFN 5×5 мм (урезанная версия по сравнению с SD3502).


Также доступны следующие SiP модули, включающие в себя кварц и минимальную обвязку для работы чипа:

8ad4e7f280c442ee93ae437b86a9f328.png
ZM5101, 56-QFN 8×8 мм, совместим с ZM4101 (4ое поколение),
9ccf1781b53842adaa1bde51684fa5db.png
ZM5202, PCB 12.5×13.6 мм, на базе SD3502, совместим с ZM3102 (3ее поколение),
c3b4d7f7dbc94618b3e1aa6a5b9a11f3.png
ZM5304, PCB 27×15.2 мм, на базе SD3503, включает память EEPROM, SAW-фильтр, спиральную антенну и защитный экран (предназначен для «модемов», т.е. для контроллеров Z-Wave),

И серия от Mitsumi:

0cbf6376ce96417db7e50acccbc29d93.png
WML-C84, 56-QFN 8×8 мм, полный аналог ZM5101,
3057738ad87f48a9b7d90641178257c1.png
WML-C85, 56-QFN 8×8 мм, по сравнению с C84 имеет встроенный SAW-фильтр,
8e26d103c73040da934a377b7a4fbab3.png
WML-C86, 56-QFN 15×15 мм, встроенные SAW-фильтр и EEPROM, увеличенные мощность TX и чувствительность RX, защитный экран,
8e26d103c73040da934a377b7a4fbab3.png
WML-C87, 56-QFN 15×15 мм, встроенные 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 (об этом ниже),
  • всякие провода и блоки питания.


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

Стоимость кита от $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 как технологии-бренда.
75fcea7b8d4e44e08a15a8c526372e74.jpg

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

В роли 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), что позволит плавно менять цвета в режиме новогодней гирлянды.

76afd21ba5524dae9b383b80b34520d5.png

Заметьте, у нас осталась ещё куча (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 0×25) необходимо обработать команду Set (25 01), включив реле или светодиод или что-то там ещё, команду Get (25 02), ответив на неё командой Report (25 03 xx), где xx = 00 или FF в зависимости от текущего состояния реле, лампочки или что у вас там.

Для нашего примера «сложного» устройства это будет выглядеть как-то так

Псевдокод обработчика
NIF будет содержать 0×25 (SwitchBinary), 0×26 (SwitchMultilevel), 0×30 (SensorBinary), 0×31 (SensorMultilevel), 0×60 (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 и доступен всем разработчикам. 753cab80d6334b91997f55956ca40394.png Такой подход позволил создать «рынок» 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 и затрат на разработку.

8485b26bfeec4ada84930921d67fd675.jpg Забудем о нашем «сложном» устройстве и поговорим о, например, простом брелоке (слева плата нашего брелока на 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!

4114a50b96ac43f799c7c8bbdfeed878.png

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

© Geektimes