
Идея проекта появилась после разговора с коллегой об автоматической регулировке яркости мониторов. Оказалось, что готовых внешних устройств почти нет: встроенная функция встречается только в некоторых дорогих моделях, а существующие решения либо сложно купить, либо они стоят неоправданно дорого, либо просто выглядят не очень.
После этого разговора я решила сделать такое устройство для себя из подручных средств — у меня была простая плата esp32c3 и фоторезистор ky018. Я хотела получить быстрое и простое решение, потому что сама задача тривиальна, а для меня она при этом решала вполне реальную проблему: постоянное напряжение глаз из‑за изменения освещения в течение дня. Позже проект переехал на Waveshare ESP32-C6-LCD-1.47 со встроенным экраном.

Изначально это была очень простая вещь: без экрана, с максимально простым консольным приложением и с установкой «сделать быстро и без лишней сложности».
Почти сразу стало понятно, что саму техническую часть я более‑менее вижу, а вот с физической формой все гораздо хуже. Мне хотелось напечатать корпус, но в голове не было вообще ни одной хорошей идеи. Все варианты быстро скатывались в очередной черный ящик с креплением к монитору.
Эту проблему решил мой брат: он предложил и изготовил корпус в форме цветка с шарнирным механизмом. Благодаря этому проект стал не только визуально привлекательнее, но и в каком‑то смысле функциональнее.
Изначально я выложила проект в open source, чтобы делиться им с коллегами, и дальше тоже планирую развивать его именно в таком формате.
Что получилось в итоге
Внутри LumaBloom всего несколько компонентов:
Параметр | Значение |
|---|---|
Плата | Waveshare ESP32-C6-LCD-1.47 |
Сенсор освещенности | KY-018 |
Интерфейс связи | USB Serial |
Управление яркостью | DDC/CI (внешние мониторы), WMI (встроенный экран) |
Десктопное приложение | NET |
Интерфейс приложения | Terminal.Gui + Spectre.Console |
Корпус | 3D‑печать (Fusion + Blender) |
Материал корпуса | PLA (~150 г) |
Поддержка нескольких мониторов | Да |
Стоимость электроники | ≈ 1 540 ₽ |
Полная стоимость проекта | ≈ 1 915 ₽ (без учета доставки) |
Сценарий работы простой: цветок направляется на тот источник света, на который хочется ориентироваться — например, на окно или настольную лампу. Датчик считывает освещенность, отправляет данные в десктопное приложение, а оно уже рассчитывает нужную яркость экрана. Если хочется, дальше в приложении можно подстроить поведение под себя: поменять кривую яркости и другие параметры.

Процесс создания корпуса и печать
Со стороны корпуса брат сделал не просто декоративную оболочку, а действительно удобную физическую конструкцию: цветок, стебель, горшок, шарнирность, печатные детали по цветам и возможность собрать все это в аккуратный объект, который органично смотрится рядом с монитором.
Модель создавалась в Autodesk Fusion + лепестки в Blender. Полный список компонентов (BOM) доступен в репозитории.


В процессе были сглажены лепестки в Blender и модель стала более «мягкая».

Видео со сборкой:
Аппаратная часть
Аппаратная часть проекта достаточно простая. Основная плата здесь — Waveshare ESP32-C6-LCD-1.47, а в качестве сенсора мы использовали KY-018.
KY-018 не самый точный датчик освещенности, но для этой задачи его оказалось вполне достаточно благодаря последующей обработке данных и настройке кривой яркости.
Базовое подключение такое:
VCC→3V3GND→GNDAO→GPIO4
Встроенный LCD уже находится на самой плате, так что отдельный дисплей подключать не нужно. Это сильно упрощает сборку и делает устройство удобнее в повседневном использовании: можно сразу видеть, живо ли устройство, что происходит с датчиком и завершена ли инициализация.

