habrahabr

Конструктор для «Умного Дома» — от идеи до воплощения

  • вторник, 12 августа 2014 г. в 03:10:58
http://habrahabr.ru/post/232901/



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

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

В прошлом году появилась мысль усовершенствовать домашнее освещение, чтобы оно самостоятельно включалось там, где и когда нужно, подстраиваясь под обитателей дома, время суток, дни недели, и общую освещенность. Тоже можно сказать и об обогреве и прочей домашней инженерии — почему бы не придать ей интеллектуальности? К тому же об Умных Домах столько говорится и пишется.

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



Есть простые и дешевые устройства, а есть такие, стоимость которых заставляла пересчитывать нули на ценниках. Есть полные, законченные решения, а есть наборы «сделай сам». Оставалось выбрать, что-то наиболее подходящее, интересное с моей точки зрения: пользователя и разработчика.

Интересный момент, с которым наверняка сталкивались начинающие строители своего умного дома. Некоторые элементы планируемой системы четко определены изначально — например, нужен умный свет и интеллектуальный обогрев, или жена просит авто-полив цветов. Однако, большое количество идей существует в виде: «Попробовать в перспективе сделать управление жалюзи», или «Поэкспериментировать бы с удаленным управлением кондиционерами», а еще: «Здорово будет домашнего робота-паука интегрировать в общую сеть — будет гостей весело встречать»… Да мало ли что нам, людям творческим, с инженерным уклоном, завтра еще придет в голову? Система должна с легкостью принимать все дополнения, меняться, перестраиваться под наши идеи. Представлялся некий набор модулей, «электронных кубиков», которые можно легко собирать-соединять комбинируя каждый раз в новую Систему Мечты: надежную, с хорошей эстетикой и удобными средствами программирования. Нужна возможность постепенного дополнения новыми модулями, чтобы в конечном итоге получить единое интеллектуальное пространство, где все работает с максимальным комфортом для человека. В интерактивном или автономном режиме — на каждом этапе система должна сохранять широкие возможности для творчества.

Каждая из рассмотренных систем, оставляла двоякое чувство — вроде, все здорово… Но немного не то. Желание иметь коммуникации без проводов уменьшило список претендентов втрое. Ценовой фактор отсеял еще половину. Опять же, не рациональным кажется использование WIFI-протокола для включения лампочки. Хороши системы Zigbee, Z-wave и подобные, но и у них обнаружилось то, что заставило не спешить с решением. Удивляла «заточенность» продуктов на централизацию: с выделенным сервером или центральным контроллером. На мой взгляд, распределенные системы гибче и надежнее, обладают большей автономностью. Часто возникали вопросы к масштабируемости решений. Еще позабавил момент — «Умным Домом» зачастую называют элементарную логику и простейшую автоматизацию. Чтобы отделиться от этих представлений, давайте назовем настоящий умный дом тогда иначе, например, «Интеллектуальное Пространство» — лучше раскрывает суть.

Дальнейшее изучение вопроса привело к простому выводу: если система стоит не дорого и проста в настройке, то ограничена по возможностям и не гибка — сложно реализовать все идеи интеллектуального обустройства дома. Функционально насыщенные и универсальные системы часто требуют специальной подготовки для монтажа, имеют много лишнего и слишком дороги.
Мысль: «Можно сделать лучше и дешевле», появилась вполне закономерно.

Если у тебя есть энтузиазм,
ты можешь совершить все, что угодно.
Энтузиазм — это основа любого прогресса.
Генри Форд

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

