
HAQuDA – это настольная лампа, которая отображает данные о параметрах окружающей среды: качестве воздуха, температуре и влажности, при помощи цвета освещения. Если параметр в норме, то он зеленый, а если завышен или занижен, то красный или синий соответственно. У лампы есть несколько режимов отображения: стандартный, мульти, ночной, режим светильника, и возможность управления с помощью собственной веб-страницы и голосовых помощников.
Всем привет!
В период пандемии большая часть нашей жизни перестала выходить за рамки четырех стен, из-за чего остро встал вопрос о состоянии окружающей нас среды, о качестве воздуха в квартире, так как он напрямую влияет на наше самочувствие и продуктивность. В этой статье я хотел бы рассказать о процессе разработки волшебного домашнего отображателя качества воздуха.
С чего все началось…
В книге "Будущее вещей" Дэвида Роуза, автор рассказывает о свойствах волшебных вещей, способных облегчить нашу повседневную жизнь: часы с цветовым отображением количества потребленной электроэнергии в квартире, волшебный шар, способный цветом показывать совершенно разные параметры: от количества аллергической пыльцы на улице, до текущей стоимости акций. Почему эти вещи волшебные? Их концепции взяты из известных фантастических произведений. Судите сами: в повести Дж.Р.Р. Толкина "Хоббит, или Туда и Обратно" есть волшебный кинжал - "Жало", который кроме своей основной задачи - убивать полчища орков и гоблинов, еще и предупреждает своего хозяина о присутствии недругов - отличный пример простого интерфейса человек-устройство. Развитие идеи волшебных устройств воплотилось в устройстве ОПЭДИ, которое отображает на календаре количество потребленной электроэнергии в квартире, в разработке которого и я принимал участие. Мне захотелось продолжить эту идею и я решил собрать станцию мониторинга качества воздуха, которая совмещала бы в себе все необходимые датчики и имела "волшебные" свойства. Так и родилась идея HAQuDA…
Для чего он нужен?
Основная идея устройства заключается в простоте передачи информации о состоянии дома человеку. Существующие модели датчиков качества воздуха передают информацию понятную специалистам, но специфичную для простых пользователей, например единица измерения CO2 – PPM, а количество летучей органики (формальдегиды, ацетон, этанол и т.д.) измеряется в микрограммах на кубический метр. ОКВоДи позволяет моментально и понятно показывать информацию о качестве воздуха, за счет ее отображения цветом: от зеленого – качество воздуха хорошее, до красного - когда уже пора проветрить помещение. В этом устройстве заложен принцип “преаттентивности” (от англ. pre-attention) - показывать тот объем информации, который необходим для принятия решения, что позволит человеку быстрее обрабатывать информации, не фокусируя на ней внимание.
Примеры преаттентивных отображений данных


Как он устроен?
ОКВоДи представляет собой лампу цилиндрической формы (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) – светодиоды делятся на три секции и отображают три параметра, выбранные пользователем

-
Ночной (Night-mode) – три вертикальные линии светодиодов выделяются под отображение одного параметра, заданного пользователем, остальные выполняют роль подсветки-ночника и отображают время преаттентивно: вертикальным заполнением полосы светодиодов. Пользователь вводит временной диапазон, например от времени засыпания, до будильника, по умолчанию установлен с 21.00 до 09.00. Каждый час загорается новая линия светодиодов, таким образом яркость ночника увеличивается с наступлением утра, а в промежутках сна можно определить оставшееся время чтобы поспать. В итоге получается progress bar времени вашего сна
Примеры ночного режима с отображением CO2



Приступаем к разработке
Разработку я начал с создания общей 3D-модели устройства, чтобы примерно определить его габариты, размеры печатной платы и количество светодиодов ,которые можно разместить внутри.
За основу корпуса решил взять небольшую лампу, потому что у нее был отличный рассеиватель и по размерам он подходил.В SolidWorks сделал 3D модель всей лампы с нижней частью корпуса, и со всеми отверстиями, чтобы понимать как разместить все компоненты в столь небольшом объеме.

А под спойлером вы можете увидеть, как лампа выглядит внутри

Схему проектировал с расчетом на то, что в будущем заменю готовый модуль D1 Mini ESP32 на оригинальный ESP WROOM 32, так как порт USB-micro на D1 Mini расположен в неудобном для круглого корпуса месте (его не выведешь наружу, он утоплен в плате) и при разработке ориентировался на прошивку и отладку с помощью JTAG-программатора, ну и готовый модуль занимает меньше места.Развел печатную плату в Altium-е и заказал ее на JLC PCB.

Теперь необходимо было запустить все датчики и начать выводить первые данные на светодиоды.
Переходим к написанию кода
Основные сведения о протоколах обмена данными с датчиками я почерпнул в основном из интернета. Измерения проводятся раз в 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


В дальнейшем я планирую
-
Улучшить нижнюю часть корпуса, закрепить в ней плату;
-
Заменить вертикальную трубу для светодиодов на прямоугольные платы, с посадочными местами под отдельные светодиоды и разместить светодиоды ближе к краю платы, чтобы они были более отчетливо видны;
-
Развернуть веб-сервер, для удаленного управление лампой, который позволит менять режимы отображения параметров, включать одноцветную подсветку и эффекты. На веб-сервере будут отображаться текущие показатели микроклимата дома, графики показателей за несколько дней;
-
Сделать интеграцию с Яндекс Алисой для голосового управления. С помощью навыка “Домовенок Кузя” Алиса будет отправлять HTTP запросы на веб-сервер ESP-32 и, например, включать ночной режим или выключать лампу. Выбор Алисы обусловлен ее популярностью, поддержкой русского языка и простотой ее навыка;
-
Убрать датчик озона, так как его точность недостаточна для повседневных наблюдений (+- 10 ppb и диапазон измерений 0-10000 ppb, при том, что норма концентрации в помещении до 60 ppb, а при концентрации свыше 116 ppb в помещении уже находиться нельзя), а цена даже самого популярного датчика высока;
-
Собрать еще несколько обновленных ламп и отправить их желающим для тестов, с последующим дарением.
Автор: Илья