![](https://habrastorage.org/getpro/habr/upload_files/10f/4e1/34c/10f4e134c46898bf20ddd39049f9330b.jpg)
HAQuDA – это настольная лампа, которая отображает данные о параметрах окружающей среды: качестве воздуха, температуре и влажности, при помощи цвета освещения. Если параметр в норме, то он зеленый, а если завышен или занижен, то красный или синий соответственно. У лампы есть несколько режимов отображения: стандартный, мульти, ночной, режим светильника, и возможность управления с помощью собственной веб-страницы и голосовых помощников.
Всем привет!
В период пандемии большая часть нашей жизни перестала выходить за рамки четырех стен, из-за чего остро встал вопрос о состоянии окружающей нас среды, о качестве воздуха в квартире, так как он напрямую влияет на наше самочувствие и продуктивность. В этой статье я хотел бы рассказать о процессе разработки волшебного домашнего отображателя качества воздуха.
С чего все началось…
В книге "Будущее вещей" Дэвида Роуза, автор рассказывает о свойствах волшебных вещей, способных облегчить нашу повседневную жизнь: часы с цветовым отображением количества потребленной электроэнергии в квартире, волшебный шар, способный цветом показывать совершенно разные параметры: от количества аллергической пыльцы на улице, до текущей стоимости акций. Почему эти вещи волшебные? Их концепции взяты из известных фантастических произведений. Судите сами: в повести Дж.Р.Р. Толкина "Хоббит, или Туда и Обратно" есть волшебный кинжал - "Жало", который кроме своей основной задачи - убивать полчища орков и гоблинов, еще и предупреждает своего хозяина о присутствии недругов - отличный пример простого интерфейса человек-устройство. Развитие идеи волшебных устройств воплотилось в устройстве ОПЭДИ, которое отображает на календаре количество потребленной электроэнергии в квартире, в разработке которого и я принимал участие. Мне захотелось продолжить эту идею и я решил собрать станцию мониторинга качества воздуха, которая совмещала бы в себе все необходимые датчики и имела "волшебные" свойства. Так и родилась идея HAQuDA…
Для чего он нужен?
Основная идея устройства заключается в простоте передачи информации о состоянии дома человеку. Существующие модели датчиков качества воздуха передают информацию понятную специалистам, но специфичную для простых пользователей, например единица измерения CO2 – PPM, а количество летучей органики (формальдегиды, ацетон, этанол и т.д.) измеряется в микрограммах на кубический метр. ОКВоДи позволяет моментально и понятно показывать информацию о качестве воздуха, за счет ее отображения цветом: от зеленого – качество воздуха хорошее, до красного - когда уже пора проветрить помещение. В этом устройстве заложен принцип “преаттентивности” (от англ. pre-attention) - показывать тот объем информации, который необходим для принятия решения, что позволит человеку быстрее обрабатывать информации, не фокусируя на ней внимание.
Примеры преаттентивных отображений данных
![На тепловой карте акций по цвету сразу можно увидеть акции каких компаний теряют в цене, а по размеру у кого сумма акций больше На тепловой карте акций по цвету сразу можно увидеть акции каких компаний теряют в цене, а по размеру у кого сумма акций больше](https://habrastorage.org/getpro/habr/upload_files/efa/a9e/71c/efaa9e71c068b387883cd0d1248b64fc.jpg)
![А на тепловой карте температуры можно сразу определить в каких регионах теплее, а в каких зима в самом разгаре А на тепловой карте температуры можно сразу определить в каких регионах теплее, а в каких зима в самом разгаре](https://habrastorage.org/getpro/habr/upload_files/6b9/d9e/690/6b9d9e69016b6f12459960d368b08293.jpg)
Как он устроен?
ОКВоДи представляет собой лампу цилиндрической формы (90x130мм) состоящую из двух частей: матовая полупрозрачная белая верхняя часть и основание из непрозрачного пластика. Внутри верхней части к трубе, закрепленной на плате, приклеены адресные светодиоды WS2812B, в количестве 12x9 штук. На плате расположены ESP-32 mini и датчики: датчик влажности и температуры – DHT-11, датчик летучих органических соединений и датчик углекислого газа – CCS811, датчик озона - ZE25-O3, датчик взвешенных частиц - ZH03B. В верхней крышке расположена сенсорная кнопка, чтобы отслеживать касания и менять режим отображения. Также на плате располагается два USB-A выхода для зарядки устройств и один USB-Micro вход питания.
Основные функции
ОКВоДи умеет отображать следующие параметры микроклимата дома:
Летучие органические соединения (TVOC) – измеряется в частицах на миллиард [ppb]
Количество озона (O3) – измеряется в частицах на миллиард [ppm], ±0.01ppm
Твердые частицы PM1.0, PM2.5, PM10 (Dust) – измеряется в микрограммах на метр кубический [мкг/м3], ±15 мкг/м3
Углекислый газ (CO2) - измеряется в частицах на миллион [ppm]
Температура (Temp) – измеряется в градусах Цельсия [°C], ± 2℃
Влажность (Humid) – измеряется в процентах [%], ± 5%
Общее качество воздуха (TotalAirQuality) – рассчитывается на основе всех предыдущих показателей
Выбор именно этих показателей качества воздуха связан с тем, что они оказывают основное долговременное воздействие на человека.
Режимы отображения:
Основной (Standard-mode) – все светодиоды задействованы для одного конкретного параметра
Мульти-режим (Multi-mode) – светодиоды делятся на три секции и отображают три параметра, выбранные пользователем
![Пример мульти-режима: снизу температура, затем CO2, и пыль, как видно в комнате было достаточно тепло, а качество воздуха было в порядке Пример мульти-режима: снизу температура, затем CO2, и пыль, как видно в комнате было достаточно тепло, а качество воздуха было в порядке](https://habrastorage.org/getpro/habr/upload_files/27a/370/2b1/27a3702b1689744e4c9f8d41b49ec54b.jpg)
Ночной (Night-mode) – три вертикальные линии светодиодов выделяются под отображение одного параметра, заданного пользователем, остальные выполняют роль подсветки-ночника и отображают время преаттентивно: вертикальным заполнением полосы светодиодов. Пользователь вводит временной диапазон, например от времени засыпания, до будильника, по умолчанию установлен с 21.00 до 09.00. Каждый час загорается новая линия светодиодов, таким образом яркость ночника увеличивается с наступлением утра, а в промежутках сна можно определить оставшееся время чтобы поспать. В итоге получается progress bar времени вашего сна
Примеры ночного режима с отображением CO2
![На этой картинке время примерно между 11-ю и 12-ю часами ночи, горят 2 белых светодиода На этой картинке время примерно между 11-ю и 12-ю часами ночи, горят 2 белых светодиода](https://habrastorage.org/getpro/habr/upload_files/e47/628/30d/e4762830dbe028f1b6917957614a4905.jpg)
![А на этой картинке уже утро - горят все светодиоды и количество CO2 уменьшилось А на этой картинке уже утро - горят все светодиоды и количество CO2 уменьшилось](https://habrastorage.org/getpro/habr/upload_files/712/4b5/bca/7124b5bcaf29e50f42569177317ae2af.jpg)
![Пример ночного режима на 3D модели лампы Пример ночного режима на 3D модели лампы](https://habrastorage.org/getpro/habr/upload_files/868/eab/378/868eab3786a1eb45f9c1711f26be896a.png)
Приступаем к разработке
Разработку я начал с создания общей 3D-модели устройства, чтобы примерно определить его габариты, размеры печатной платы и количество светодиодов ,которые можно разместить внутри.
За основу корпуса решил взять небольшую лампу, потому что у нее был отличный рассеиватель и по размерам он подходил. В SolidWorks сделал 3D модель всей лампы с нижней частью корпуса, и со всеми отверстиями, чтобы понимать как разместить все компоненты в столь небольшом объеме.
![3D-модель первой версии лампы 3D-модель первой версии лампы](https://habrastorage.org/getpro/habr/upload_files/51f/fe1/831/51ffe18313e2688a5d183091c4cb3418.png)
А под спойлером вы можете увидеть, как лампа выглядит внутри
![3D-модель лампы без корпуса и рассеивателя 3D-модель лампы без корпуса и рассеивателя](https://habrastorage.org/getpro/habr/upload_files/f46/7fb/0ef/f467fb0efcc264e065650c55238763dd.png)
Схему проектировал с расчетом на то, что в будущем заменю готовый модуль D1 Mini ESP32 на оригинальный ESP WROOM 32, так как порт USB-micro на D1 Mini расположен в неудобном для круглого корпуса месте (его не выведешь наружу, он утоплен в плате) и при разработке ориентировался на прошивку и отладку с помощью JTAG-программатора, ну и готовый модуль занимает меньше места. Развел печатную плату в Altium-е и заказал ее на JLC PCB.
![Верхний и нижний слои платы Верхний и нижний слои платы](https://habrastorage.org/getpro/habr/upload_files/006/a74/656/006a74656b2ea812dda7c0d7f5c0e47b.jpg)
Теперь необходимо было запустить все датчики и начать выводить первые данные на светодиоды.
Переходим к написанию кода
Основные сведения о протоколах обмена данными с датчиками я почерпнул в основном из интернета. Измерения проводятся раз в 2 секунды (так как это время измерения самого медленного датчика - DHT11) и суммируются для последующего расчета их среднего значения. Каждые 5 минут обновляются показания светодиодной ленты на основе среднего значения выбранных параметров, затем все измерения обнуляются, чтобы начать новый 5-ти минутный цикл.
Для перевода количественных показателей качества воздуха в цвет светодиодов, диапазон измерений условно разбил на 3 части (по основным цветам светодиодов, 1-я граница - минимум значения параметра, 2-я граница - оптимальное значение, 3-я граница - максимум): между первой и второй границей для отображения используются только синий и зеленый цвета; между второй и третьей - зеленый и красный соответственно. Если измерение выходит за первую или последнюю границу, то цвет светодиодов назначается синий или красный соответственно, что сигнализирует о чрезмерном уменьшении или превышении некоторого показателя.
void getRGB(int *_red, int *_green, int *_blue, float data, paramsDivideDots divideDots) {
volatile float coefficient = (pixels.getBrightness() * 2) / (divideDots.thirdDot - divideDots.firstDot); //коэффициент настройки яркости цвета в зависимости от текущей установленной яркости лампы
if ((data < divideDots.secondDot) && (data >= divideDots.firstDot)) {
/* Измерение между 1-й и 2-й границами,
используются синий и зеленый цвета, при приближении,
например, ко 2-й границе цвет становится более зеленым */
*_blue = round(-abs(data - divideDots.firstDot) * coefficient) + MAX_BRIGHTNESS;
*_green = round(-abs(data - divideDots.secondDot) * coefficient) + MAX_BRIGHTNESS;
*_red = 0;
} else if ((data >= divideDots.secondDot) && (data <= divideDots.thirdDot)) {
/* Измерение между 2-й и 3-й границами,
используются зеленый и красный цвета */
*_blue = 0;
*_green = round(-abs(data - divideDots.secondDot) * coefficient) + MAX_BRIGHTNESS;
*_red = round(-abs(data - divideDots.thirdDot) * coefficient) + MAX_BRIGHTNESS;
} else if (data < divideDots.firstDot) {
// Измерение ниже 1-й границы, поэтому цвет устанавливаем синим
*_blue = MAX_BRIGHTNESS;
*_green = 0;
*_red = 0;
} else if (data > divideDots.thirdDot) {
// Измерение выше 3-й границы, поэтому цвет устанавливаем красным
*_blue = 0;
*_green = 0;
*_red = MAX_BRIGHTNESS;
}
}
Расчет общего состояния воздуха производил следующим образом:
Если какой-то из параметров воздуха вышел за третью границу, то есть превысил максимум и качество воздуха существенно снизилось, то цвет светодиодов устанавливается только в зависимости от этого параметра;
Иначе, рассчитываем цвета светодиодов для каждого параметра по функции, представленной выше, вычисляем среднее значение каждого цвета и устанавливаем эти средние значения на светодиоды.
Выбор именно такого алгоритма обусловлен тем, что для общей оценки качества воздуха нам нужно привести все значения измерений к одной размерности, чтобы можно было вычислить среднее. Лучшей безразмерной величиной для усреднения, чем цвет светодиодов в данном случае не придумаешь.
void WS2812_showParams_standardTotal(float *data) {
// Создаем массив 5x3 (5 - кол-во отображаемых параметров, 3 - кол-во цветов)
int colorsArr[DISP_PARAMS_NUM][COLORS_NUM];
for (int i = 0; i < DISP_PARAMS_NUM; i++) {
// Рассчитываем все 3 цвета для каждого отображаемого параметра
getRGB(&(colorsArr[i][0]), &(colorsArr[i][1]), &(colorsArr[i][2]), data[i], temp_divideDots);
}
int red, green, blue;
for (int i = 0; i < DISP_PARAMS_NUM; i++) {
red += colorsArr[i][0];
green += colorsArr[i][1]; // Рассчитываем средние значения каждого цвета
blue += colorsArr[i][2];
}
red /= DISP_PARAMS_NUM;
green /= DISP_PARAMS_NUM;
blue /= DISP_PARAMS_NUM;
// Выводим получившиеся цвета
pixels.fill(pixels.Color(red, green, blue), 0, LED_NUM_PIXELS);
pixels.show();
delay(100);
}
Код проекта вы можете найти на моем гитхабе.
Итог
На данный момент прототип моей лампы умеет отображать все запланированные показатели состояния воздуха цветом, как по отдельности, так и общее качество воздуха в целом по всем параметрам. Имеется управление с помощью Blynk.
Меню устройства в Blynk
![](https://habrastorage.org/getpro/habr/upload_files/f0c/c5b/c2d/f0cc5bc2d66f6deb02c7e360c3af1571.jpg)
![В темной комнате создается мягкое рассеянное освещение, идеальный вариант для ночника В темной комнате создается мягкое рассеянное освещение, идеальный вариант для ночника](https://habrastorage.org/getpro/habr/upload_files/509/1c4/18d/5091c418dc671868f014a0fca83b3310.jpg)
В дальнейшем я планирую
Улучшить нижнюю часть корпуса, закрепить в ней плату;
Заменить вертикальную трубу для светодиодов на прямоугольные платы, с посадочными местами под отдельные светодиоды и разместить светодиоды ближе к краю платы, чтобы они были более отчетливо видны;
Развернуть веб-сервер, для удаленного управление лампой, который позволит менять режимы отображения параметров, включать одноцветную подсветку и эффекты. На веб-сервере будут отображаться текущие показатели микроклимата дома, графики показателей за несколько дней;
Сделать интеграцию с Яндекс Алисой для голосового управления. С помощью навыка “Домовенок Кузя” Алиса будет отправлять HTTP запросы на веб-сервер ESP-32 и, например, включать ночной режим или выключать лампу. Выбор Алисы обусловлен ее популярностью, поддержкой русского языка и простотой ее навыка;
Убрать датчик озона, так как его точность недостаточна для повседневных наблюдений (+- 10 ppb и диапазон измерений 0-10000 ppb, при том, что норма концентрации в помещении до 60 ppb, а при концентрации свыше 116 ppb в помещении уже находиться нельзя), а цена даже самого популярного датчика высока;
Собрать еще несколько обновленных ламп и отправить их желающим для тестов, с последующим дарением.