Первым делом сформулируем, что будем создавать?

  1. Интеллектуальное пространство дома, в моем понимании, — это своего рода нервная система. По сути специализированная распределенная система, реагирующая на все происходящее и динамически меняющая свое поведение. Множество устройств, каждое выполняет свою часть общего алгоритма, все взаимодействуют со всеми, реагируют на внешнюю среду, передают данные, сигналы и определяют свое поведение в зависимости от полученной информации. Отсутствие единого центра повышает надежность системы и позволяет наращивать возможности и интеллектуальный потенциал своего дома путем простой установки дополнительных модулей.
  2. Роль отдельного «нервного узла» возьмет на себя модуль — устройство, состоящее из двух-трех частей: системной — базовой; и одной-двух функциональных — дополнительных. Некий продуманный набор «кубиков», способных к комбинированию в широких пределах. Готовый к работе модуль получается просто: к основной части присоединяем одну или две функциональные, подходящие под конкретную задачу. Части соединяются по принципу plug-and-play, без всяких хлопот. Базовая часть содержит процессор, радио-интерфейс внутренней сети, системный и прикладной софт. Дополнительные части — они разные: блоки всевозможных датчиков или управляющих реле; WIFI или Z-wave точки доступа; а, может быть, какое-то свое устройство. Таким образом, имеем любой желанный набор «электронных кубиков», которые можно легко скомбинировать.
    Итак, общие характеристики структуры будущей системы:
    • распределенная;
    • модульная;
  3. Мне, как программисту, нужен определенный комфорт. Например, возможность не только наблюдать работу, но и перепрограммировать любое устройство в сети в любой момент. Максимально быстро и просто, без программаторов и без проводов, из любого места, где есть интернет, в он-лайновом редакторе подправить программный код и сразу увидеть изменения в работе модуля.
  4. Говоря о комфорте, обдумаем еще одно требование. При программировании этого «распределенного хозяйства», языковые средства должны поддерживать возможности удобного описания межмодульных взаимосвязей. С другой стороны, нужен и низкоуровневый доступ к аппаратуре, например, к портам ввода-вывода.
  5. При этом важна надежность, защищенность от внешнего вторжения и ошибок в программе.
  6. Стоимость отдельного модуля должна быть минимально возможной, поскольку концепция предусматривает установку большого количества устройств.
  7. Устройства должны быть:
    • компактными;
    • эстетичными;

Разберемся с этими требованиями. А к сети, радиоканалу, «облакам» и непосредственно программированию системы перейдем позже, там тоже масса увлекательного.

Постановка задачи определила основу — недорогой микроконтроллер на базе 32-битного ядра Cortex-M3/M4 с 64 или 128 Кб флеш-памяти. Цены, например, на STM32 начинаются от 1.5 долларов. За эти деньги получаем неплохую производительность. Потребление в миллиамперы позволяет питать систему от батареек. Плюсом будет достаточный объем ОЗУ, таймеры, основные аппаратные интерфейсы, продвинутые часы и календарь и другая полезная периферия. Простая двухслойная плата позволит сэкономить при производстве. Но сможет ли столь простой микроконтроллер справится со всеми задачами? Плюс вопросы безопасности и надежности работы: устройства умного дома вполне могут управлять мощными двигателями или быть частью охранной системы. Нарушение алгоритмов, преднамеренное или случайное, способно привести к печальным последствиям. Следовательно, нужна защита памяти операционной системы, нужен контроль над пользовательским кодом, также необходимо сделать бессмысленным написание вирусов. При этом хотелось бы сохранить гибкость программ и простоту операционной системы. И реализовать все на недорогом STM32, который хоть и ARM, но у которого в отличии от старших моделей серии Cortex-A, отсутствует MMU (Memory Management Unit), и всего лишь 16 — максимум 64 Килобайта ОЗУ, у моделей в заданном ценовом диапазоне.

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

Скромные ресурсы микроконтроллера — не проблема. Кто-то из коллег наверняка помнит чарующий Spectrum 48K. Процессор 8-битный Z-80 3,5МГц и чуть больше 40 Килобайт ОЗУ. Однако, какие удивительные программы для него были написаны: Elite – 3D-игра, в которой уместилась целая вселенная с тысячами планет; весьма приличные графические редакторы «Art studio» и «Artist II»; текстовые редакторы и базы данных; компиляторы Паскаль и Си. Ресурсов хватало.

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