Что делает прошивка
Прошивка на ESP32-C6 решает несколько задач:
читает сырое значение с
KY-018;показывает состояние на встроенном LCD;
публикует телеметрию по
USB Serial;поддерживает calibration flow для привязки значения света к яркости экрана.
Пример телеметрии выглядит так:
{ "deviceId": "esp32c6-01", "sensorId": "light0", "ts": 1234567, "value": 742, "raw": 1840, "calibrated": true }
Здесь:
deviceIdиsensorIdпомогают приложению понять, с каким устройством оно работает;raw— сырое значение датчика;value— нормализованное значение;calibratedпоказывает, завершен ли calibration flow.
Десктопное приложение
Для интерфейса использовались Terminal.Gui и Spectre.Console — хотелось получить полноценный интерфейс без написания графического приложения.
находит устройство по COM‑порту;
читает телеметрию;
определяет профиль устройства (для обратной совместимости с esp32c3);
мапит освещенность на яркость;
применяет сглаживание и ограничения на резкие скачки;
управляет яркостью нескольких мониторов.
Приложение поддерживает несколько мониторов, и в коде нет жёсткого лимита вида «максимум 2/3/4». Приложение просто собирает список всех доступных яркостно‑управляемых дисплеев из двух источников, WMI и DDC/CI, и дальше создаёт сессию на каждый найденный монитор.
В приложении есть несколько основных экранов: обзор, настройки, события и диагностика. На обзорном экране можно видеть текущее состояние датчика, активный режим яркости, состояние мониторов и то, как система реагирует на текущий свет.

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



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


Калибровка
В первой версии проекта калибровка была обязательной частью настройки устройства. Причина простая: фоторезистор выдает только относительное значение освещенности. Само по себе число вроде 1840 или 950 ничего не говорит о том, насколько ярким должен быть монитор.
Поэтому при первом запуске приложение использовало текущую яркость экрана как эталон. Пользователь выставлял комфортную яркость, устройство запоминало соответствующее значение датчика, а дальше уже рассчитывало изменения относительно этой точки.
Команда калибровки выглядела так:
{ "type": "calibrate", "screenBrightnessPercent": 65, "sensorAverageRaw": 1840}
Такой подход работал, но со временем стало понятно, что он делает систему сложнее, чем хотелось бы для понимания работы калибровки пользователем.
Поэтому в текущей версии логика стала проще. Вместо обязательной стартовой калибровки приложение работает с живым диапазоном значений датчика и отображает их на пользовательскую кривую яркости. При необходимости эту кривую можно настроить в интерфейсе, изменив диапазон датчика, gamma‑коррекцию, сглаживание, гистерезис и максимальный шаг изменения яркости.
В результате настройка устройства стала значительно проще: достаточно подключить его и при желании немного подстроить параметры под свои предпочтения, не проходя отдельную процедуру калибровки.
Что хочется сделать дальше
Интересно превратить устройство в более универсальный настольный аксессуар: объединить его с подставкой для наушников, зарядкой или системой организации проводов. При этом хочется сохранить простоту конструкции.
Еще одно очевидное направление развития — поддержка разных ОС. Сейчас проект сфокусирован на Windows, потому что именно под нее он изначально и делался, но сама идея устройства этим явно не ограничивается. Если кому‑то захочется заняться отдельной версией для другой платформы, это тоже было бы очень полезно.
Также хочется отказаться от фоторезистора в пользу более точного цифрового датчика освещенности.
Проект открыт, так что буду рада, если кто‑то захочет посмотреть код, форкнуть его, переделать корпус или собрать свою версию. И особенно интересно услышать идеи — и по программной части, и по форме устройства, и по тому, с чем еще его можно было бы объединить.
Ограничения
После публикации проекта на Reddit мы получили много полезных отзывов. Один из самых интересных касался DDC/CI.
Для встроенных экранов и для внешних мониторов в Windows используются разные API: для встроенного экрана это WMI, а для внешних дисплеев — DDC/CI. Пользователи отметили, что использование DDC/CI в Windows иногда приводит к проблемам с отдельными моделями мониторов и драйверами. На моих мониторах и брата это ограничение не проявилось, однако его стоит учитывать при использовании устройства с другими моделями.

Где посмотреть проект
GitHub: проект на GitHubLumaBloom
Reddit / r/DIY: My sister and I built a 3D printed flower that automatically adjusts monitor brightness
Reddit / r/esp32: We built a flower‑shaped ESP32 light sensor that…
Printables: модель для печати
Thingiverse: описание проекта