Структура модуля в общем виде:



Что из себя представляют функциональные части? Как соединяются с системной?

Плата базового блока в схематичном виде: микроконтроллер ARM cortex M3/M4, чип радио-передатчика CC1101, антенна и интерфейсные разъемы.
Соединим базовый блок с сенсорной частью:



Получится такое устройство:



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


Сенсорные блоки могут быть самые разные, на данный момент разрабатываются такие:



Входящие в их состав датчики определяют назначение и подобраны так, что бы стоимость сенсорных блоков была небольшая.

Друзья, какие сенсоры еще нужны для дома?
В планах создание блоков для домашней безопасности:
№ 4 – контроль качества воздуха — с датчиками CO2 и вредных примесей в воздухе;
№ 5 – контроль дыма, огня, угарного (CO) и бытового газа;
№ 6 – датчик протечек.
Для любителей выращивать капризные растения:
№ 7 – блок с датчиками температуры и влажности почвы, солености и Ph (кислотности), рассчитанный на использование вне дома.

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

Нагрузка может быть в виде насосов, светильников, светодиодных лент, приводов кранов и т. д. Модули имеют несколько каналов управления, проще говоря — разъемов для подключения устройств:



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

Кроме того, думаю полезны будут еще:
  • доп. модуль управления сервомоторами и коллекторными электродвигателями;
  • доп. модуль управления шаговыми и бесколлекторными моторами.


Соединим модули и подключим к роботу:



Интерфейсная часть (Interface #3) облегчает подключение различной периферии, а также литий-полимерного аккумулятора. Модуль-драйвер позволит управлять коллекторными и серво-моторами.

Кстати, об интерфейсных дополнительных блоках:



Если нужен постоянный доступ к домашней системе через интернет — имеет смысл WIFI модуль подключить. Если нужно от случая к случаю собирать данные и планируется, в основном, автономная работа системы, подойдет bluetooth. Для собственных аппаратных разработок, экспериментов и решения каких-то особых задач пригодится блок с набором популярных интерфейсов.

Запланированы дополнительные блоки Z-wave и других сетей для умных домов, чтобы получить возможность объединяться с существующими устройствами, которых уже наделаны тысячи под разные запросы. Увидел, например, красивые дизайнерские выключатели с интерфейсом ZigBee, так почему бы не добавить их в свою систему?

Решив ряд задач с помощью виртуальной машины и вынеся механизмы межмодульного взаимодействия в сетевую подсистему, ядро операционной системы можем упростить до предела. Простое и «легкое» ядро системы — большой плюс в нашем случае. Рассмотрим подробнее структуру программного обеспечения модуля. Цветами обозначено, что реализовано, а что еще в работе. Условно можно разделить на четыре части: системная, сетевая, контролирующая и виртуальная машина:



Об операционной системе
Одним и первых шагов был выбор: взять готовую ОС или написать свою. Операционных систем для микроконтроллеров не мало: ChibiOS, eCos, TinyOS, FreeRTOS, FemtoOS и другие. Все они по-своему интересны и достойны, чтобы их применять, однако, хотелось получить скроенную под конкретную задачу, специализированную ОС, максимально простую и быструю. Изначально надеялся обойтись простым диспетчером сообщений, но функционал пришлось постепенно расширить. Каждое дополнение тщательно взвешивалось, все лишнее отсекалось. Создавая систему с нуля, получаешь замечательную возможность оптимизации на всех этапах. В результате, на данный момент, системная часть умещается в 5 Кб флеш-памяти, в процессе написания дополнительных драйверов датчиков, объем будет расти. Сразу надо пояснить, что «драйверы» в данном случае — это не совсем то, с чем мы сталкиваемся в Windows или Linux, это — просто набор функций инициализации, задания параметров работы или чтения результатов измерений.

Итак, ядро представляет собой простую событийную операционную систему реального времени, с дискретность реакции 5 миллисекунд. Многозадачность поддерживается: для пользовательских скриптов — кооперативная, для системных процессов — вытесняющая, с учетом приоритетов, основана на аппаратных возможностях микроконтроллера. Процессы связываются с событием, и при его возникновении — запускаются. События могут инициироваться самими процессами, таймерами, оборудованием, сетью и скриптами пользователя. Процессы взаимодействуют через сообщения. В общем, предельный минимум, однако, позволяет реализовать все, что угодно.

О виртуальной машине
Виртуальная машина тоже достаточно простая и компактная — помещается в 12 Килобайт флеш-памяти. Работает пока с целыми числами и строками. Поддержка арифметики с плавающей точкой — в процессе. Синтаксис языка, близок к стандарту Си-99, но с некоторыми особенностями. Размер получаемого байт-кода радует — в 1-2 Килобайта умещается вполне существенный алгоритм. Трансляция в байт-код идет очень быстро (в том числе по причине слабой оптимизации).

Идею создания своего специализированного языка программирования для «Домашнего Интеллектуального Пространства», не дрогнувшей рукой, отложил в дальний ящик, поскольку знаю во что это выльется по срокам, есть опыт. А вот добавить трансляторы более современного С++, Javascript и, возможно, других языков планирую. Второе по важности — сделать JIT-компилятор. Для решения этих задач знакомлюсь с LLVM — отличный инструментарий, надо сказать! Если все задуманное получится, быстродействие байт-кода приблизится к нативному, а писать программки можно будет на нескольких языках.

На данный же момент производительность Виртуальной Машины примерно соответствует другим аналогичным без JIT-компиляции. Подергаем, для теста, выводом микроконтроллера в цикле и измерим частоту:

// Инициализируем порт ввода-вывода   
_pinConfig (GPIOB, GPIO_PIN_1, GPIO_MODE_OUTPUT_PP, GPIO_Speed_10MHz);
_pinOff (GPIOB, GPIO_PIN_1);

int i = 100000;
while (i){
 	    _pinInv (GPIOB, GPIO_PIN_1);
 	    --i;
}

Цикл выполнился примерно за секунду. Соответственно, получилось около 100 КГц. STM32L151CB, 32МГц — очень экономичный, но не быстрый микроконтроллер. С чем сравнить результат? Аналогичный Си-код на том же микроконтроллере со стандартной (-O2) оптимизацией, выполняется примерно в 16 раз быстрее.

К слову, можно задействовать аппаратные возможности контроллера, и получить, например, 10МГц на выводе:

// Сконфигурируем 1-й и 2-й каналы, задав частоту 10 МГц и режим работы.
_pwmConfig( PWM_CHANNEL_1 | PWM_CHANNEL_2, 10000000 , TIM_CounterMode_Up , TIM_OCPolarity_High)

// Запускаем генерацию импульсов с 50% заполнением, т.е.
// длительность высокого уровня будет равна длительности низкого.
_pwmOn ( PWM_CHANNEL_1 | PWM_CHANNEL_2, 50 )


Функции "_pinInv (...)" и "_pwmOn (...)" и аналогичные — это прямой доступ к драйверам периферии микроконтроллера, элементы низкоуровневого API, так сказать.

Контролирующая часть
Потребность в этом блоке появилась не сразу, возникающие исключения обрабатывались по месту возникновения. Однако, необходимость уведомлять и координировать работу других подсистем, в зависимости от возникшей проблемы или изменившегося режима работы сильно усложняла жизнь. За счет вынесения контролирующей логики в отдельный блок легче отслеживать проблемы в остальных трех подсистемах и реагировать на них. Можно попытаться восстановить работу или уведомить пользователя. Или сохранить на «облачном» сервере данные пользовательского скрипта, затем перезагрузить модуль и продолжить работу. Отслеживаются: проблемы с питанием, ошибки в скриптах, зависания и сбои, проблемы сетевого обмена.

Сетевая подсистема
Как и весь проект, сеть создавалась с мыслью о максимальной автоматизации работы и удобстве для пользователя. При этом оказалось много тонкостей и на физическом уровне, и на уровне протокола. Поскольку раньше сетями и радио-устройствами не занимался, получил массу удовольствия и ценного опыта. Подробностям, пожалуй, стоит посвятить в отдельную статью.
В общих чертах: получилась самоорганизующаяся сеть, типа Mesh (ячеистая) с динамически назначаемыми «маршрутизаторами». Настройка, конфигурирование при добавлении и отключении модулей, а так же перестройка маршрутов при возникновении препятствий на пути радиосигнала происходит без участия пользователя. Оригинальные алгоритмы самоорганизации сети являются отдельным предметом гордости: при объеме занимаемой памяти около 10 Килобайт, обеспечивают стабильность передачи данных и надежность работы. Например, любой модуль, обнаружив, что оказался связан с удаленным модулем, который не видят некоторые устройства сети, берет на себя функцию маршрутизатора, чтобы транслировать предназначенные удаленному устройству пакеты. Другие модули так же определяют сами, нужно ли им заниматься маршрутизацией или не засорять эфир лишней передачей данных.

Сетевой протокол предусматривает несколько способов взаимодействия между модулями и внешним миром, расскажу о самом, на мой взгляд, удобном для программиста. Он навеян замечательным решением в QT – signal/slot. Сигнал может отправить любой модуль домашней сети. А может и удаленный сервер в облаке. Или приложение пользователя, запущенное в смартфоне. Этот сигнал будет обработан одним или несколькими устройствами, которым программист задал слушать этот сигнал. Например, сигнал могут отправить: датчик влажности на клумбе или кнопка интерфейса приложения, запущенного в браузере. Принять сигнал может как Веб-приложение, так и модуль управления насосом полива. Таким образом упрощена реализация пользовательских интерфейсов, все взаимодействия построены по единому принципу, а значит достаточно просто заставить всю распределенную систему взаимодействовать, не вдаваясь в особые сложности. Структура передаваемых данных может быть различной: например, показания отдельного датчика или набора сенсоров, или текстовое сообщение. Для решения каких-либо специфичных задач, можно использовать другие типы сетевого обмена. Помимо сигналов, в которых явная адресация отсутствует, можно формировать пакеты на более низком уровне с конкретной адресацией, например широковещательные или предназначенные определенному сегменту сети, или определенному устройству, или, например, передать данные синхронизации даты/времени. Внутри сети адресация 16-битная, соответственно возможно объединение тысяч устройств. Уникальный идентификатор каждой сети — 32-битный. Защита данных — шифрование AES128.

Подводя предварительный итог, можно сказать, что объединение идей модульности и распределенной одно-ранговой умной сети, дают положительный результат. Основные плюсы:
  1. Домашняя система может постоянно находиться on-line, сохранять данные в «облаке» и т. д.
  2. И наоборот, будучи единожды запрограммированной, может прекрасно работать автономно. Автономности способствует экономичность модулей, следовательно, их малая зависимость от сетевого напряжения.
  3. Высокая способность к модификации интеллектуальной среды. Можно быстро вносить коррективы в программный код и сразу видеть результат. Любой модуль можно соединить/разъединить с любыми функциональными частями без остановки работы системы, Например, модуль управлял умным обогревом зимой, на лето же заменим функциональную часть, и отправим его на управление декоративным фонтаном или умным поливом растений.
  4. Высокий параллелизм процессов.
  5. Надежность работы: отсутствие единого центра, работа пользовательского кода в виртуальной машине, плюс шифрование сетевых пакетов и контролирующий блок кода.
  6. Любое домашнее устройство с дисплеем и интернет-браузером — телевизор, планшет или смартфон — способно быть интерфейсом умного дома. Интерфейс – WEB приложение, соответственно его кастомизация не ограничена.
  7. Упрощение реализации творческих задумок. Даже в таком, незавершенном виде, система позволяет комфортно экспериментировать с различными устройствами.

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

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

Пока же проведем пару тестов в подтверждение работоспособности системы.
Тестируем веб-приложение и модуль управления светодиодной лентой. Набираем небольшую программку в он-лайновом редакторе, запускаем — смотрим — светится как положено, яркость красного задана 100%.



Код достаточно прост:



Еще один тест. Свяжем датчик освещенности и управление нагрузкой 220Вольт. Элементарный алгоритм, пороговое значение ставим 500Lux.



Лампа зажглась — тень зафиксирована.

Свет от окна около 1000 Lux, лампа гаснет:



Код для модуля, управляющего лампой:

@lamp(idx) // При получении сигнала "SENSOR" из сети, попадаем в эту функцию-обработчик
{ 
    // Значение освещенности, пришедшее из сети
		int light = Argument(idx, 0);
    
		// Проверка порогового значения
		if (light < 500){
    	  _pinOff (GPIOA, GPIO_PIN_3);
    	  tick  = GetTick();
    }
    else{
        _pinOn (GPIOA, GPIO_PIN_3);
        tick  = GetTick();
    }
}

main()
{
    // Конфигурируем вывод, управляющий нагрузкой
		_pinConfig (GPIOA, GPIO_PIN_3, GPIO_MODE_OUTPUT_PP, GPIO_Speed_10MHz);
    // Управление инвертировано: pinOff - включено, pinOn - выключено
		_pinOn (GPIOA, GPIO_PIN_3);
	
    // Слушаем сигнал из сети и обрабатываем его при получении
    Listen ("SENSOR", "@lamp");
}


Код для модуля с датчиком:

@sendSens() // Обработчик, с которым связали сигнал об окончании преобразования АЦП
{
	// Значение освещенности в милливольтах, которое насчитал АЦП
	// Новое и предыдущее значение
	// считаем в милливольтах ввиду временного отсутствия поддержки типа float
    int ambLightNew = _getSensor (SENSOR_AMBILIGHT, NEW_VAL)+1;
    int ambLightOld = _getSensor (SENSOR_AMBILIGHT, OLD_VAL)+1;
    
    //Преобразуем в Люксы, библиотечная ф-ция
    int ambLight = _getAPDS9007(ambLightNew)/1000;
    
    //Сравним старое и новое значение, в h - процентная разница
    int h;
    if (ambLightNew > ambLightOld)
        h = ambLightNew*100 / ambLightOld;
    else
        h = ambLightOld*100 /ambLightNew;
    h -= 100;
    
    int d[2];
    if ( h>10 ){ // Реагируем на более, чем 10% изменение освещенности
		
      // Формируем пакетик с результатом измерения
    d[0] = 1; // Одно значение
    d[1] = ambLight;

      // Отправляем в сеть сигнал
	    Signal("SENSOR",d[0]);
    }
	// Взводим таймер на 1/4 секунды для чтения результатов сенсора, чтобы снова попасть в эту функцию
	Timer (MSG_READ_ADC_SENSORS, 0, 250);
}

main() {
	// После старта, ждем одну секунду и запускаем чтение сенсоров
	Timer (MSG_READ_ADC_SENSORS, 0, 1000);
	
	// Вычисления значения аналогово-цифровым преобразователем закончится отправкой "MSG_ADC_FINISHED"
	// свяжем его с функцией @sendSens
	Bind  (MSG_ADC_FINISHED, "@sendSens" );
}




В тесте участвовал прототип модуля с платой сенсора освещенности и питанием от батареек.

Разработке «железа» посвящена следующая часть: проектируем, делаем рабочий макет, паяем мелочь размера 0402 (1мм x 0,5мм) и QFN-корпуса, изготавливаем прототипы.