Всем привет и наступающими! Захотелось тут сделать пару гаджетов для друзей в их умные дома. И что-то вдруг подумалось - а что они все скучные такие? Давайте же сегодня сделаем датчик в таком форм-факторе, в котором точно не купишь в магазине, будет отличный подарок на Новый Год или Рождество. Ну и ещё чтобы подарить было не стыдно.
Сразу оговорюсь, прибор конечно же не аналоговый, а полностью цифровой. "Аналоговый" тут только дизайн, внутри же ничего сверхъестественного на данный момент времени. Используется народный датчик SenseAir S8 и инструментальный шаговый двигатель для автомобильных приборок.

Дисклеймер: электроника у меня только хобби, так что могут быть неточности и ошибки. Пишите комментарии, поправим. Также являюсь луноходом и живу в Германии, что приводит к некоторым особенностям данного поста: цены в евро + в процессе разработки мы будем использовать только свободный софт под Linux.

Полное создание данного малыша заняло примерно полтора месяца. Обзор скомпилирован из фоток разного времени, когда я ещё находился в активном поиске - на фотографиях могут быть разные версии приборов, прототипов, могут быть отличия в деталях, косяки и видна пыль. Помощь AI в данной статье не использовалась - соответственно могут быть опечатки или странная лексика. Просьба отнестись с пониманием :)

Всё опубликованное здесь и в репозитории лицензировано под GNU GPLv3.
Техническое задание
Наш прибор задумывался как девайс, который можно подарить и пользователь мог сам с ним справиться - без использования программатора, при этом должна быть интеграция в популярные системы Умный Дом (но как опция). Второе ключевое трeбование: прибор должен быть технологичным, чтобы его мог собрать и подарить кто-то другой, кому он понравился, при этом не имея геморроя типа поиска советских радиоламп или выпиливания бронзы лобзиком.
Для начала формализуем требования:
Измерение уровня CO2 с хорошей точностью и отзывчивостью;
Измерение стандартных климатических параметров: температура, влажность и давление;
Передача всего этого намерянного добра в умный дом;
Отображение текущего уровня на аналоговом дисплее прибора (стрелкой);
Прибор должен иметь подсветку;
Веб-интерфейс с отображением статуса, настройками, обновлением прошивки и проч - это важно чтобы пользователь мог с ним разобраться сам;
Желательно чтобы это не выглядело как страшное DIY;
Устройство должно быть легкое в повторении и не содержать уникальных компонентов; Компонен��ы должны быть доступны по всему миру;
Изначально я хотел сделать именно "авиационный прибор", но в процессе у меня быстро попросили сделать также ретро-версию. Соответственно, прибор у нас будет с опциями комплектации, каждая может быть выбрана независимо:
Стиль шкалы: "авиационный" и "ретро", также ставится соответствующая стрелка;
Подсветка: без подсветки, "ламповая" и "RGB";
Датчики: CO₂, климата - могут быть установлены в любой комбинации, также вообще без датчиков - в этом случае прибор будет управляться только внешней командой, например от системны Умный Дом;
Требования к конкретно прошивке: она должна быть с документацией, коммьюнити и обновлениями; Должно быть минимум велосипедов и нормальная (для обычного человека) юзабилити; Интеграция в умный дом без плясок с бубном и прошивки;
Нейминг и маркетинг
Мне не нравится, что многие хорошие девайсы зачастую сложно найти. Часто никто не парится с названием и делает что-то типа "Advanced Co2 home sensor module", которое невозможно найти или понять - где что.
Придумал название для серии датчиков - Galoped. Название не несёт никакого смысла, просто стоял курил на улице и подумал - надо что-то такое, что было в стиле Икеи, состоящие из слов "Галоперидол" и "Педиатр". Так и придумал.
Потом о таком названии пожалел, т.к. постоянно спрашивали - что это значит и вообще какой скрытый смысл, наверное можно было бы придумать что-то более очевидное. Но что есть - то есть.
Разработка концепции
Небольшая предыстория - идея сделать "аналоговый" показометр у меня была уже очень давно. Я гд��-то в году 2012 купил себе двухстрелочный тахометр от турбовинтового самолёта, который я хотел "оживить". Естественно, никто ничего за 10 лет не оживил :) Но идея никуда не девалась, прибор переехал вместе со мной в Германию в 2017 году и до сих пор стоит у меня на столе:

Данный девайс оживить сложно, ему нужно два трёхфазных сигнала, которые вращают контрольные диски внутри, которые через магнитную муфту отклоняют стрелки. Девайс большой и наверняка шумный. Но в принципе это возможно, он может указывать что-то в процентах. В данном случае лучше было бы воспользоваться современными технологиями и сделать всё с нуля - у меня вроде как всё есть для этого: старенький 3D принтер Ender-3 (ещё самая первая модель) и руки чешутся.
Конечно на рынке есть всякие-разные показометры, например на Алишке полно приборов типа такого:
Приборы с алишки


, но они все сделаны для стритсракеров и мало подходят для разумного применения. До того момента, как я понял, на чём подобные приборы работают - думал заказать на пробу, разобрать и посмотреть. Но это не понадобилось, так как оказалось, что сделать с нуля в общем будет проще.
Также рассматривал вопрос использования аналогового вольт- или амперметра. Они показывают что надо, сигнал легко намутить через DAC. Тут я застрял на том, что уголы поворота из коробки слишком маленькие - из коробки это обычно около 90° для большинства моделей. Использование реальных авиационных вольтметров или каких-то "специальных" у нас тоже отпадает (см требования по технологичности). Кроме того, я думал что для вольтметра будет куда сложнее сделать красивую стрелку и всё остальное, так как они обычно очень нежные создания, ведь управлять мы сможем только низковольтным напрямую. Всякие вольтметры от ВАЗ или советские приборы тоже отпадают, т.к. являются экзотикой за пределами СНГ.
В итоге решил делать по технологии автомобильных приборок. Они же как-то крутят там стрелками? У них там и всё красиво и угол большой. Значит, будем смотреть в этом направлении.
Следующий вопрос - а что, собственно, показывать? Можно отображать разные метрики умного дома, с работы или домашней инфраструктуры, но такое слишком специфично. В итоге выбираем уровень CO2 - подходит отлично: таких исполнений датчиков просто нет (я не нашёл ни одного), данная метрика медленно меняется, автономна (можно измерять на месте), кроме того, полезна - можно посмотреть, когда пора бы проветрить. У нас в офисе, кстати, постоянно спорят - надо ли открывать окна или нет, и такой девайс может разрешить подобные спорты путём прямого инструментального измерения. Я не буду в сотый раз расписывать - что такое измерение CO₂ и если тема для вас непонятна - почитать можно, например, тут. В качестве измерителя выбираем SenseAir S8, как самый авторитетный из народных. Почитать про него и сравнение с другими можно здесь. Ну и, конечно же, данный прибор может показывать что угодно, строго говоря CO₂ - только лишь пример, чтобы получить законченное устройство.
Когда пришла в голову идея создания нового прибора - казалось, что всё просто, берём шаговый моторчик (серву?) и приводим в движение одним из миллиона способов. Но быстро стало понятно что серва не подходит - шумная, неточная и имеет слишком малый угол поворота.
Довольно быстро я нагуглил что существует прям народный шаговый двигатель X27-168, точнее - целое их семейство. Довольно быстро нашёл пост замечательного парня guy.carpenter с экспериментами с драйверами данных двигателей. Данные моторчики широко применяются в различных девайсах, например популярны у симмеров. Так же, оказалось что их существует целое большое семейство - например есть варианты с 2-мя стрелками или датчиками нуля (варианты для часов). Эти и подобные им двигатели ставятся в практически все автомобили и широко доступны повсюду. Используются например в приборках OPEL или ВАЗ (например в ВАЗ-2110).
Существуют целый семейство и множественные клоны специальных драйверов, которые реализуют алгоритм микростеппинга: когда одна команда от контроллера поворачивает привод не на одно деление (обычно это 1/3°), а на 1/12°. Так же в даташите написано что такой способ является предпочтительным - это повышает точность и уменьшает шум привода. С большим трудом отыскал английский даташит на VID6608 и залил его в репу, потом заказал обойму из 10 штук.
Для начала заказал сразу шесть моторчиков (комплект обошелся в 12€), они приехали первыми. Драйверов у меня ешё не было, и я проверил их через рандомные H-Bridge драйвера, какие нашлись в хламе. В принципе работает, но выглядит очень так себе - точность плохая, шум сильный. Стрелка двигается неестественно. Да, в принципе уже можно сказать - работает и так, но на приборку авто пока что мало похоже.

Пока занимался другими делами - приехали драйвера (и сразу взял breakout pcb для SOP-28). Первый прототип собрал на макетных платах и приступил к тестированию. В принципе, что-то уже работало, но тут было первое разочарование: собрав прошивку на коленке в platform.io с библиотекой SwitecX25 от уважаемого guy.carpenter наткнулся на кучу багов и проблем. Пришлось их на ходу править, что довольно сильно затормозило процесс.

Начнём с того что библиотека под ESP32 вообще не работает - там имеется неосторожное использование char, который под ESP32 имеет тип unsigned и попадаем на целочисленное переполнение. Причём конкретно этот баг поправили, но версию не выкатили - если тащить библиотеку по зависимостям в platform.io, то получим баги. Потыкался логическим анализатором и нашёл ещё проблемы - например библиотека не парится по поводу необходимых тайм-аутов, которые требует даташит на VID6608.
В какой-то момент я пришёл к выводу что проще написать свою с нуля, чем разбираться в оригинальной - автор явно потыкался немного, а потом потерял к теме интерес. Пулл-риквесты висят уже давно. Но всё равно - огромное спасибо автору! Он положил начало для реализации.
С самого начала задумал использовать прошивку Tasmota как основу для девайса, т.к. содержит в себе уже всё что нужно и широко известна. Но тут меня ждало следующее разочарование, что в Tasmota имеется поддержка только H-Bridge драйверов для "обычных" шаговых двигателей.
Итого, формируем наш с вами план - как же нам собрать всё вместе?
Добавляем поддержку инструментальных шаговых двигателей в Tasmota
Находим подходящий корпус-донор (часы-будильник)
Проектируем и заказываем печатную плату
Проектируем и печатаем корпусные детали
Придумываем подсветку как-нибудь
Собираем это вместе и придумываем че-нибудь, что-бы это всё вместе заработало :-)
Добавляем поддержку инструментальных двигателей в Tasmota
Итак, раз решили - надо делать :-) Клонируем проект и погружаемся в документацию. На деле оказалось всё непросто: документация в принципе есть, но довольно отрывочная, пришлось выбрать парочку простых драйверов и использовать как живой пример. Посмотрел как сделано поддержка других библиотек - они просто закоммичены напрямую прямо в репозиторий, не как суб-модули или зависимости. В этот момент я решил что проще написать свою библиотеку и добавить её туда же + драйвер.
Про разработку особо не буду распинаться, сделано всё по образу и подобию уже существующей SwitecX25 - только без багов)) Отличия от старой:
Поддержка управления только через драйвер VID6608 и им подобным - прямое управление бессмысленно, кмк
Поддержка настроек кривых ускорения
Поддержка выставления нуля из сохранённого положения
Меньше вычислений на шаг, проще алгоритм управления
Более точное соответствие даташиту, старая не заботилась о некоторых таймингах, которые требует даташит
В итоге появилась новая библиотека: arduino-vid6608.
Библиотека использует более простой алгоритм расчёта ускорения, где имеется статический массив расстояние-задержка, и до первой 1/2 пути происходит сравнение расстояния и рост скорости, на второй половине происходит замедление. Функции задания положения асинхронные, функция vid6608::loop() чувствительна к точности вызова функции обновления.
На видео пример работы алгоритма - прибор просто показывает случайные значения. В итоге оставил так - как по мне получилось достаточно реалистично при минимуме вычислений.
В данном режиме инженерный образец отработал чуть больше двух суток без остановки - пропусков шагов и дрейфа показаний я не обнаружил.
Далее выбираем следующий свободный Driver-ID в Тасмоте и занимаем его. Мне достался номер 92, в результате чего появился на свет драйвер xdrv_92_vid6608. Обратите внимание что реализация именно в виде драйвера общего назначения, изначально я думал сделать как display, но у данного класса драйвера нет достаточно точного тайминга для обеспечения плавного движения стрелки.
Сделав первую версию драйвера - сразу же сталкиваемся с двумя новым проблемами:
Движение стрелки очень медленное - из-за того что функция цикла не вызывается в Tasmota с достаточным разрешением
Функция выставления в ноль при запуске вызывает срабатывание Watchdog в некоторых случаях - из-за блокировки главного потока на слишком большое время
Решение первой проблемы очевидно: для ESP32 в Tasmota используется FreeRTOS из пакета разработки ESP-IDF, а значит что мы можем использовать примитивы и функции операционной системы реального времени. Собственно решение простое как полено: мы просто заведём обработку обновления в отдельный поток, который по-умолчанию уйдёт на второе ядро (мы будем ставить на плату двух-ядерную версию ESP32):
// Start background RTOS thread -> required for precision timing
xTaskCreate(
VID6608XvTask, /* Function to implement the task */
"VID6608XvTask", /* Name of the task */
1024, /* Stack size in words */
NULL, /* Task input parameter */
0, /* Priority of the task, lowest */
NULL /* Task handle. */
);
...
void VID6608XvTask(void *) {
while(true) {
...
driver->loop();
...
/*
If we dont need to move any -> go sleep.
This will delay next move begin up to 500ms, but freeds up CPU a lot.
*/
if (!needToMove) {
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
}
Хорошо, но данный трюк сработает только для ESP32, а для старой ESP8266 данное решение не канает. В итоге оставил как есть - я не планировал использовать ESP8266, и в принципе драйвер там всё равно работает - только довольно медленно: порядка 20 секунд на каждые 10 градусов движения. Этого всё ещё достаточно для отображения медленно изменяющихся параметров (такие например как температура или количество лайков к этому посту). Обратите внимание что цикл в VID6608XvTask() надолго засыпает, если мотор окончил движение: это замедляет начало следующего движения на 0...500 мс, но зато существенно разгружает ядро своим сном.
Решение второй проблемы менее очевидно: надо просто добавить вызов функции yield() в процедуру выставления нужного шага:
void vid6608::step(vid6608::MoveDirection direction, uint16_t delayUs) {
...
// We should keep resources reserved by others
yield();
}
В этом случае даже многократный вызов в цикле не будет блочить нашу программу и мы избавимся от падения Watchdog.
Добавляем примитивы синхронизации FreeRTOS - мьютексы. Изначально я на них забил, т.к. решил что проблема не должна быть большая, в крайнем случае просто лишнее попадёт в вывод MQTT, а так сэкономим на ресурсах. Но нет: проблемы синхронизации многопоточности быстро вылезли на собранном девайсе, поэтому делаем себе макрос, с заворотом этого всего в ESP-32-only код:
#ifdef VID6608_RTOS
SemaphoreHandle_t vid6608Mutex;
#define VID6608_MUTEX_TAKE xSemaphoreTake(vid6608Mutex, portMAX_DELAY);
#define VID6608_MUTEX_GIVE xSemaphoreGive(vid6608Mutex);
#else
#define VID6608_MUTEX_TAKE
#define VID6608_MUTEX_GIVE
#endif
, который можно безопасно пихать везде где надо, и это всё собирается и под esp8266. Вообще, работа драйвера под esp8266 не является строго обязательной, у Тасмоты гайдлайн требует только что-бы собиралось так же для esp8266, в принципе фичу можно оставить как эксклюзив для ESP32, но я решил оставить - мы же не Apple, что бы делать искусственные ограничения людям.
Ещё хочу коснуться другой проблемы: тайминги. Для красивой отрисовки движения стрелки мы должны выдерживать тайминги вплоть до 0.3мс (300 мкс), что уже средствами таймеров FreeRTOS невозможно. Да, у них есть своя реализация delayMicroseconds(), но посмотрев в исходный код нас ждёт фрустрация: там просто цикл из nop-ов на нужное время. Что просто превращает в тепло время ожидания вместо таймеров. Проблема на данный момент не решена - если кто-то знает хорошее решение - пожалуйста напишите в комментах. Из хорошего: проблема не то что бы большая, она проявляется только во время активного движения стрелки и только на некоторых участках.
В любом случае: патчи успешно приняты в Тасмоту и баги поправлены:
Добавление драйвера - здесь можете посмотреть пример полного пакета изменений на добавление драйверов, пинов к ним и команд
Добавление поддержки сброса из сохраненного состояния и исправление багов по-меньше
На момент написания обзора драйвер уже включён в релиз Tasmota v15.2.0 Stephan. Обратите внимание что третий пакет изменений (сброс из сохраненного состояния) в релиз попасть не успел, так что база для прошивки пока что всё равно development.
Драйвер добавляет следующие команды:
GaugeZero N- процедура калибровки, гдеNопциональная начальная позиция (см следующий раздел)GaugeSet N- выставить положение в абсолютном значении шагов мотора, от 0 до 3840 (320*12)GaugePercent N- выставить положение в процентах, от 0 до 100
Драйвер поддерживает до 4 двигателей. Все команды по-умолчанию управляют первым двигателем, могут быть с суффиксом мотора (от 1 до 4), при этом 0 - это все двигатели. Пример: GaugeSet0 520 - выставит все двигатели в значение 520, GaugeZero3 - сброс только мотора №3.
При старте прошивки все двигатели сбрасываются по-очереди, что несколько замедляет инициализацию, но сделать парралельную довольно сложно, надо будет делать усложнение нашего маленького драйвера, что в общем тоже нежелательно. Оставил так.
Калибровка привода
Это была одна из главных загадок для меня: я когда только заказал и сидел ждал моторчики, пытался нагуглить или выяснить - как же делают другие? На форумах симмеров предлагали всякие громоздкие решения типа оптических датчиков, а все остальные - просто ничего не писали про это. В старой библиотеке в исходном коде нашёл объяснение - там просто происходило движение назад на всю шкалу, что, видимо, приводило к торможению привода в крайнем положении, после чего текущее положение принималось за нулевое. Это действительно работает, но приводит к долблению нашего моторчика об концевые упоры - непорядок.
Собственно решение: а давайте просто будем запоминать текущее значение «куда-нибудь» и потом использовать его для калибровки. В этом случае можно просто продвинуть стрелку вперёд на остаток от последнего значения, а потом полный круг назад. Если стрелка была в рассинхроне с тем что у нас было записано, то в худшем случае произойдёт долбление либо в начале, либо в конце (смотря куда уехало реальное значение), но в итоге стрелка будет гарантировано в нулевой позиции.
Вопрос только - куда писать? Флеш не подходит, т.к. у него сильно ограничено кол-во записи. Но всё уже придумано до нас: это - сегнетоэлектрическая оперативная память (Ferroelectric RAM, FeRAM или FRAM) — оперативная память, по своему устройству схожая с DRAM, использующая слой сегнетоэлектрика вместо диэлектрического слоя для обеспечения энергонезависимости. Чип стоит недорого и обеспечивает до 10¹² циклов записи, этого должно быть достаточно для чуть больше 31 тысяч лет непрерывной работы при условии записи раз в секунду. Реализация очень простая - давайте просто поставим недорогой чип Fujitsu MB85RC04V FRAM на плату и будем писать туда каждый раз, когда стрелка принимает команду.
Пример восстановления из сохранённого состояния. Всё работает и не долбится где не следует :-)
Вообще, помимо FRAM существуют другие решения, например DRAM с бекапом во флеш при отключении питания и им подобные, но в данном случае это избыточно. Много запоминать нам и не надо, стоит недорого. В автомобильных приборках думаю какой-то особой процедуры нет вообще - так как там система находится под постоянным бекапом батареи, у меня такой опции нет. У меня в машине приборка кстати делает тест стрелок - точно так же как у меня получилось, но это чисто декоративное, можно выключить шнурком.
Аппаратная реализация
Итак, мы отработали основные идеи и можно приступать к дизайну электроники нашего девайса.
Внимание: я буду использовать схему с исправлениями оригинального дизайна. Вы можете заметить отличия от фотографий реального девайса, но схема уже содержит исправления косяков. Это сделано для простоты повторения. Оригинальные схемы могут быть найдены в репозитории, если вас интересует именно изначальное исполнение.
Заходим на EasyEDA и рисуем схему:

Основа для всего девайса - модуль ESP32-WROOM-32, двух-ядерный, 4Мб флеша. Вы, конечно, можете поставить любой другой в том же форм-факторе.
Самое важное на данном этапе - выбрать правильные GPIO. Если вы задействуете не тот пин, который имеет двойное назначение - то это может привести к куче неожиданных эффектов, например кристалл не загрузится, если некоторые ноги будут иметь подтяжку в этот момент. Я использовал вот этот гайд: https://randomnerdtutorials.com/esp32-pinout-reference-gpios/ - всё под рукой и доходчиво.
Схема сброса

Данная схема нужна для удалённого сброса кристалла из esptool без необходимости нажимать кнопки сброса/boot. Схема срисована с модуля ESP32-Devkit-v1. Реализует элемент ИЛИ-НЕ для обеспечения очередности сигнала сброса с DTR или RST. Это обеспечивает прошивку через подходящий USB-UART модуль в полностью автоматическом режиме.
Драйвер привода

Собственно - самое главное :) Драйвер привода, двух-канальный. В стоке девайс собран с одной стрелкой, но может быть оснащён двойной при необходимости. Чип не управляется схемой сброса с MCU, как это рекомендует даташит, так как у меня чипы с алишки VID6608 реагировали неадекватно - возможно не-оригиналы :) В любом случае, прижать резет к питанию и поставить рекомендуемые конденсаторы - базовый минимум, работает как надо тогда.
Разъём расширения

На данный разъём выведены GPIO 4, 13 и 25 а так же шина I²C, к которой можно подключить дополнительные датчики или исполнительные устройства, например часы. Присутствует питание и земля. Так же на плате есть ещё два GPIO (18 и 23), выведеные просто на площадки на плате, можно подпаяться.
Схема памяти положения привода

Выполнена на I²C кристалле FRAM памяти MB85RC04V, производства Fujitsu. Имеет на борту 4Кб памяти - довольно скромно по нашим меркам, зато недорого и работает :)
Всё остальное
Дальше ничего особо интересного нет, от модуля разведены:
Кнопка сброса для ручного привода EN. Сбрасывает кристалл при необходимости. Для отсутствия сброса без необходимости предусмотрены цепи подтяжки и конденсатор против дребезга.
Кнопка GPIO34: настроена как
Button 0в Tasmota. При однократном нажатии включает/выключает подсветку, при зажатии на 45 секунд сбрасывает настройки и активирует первоначальную настройку через точку доступа.Кнопка boot: зажимает GPIO0, переводит в режим прошивки, если нажата одновременно с EN. Данной кнопки нет на фотографиях, добавлена позже.
Датчик SenseAir S8, подключён к GPIO 16 и 17 для коммуникации, порт калибровки подключён к GPIO 19
Модуль ANT20+BMP280, подключён к I²C, измеряет температуру, влажность и давление. Является опцией, при отсутствии просто не будет телеметрии.
Управление подсветкой "ретро" выполнена на схеме биполярного транзистора с открытым коллектором - может управлять чем-то ещё разумеется.
Программный триггер калибровки может помочь, если хотите откалибровать датчик принудительно (иначе он выполняет авто-калибровку каждые 7 дней). Но в прошивке пока что не придумал, как бы сделать нормальный UI под это. Тем не менее, датчик можно высунуть в окно, прижать ногу на 5 секунд - датчик тогда возьмёт текущее значение как 400 ppm.
Печатные платы
Заказываем и ждём :) У меня случилось что-то с доставкой и я получил платы только недели через три с извинениями. Платы заказаны с установкой деталей с одной стороны, без модуля ESP32 (они у меня были отдельно, плюс я не был уверен что не наделал косяков).

Народные x27-168 и им подобные рекомендуют закреплять мотор посредством пайки. Хорошая идея, в общем, но требует отдельную печатную плату. Для установки двигателя в корпус сделал простой вариантик с выводами как под разъем, так и под пайку.
Собираем и проверяем - всё почти работает :) У первой версии был один косяк - у кнопки 0 не стал ставить подтяжку, т.к. в документации Tasmota утверждалось что при такой конфигурации используется внутренний резистор подтяжки в MCU. Но нет, нифига. Если оставить болтаться в воздухе то кнопка срабатывает, что может приводить к сбросу настроек (при "нажатии" на 45 секунд). Но благо поправить очень просто - кидаем выводной резистор поверх и готово.


Ссылки на проекты в EasyEDA Web:
Корпус прибора
Это, наверное, самое важное. В этом разделе мы определим - будет ли наш прибор выглядеть как колхоз или же как что-то приличное. Разумеется, корпус можно полностью сделать на 3D-Принтере, но я эту идею отбросил сразу, по бокам будет видно что корпус печатный, а хотелось что-то более няшное, а значит - покупное и фабрично сделанное. Кроме того, у нас в требованиях пунктик что девайс должен быть простой в повторении. Следовательно, Aliexpress подходит тут слабо - у продавцов часто фактические изделия отличаются в зависимости от времени и может не соответствовать картинке. Ну и внутренности тоже могут быть разных ревизий, а нам надо что-бы всё влезало хорошо.

Начать решил с Ikea. Доводы такие: икея распространена по всему свету и у них изделия строго одинаковые везде. Следовательно, сделать себе такой прибор можно будет практически везде, купить икеевскую штуку можно даже там, где Икеи нет. Посмотрел что у них есть и выбрал Ikea Dekad. Это единственное что подходило более-менее.


Я хочу сказать что этот лот с самого начала мне не очень понравился, думал что будут сложности. Но как же я ошибался! Девайс просто как будто придуман для самоделок. Красивый и ровный корпус, очень технологичный - минимум лишнего, внутри всё на болтах. Циферблат, рамка и стекло - отдельные детали, что позволяет развернуться полёту мысли. Сверху имеется дырка для привода звонка - который электрический и приводится в действие электромотором. Его можно оставить и например удивлять пользователя громким звонком, если CO₂ высоковат. Но я решил что это будет перебор :)

От оригинального будильника нам понадобится: собственно корпус, стекло, рамка (я так думал тогда, на самом деле - не совсем), гайки и ножки из нержавейки, а так же пипка от стрелки - мы её запрессуем в нашу.
Что мы узнали на данном шаге:
Габариты прибора: цилиндр пр��мерно 95 на 50 мм
Диаметр шкалы
Название приобретает суффикс от своей сущности:
Galoped-dekad
Циферблат
Лицо нашего прибора - тут всё должно быть максимально по красоте. У меня ушло на это больше времени чем планировалось. Начал с того что нашёл видео, где мужик делает круговую шкалу в Inkscape. Сделал по аналогии - у меня только более свежая версия, там были небольшие отличия. У меня ушло много времени что бы разобраться - для того что бы модификатор "Шаблон по кривой" работал - ваш образец кусочка шкалы должен быть одной целой кривой, тогда всё делается правильно. Документ делаем сразу под будку само-обслуживания фото-печати, под 10х15.

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

И, сразу делаем версию ретро:

Для дизайна шкалы мы должны определить минимальные и максимальные значения. Смотрим на даташит на наш моторчик x27.168 и видим что полный оборот - это 315° (на самом деле 320°, но на момент дизайна шкалы я этого не знал). Теперь прикидываем: у нас есть 315*12 шагов, надо захватить примерно подходящий диапазон и минимизировать вычисления (особенно деление). Так же нужно сделать небольшую "мертвую зону" (для индикации не-готовности прибора). Рассчитываем: оставляем 15° на отображение мертвой зоны, итого у нас остаётся 300° значащего диапазона. Разбиваем его на 18 кусочков, получается что мы можем отобразить от 400 до 2200 ppm, а самое главное, что при этом получаем ровное соответствие: (300*12) / (2200-400) = 2, то есть у нас получается ровно два шага привода на 1 ppm. Это очень удобно, потому что тогда переводить одно значение в другое можно просто сдвигом на 1 бит влево или вправо, что гораздо быстрее других математических операций в MCU. Ну и у нас остаётся так же лишних 5° за пределами шкалы (и даташита) - но я просто забил на это, т.к. узнал об этом я гораздо позже и не стал ради этого переделывать. Но то значение обязательно надо учитывать при калибровке.

Идём в DM и печатаем нашу чудо-полиграфию в будке. У нас это удовольствие стоит примерно 30 копеек при печати малыми тиражами. У нас при печате в будке есть только глянцевая фото-бумага, матовую надо заказывать. Я думал что это проблема, планировал сбрызнуть матовым лаком - но это не нужно, всё выглядит супер и так.

Дальше сталкиваемся с проблемой - а как нам сделать красивую дырку в центре, что бы это не выглядело как колхоз? Я пытался просверлить или прорезать, получилось так себе. В итоге решение пришло такое - я заказал на Amazon пробойники для кожи. Просто пробить молотком получается плохо, но если зажать пробойник в патрон шуруповерта и "просверлить", то получается идеально ровное и красивое отверстие.
Подсветка
Вот тут я больше всего провозился в итоге. Изначально план был простой - в Икеевском будильнике штатная рамка как будто прям сделана для подсветки, она полу-прозрачная, изнутри накатка - выглядит супер. Но на деле оказалось всё не так просто.

Сразу стало очевидно что обычная светодиодная лента годится слабо - хотелось что-бы подсветка выглядела "лампово", то есть без видимых диодов. Для этого было решено приобрести гибкие филаментные нити на 3 вольта. Выглядят отлично, светятся тоже. Я взял вариант где выводы на одной стороне трубки - не делайте так, монтировать потом очень неудобно. Следующие версии буду делать на лентах с подключением с разных концов.

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

Для RGB подсветки приобрел 2.7мм ленту с адресуемыми диодами WS2812b. С оригинальной рамкой проблема та же - они дают тоже резкое гало вокруг циферблата, а так же выглядят ещё хуже - от диодов подсветка выглядит очень точечной, на реальные приборы мало похоже.

Я пробывал распечатать своб рамку из белого пластика, что-бы получился рассеиватель, но помогает слабо. На фото пример такого варианта. В итоге гало можно немного уменьшить, если диодную ленту клеить диодами наружу - но они всё равно светят сквозь ленту.

Пример рамки из "прозрачного" пластика, как видите тоже - так себе. В этом разделе довольно кратко, но я напечатал и проверил кучу вариантов, с диодами внутри кольца, снаружи, ближе к стеклу и циферблату - результат плохой.

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

На фото пример с RGB лентой, изолентой и промежуточной черной рамкой. Подробности можете посмотреть на 3D моделях. Филаментная лента встаёт в ту же рамку без модификаций.

Адресуемые диоды так же позволяют делать разные эффекты, например секторную подсветку или менять цвет в зависимости от показаний прибора. Секторная смотрится в целом плохо - она даёт яркий блик на противоположную сторону прибора.

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

Получается две детали: сама рамка полупрозрачная и черное кольцо против бликов на стекло.
Корпусные детали
Теперь самое время сделать пластиковую часть нашего чудо-прибора. Большая часть видимой компоненты (корпус, циферблат) у нас уже выглядят хорошо, осталось только позаботится о задней стенке, стрелке и закрыть дырку наверху корпуса (от механизма звонка). Открываем FreeCAD и приступаем к черчению наших деталей. Кстати, я думал что довольно неплохо знаком с данной CAD-Программой, но решил перед началом посмотреть обучающие видео, нашёл канал Димы Гога тоже из Германии, и просто офигел - я не знал можно сказать ничего. Большое спасибо ему, я сделал всё что нужно гораздо быстрее. Всем очень рекомендую, кто хочет научится делать красивые детали быстро и эффективно.
Стрелка
Итак, шкалу сделали, но что по ней ездить должно? Я над этим долго думал, гуглил по форумам. Там предлагают много чего - вырезать из старой карточки, пробивать, выпиливать руками из металла. Я решил всё-таки попробовать напечатать аккуратно на 3D принтере с максимальным разрешением. Если печатать вверх ногами на хорошей подложке то поверхность получается ровной, по ней даже не видно особо - что она печатная. Я в процессе поиска оптимальной формы и технологии сделал наверное штук сто этих стрелок, они у меня теперь валяются повсюду.

У меня есть любимый лак из Lidl - краска для глушителей. Она даёт прикольную матовую поверхность, я сразу решил черную часть стрелки сбрызнуть именно им. Печатаем, красим - сначала попку, потом саму стрелку белым лаком, который подрезал у своей Фрау.

Получается примерно так. Я изначально хотел заморачиваться с краской, которая в темноте светится, но потом не стал делать - лучше сделать подсветку всего прибора. Так что просто красим доступными красками / лаком и получается хорошо.

Теперь важный момент - берем оригинальную пипку от икеевского будильника, сверлим 1.8мм дырку в стрелке и запрессовываем в тисках пипку в нашу стрелку. Получается здорово - наша стрелка выглядит уже почти как настоящая в самолёте. Кроме того - она идеально плотно насаживается на вал мотора, ничего мудрить с креплением не надо. Ретро-версия стрелки выглядит почти так же и не окрашивается вообще, печатаю сразу черным пластиком.
Интерьер
В целом, прибор состоит из деталей: рамка (если комплектация с подсветкой, иначе используем оригинальную ikea), передняя панель с седлом для мотора и платы, задняя крышка, крышечьки для датчиков S8 и Климата (если устанавливается).


Вот так выглядит сборочный чертёж. Совмещаем детали, крутим-вертим и смотрим - что-бы все дырки совпадали, ничего не мешало друг другу. Из хитрого оказалось только разве что вычислить - где точно находятся дырки крепления в икеевскоом корпусе: они разнесены на 30° и 34° от вертикальной оси.

Отдельно пришлось повозиться с крышечьками - для датчиков S8 и климата. В итоге остановился на таком - крышка S8 вставляется изнутри и держится просто прижимом (или можно капнуть клея для верности), датчик климата ставится на болты к крышке. Так как оба датчика - опция, то крышки могут не устанавливаться (у меня пока что никто не просил версию без измерения CO₂ на борту, в этом случае надо будет сделать особую крышечьку - или просто удалить дырку под него).

Так же на этом этапе генерим 2D-чертеж, для инструкции для будущих пользователей :) Я для этого создал Page во FreeCad и разместил там нужный View с изометрическим видом продукта, осталось только экспортировать куда следует.

Печатаем все детали, снмиаем и очищаем. Прототипы делал из PLA. Все детали финального устройства печатал пластиком PETG черного цвета, рамка подсветки из "прозрачного". Корпусные детали и рамки - 0.2 мм слой, заполнение 20%, обдув 20%. Крышечьки датчиков и стрелка - 0.1 мм слой. Обязательно включите ironing для получения красивых плоских поверхностей, особенно которые торчат наружу.
Все модели (CAD и STL) можно посмотреть в репе: https://github.com/petrows/smarthome-galoped-dekad/tree/master/case
Крепёж
Изначально я всё собирал на саморезах М2.3 для пластика, но быстро надоело - выглядит хуже, вопросы к прочности, добавляет "дешевизны" к виду нашего серьёзного спец-изделия. Специально для устройства обзавелся болтами М2 и М3 с головкой под шестигранник из нержавеющей стали. Крепление в пластик будет на вплавляемые втулки - просто изумительная штука оказалась, как я без них жил раньше?

Винтики выглядят куда более солидно, придаёт ещё немножко "авиационного" стиля. Кое-что нужно взять от икеевского будильника (гайки и шайбы М3, пару саморезов М2 для врепления USB-C порта, если у вас нет своих).
Окончательная сборка продукта
Итак, давайте теперь соединим всё вместе! Наконец-то увидим, что за франкенштейн у нас тут получается. Выбираем комплектацию для сборки: Авиационный стиль, подсветка ламповая, оба датчика установлены.

Для сборки у нас уже должны быть все детали, что остались от предыдущих шагов или изысканий. Ну или просто печатаем новые на 3D и 2D принтерах, заказываем платы, разьёмы, провода. Раскладываем это всё на столе и любуюмся. Для сборки нужно вообще следующее:
Будильник Ikea DEKAD
Печатные детали: передняя и задняя крышки, верхняя крышка, крышечька датчиков CO₂ и климата, две детали рамки подсветки
Крепёж: Винты M3 (2 шт), Винты M2 (10 шт), Втулки для пластика M2 (10 шт)
Филаментная лента подсветки (26 см или длиннее) и провода к ней
Печатные платы: основная и двигателя
Двигатель X27-168, выводы на задней стороне
SMD кнопки 3х6, высота любая - у меня 4.5 мм
Разъёмы JST-PH 2.54 и провода: 2-pin (2 шт), 4-pin (1 шт). Мне обжимать впадлу, взял уже обжатые
Провода, гребенки, паяльник, хорошее настроение и решительность :)

Первым делом устанавливаем кристалл ESP32. Я заказывал без установки оного, т.к. у меня они были и не хотел рисковать возможным браком. Потом всё проклял - установка лютый геморрой, один модуль запорол. Заказывайте установку на заводе вместе с платой - будет тоже самое по цене и гемора намного меньше.

Сразу после установки важно проверить работоспособность - заливаем прошивку и проверяем что прибор приходит в сознание. Можно залить любую Тасмоту, потом закатаем что нужно по воздуху. Я использую данный адаптер, он имеет нужные выходы RST и DTR (обратите внимание что DTR вынесен на боковую гребенку - я сначала тупил и перепутал его с CTS и испортил одну плату, думая что сотворил непотребное). В этом случае чип прошивается напрямую через esptool или platform.io. Если такого адаптера нет, то подойдёт любой, главное что бы был совместимый с 3.3В, контакты для входа в режим прошивки коротите тогда руками. Питание лучше подавать внешнее - 3.3В в моей версии отладочного разьёма от адаптера хватало для прошивки, но уже не хватало для первого запуска. В вашей версии платы эта проблема решена (выведено 5В), но в любом случае лучше внешнее питание рекомендуется - вдруг что. В этом случае подключаем только землю от адаптера, иначе можно попалить.

Ура! Кажется что мы ничего не запороли. Пока что :)

Запаиваем остальное - разъёмы и собственно нашего героя дня - VID6608. Его ставить куда легче чем ESP32, накосячить сложнее. Обязательно прозванивайте ноги после установки! У меня всё выглядело супер, но половина ног на деле не звонилась. Если плохо припаяли то будет выглядить так: привод будет дергаться хаотично вместо плавного движения. Устанавливаем всё остальное - разъемы кнопки и прочее.

Устанавливаем гильзы под винты M2. Установка очень простая - ставим на отверстие и вдавливаем паяльником, всё получается ровно и красиво.

Запаиваем наш моторчик на плату крепления и ставим разъём. Дырки под гребенку можно рассверлить и просунуть провода туда для лучшего удержания.

После установки привода можно вырезать и приклеить лицевую панель. Подготавливаем стрелку, прессуем в неё пипку и красим. После этого можно собрать всё вместе.

На данном этапе нам важно выставить стрелку точно в ноль. Для этого натягиваем стрелку как получится (ставится она очень туго, не стесняемся), потом проворачиваем моторчик до упора (без сигнала он свободно крутится) в ноль и проворачиваем аккуратно стрелку, пока она не будет точно в начале мертвой зоны, это истинный ноль шкалы.

Разбираем будильник, снимаем с него всё ценное, удаляем наклейку и чистим. Получается красивый глянцевый цилиндрик. Стекло аккуратно вынимаем и желательно не ляпаем - жирные следы пальцев потом будет сложно убрать.

Готовим филаментную ленту - припаиваемся к выводам под прямым углом и мастрячим разъём. У меня так же припаяна корректирующая цепь: резистор на 220 Ом и конденсатор подавления пульсаций. В версии платы, что вы увидите в EasyEDA данные детали уже установлены (на момент создания самой первой версии я ещё был в сомнениях по поводу подсветки).

Устанавливаем ленту в рамку, лучше всего развернуть её "мутной" частью внутрь. Для удобства можно подклеить прозрачным скотчем. Так же подкладываем немного скотча между лепестками контактов для изоляции, нормально запихнуть в термоусадку нет места. Подрезаем ленту так, что бы ровненько сходилось - у нас тогда будет минимальный темный кусочек подсветки.

Вставляем в корпус стекло, черную рамку и нашу рамку с лентой. Важно поставить в правильной ориентации - детали сделаны так что бы входили в тугую посадку (что бы не дребезжало ничего) и провернуть потом может быть трудно. Провода должны выходить ровно снизу посередине, что-бы попасть в вырез основной детали.

Устанавливаем основную корпусную деталь, пропускаем провода подсветки. Теперь можно закрутить основные наши крепёжные магистрали: ножки и болты M3 через верхнюю крышечку.

Подсоединяем все разъёмы и устанавливаем основную плату, ориентируем её датчиками вниз. Закручиваем всё красивенькими винтами М2.

В задней крышке привинчиваем разъём USB-C на шурупчики, просунув его изнутри. Можно использовать оригинальные серебристые Ikea от будильника, но у меня есть анодированные черные, они выглядят получше. Устанавливаем решётку датчика S8, сам датчик и помещаем крышку на место, прикручиваем всё на два винта М2.

Датчик климата у нас получается торчит наружу вне корпуса. Это хорошо - тогда тепло от MCU не будет влиять на его показания.

Натыкаем наш климатический датчик на разъём и прикручиваем крышечку сверху на ещё два болта М2. Сборка завершена :-)

Отдаляем на расстояние вытянутой руки, включаем и проверяем что всё работает. Обратите внимание что без начальной конфигурации прибор даже не будет вызывать калибровку "из коробки", нам необходимо настроить Тасмоту и подготовить агрегат к работе.
Конфигурация
Первым делом надо настроить наш "модуль". Какие ноги где сидят и что делают. Для упрощения жизни я сделал темплейты (версия для RGB и Ламповых подсветок): отличия в одной ноге - она либо на WS2812B либо на транзистор диммера ламповой. Шаблон можно применить руками, но удобнее это сделать сразу в прошивке. Кроме того, нам понадобится парочка #define: по-умолчанию у Тасмоты нет поддержки ни AHT20, ни моего замечательного драйвера. Создаём файл tasmota/user_config_override.h:
// Required features for this project:
// [I2cDriver43] Enable AHT20/AM2301B instead of AHT1x humidity and temperature sensor (I2C address 0x38) (+0k8 code)
#ifndef USE_AHT2x
#define USE_AHT2x
#endif
// [I2cDriver10] Enable BMP085/BMP180/BMP280/BME280 sensors (I2C addresses 0x76 and 0x77) (+4k4 code)
#ifndef USE_BMP
#define USE_BMP
#endif
// Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code)
#ifndef USE_SENSEAIR
#define USE_SENSEAIR
#endif
// Add support for VID6608 Automotive analog gauge driver (+0k7 code)
#define USE_VID6608
// Reset VID6608 on init (default: true), change if you control this manually
#define VID6608_RESET_ON_INIT false
// Enable WS2812 leds number (any HW model)
#undef WS2812_LEDS
// If RGB backlight is used, it will have 40 LED's
#define WS2812_LEDS 40
// Template defaults, apply on flash reset.0
// You may skip this templay application, in this case please apply manually (see README.md)
// Read from file, generated by ./bin/build.sh or CI
#include "user/user_config_hw.h"
// Activate template on reset/flash new
#undef MODULE
#define MODULE USER_MODULE
Так же, для выбора уже конкретной комплектации выбираем один из двух вариантов в виде файла tasmota/user/user_config_hw.h:
/*
Part for Galoped-dekad hw version:
* Backlight: Retro
*/
#undef FRIENDLY_NAME
#define FRIENDLY_NAME "Galoped-dekad-retro"
#define USER_TEMPLATE "{\"NAME\":\"Galoped-dekad-retro\",\"GPIO\":[1,1,1,1,1,1,1,1,1,1,416,0,1600,1632,1,1,0,640,608,1,0,1,12160,12192,0,0,0,0,1,1,32,1,1,0,0,1],\"FLAG\":0,\"BASE\":1}"
, это было для ламповой, для RGB:
/*
Part for Galoped-dekad hw version:
* Backlight: RGB
*/
#undef FRIENDLY_NAME
#define FRIENDLY_NAME "Galoped-dekad-rgb"
#define USER_TEMPLATE "{\"NAME\":\"Galoped-dekad-rgb\",\"GPIO\":[1,1,1,1,1,1,1,1,1,1,0,1376,1600,1632,1,1,0,640,608,1,0,1,12160,12192,0,0,0,0,1,1,32,1,1,0,0,1],\"FLAG\":0,\"BASE\":1}"
Как видите - отличие в одном пине и редефайн FRIENDLY_NAME названии модуля - что бы не забыть :) Теперь можно собрать прошивку.
Для ленивых: идём в раздел Releases моего проекта и качаем там готовую.
Остались уже совсем мелочи: надо всё проверить и присоединить стрелку к показаниям CO₂. К счастью, в прошивке ничего даже модифицировать не надо - у Tasmota имеется Berry script в версии для ESP32, так что просто напишем скриптик и закинем в агрегат. Для автозапуска надо именовать данный чудо-файл как autoexec.be и положить его через встроенный файл-менеджер:
# Connect and preare i2c FRAM MB85RC04V
var fram_addr = 0x50
var wire = tasmota.wire_scan(fram_addr)
# Address in FRAM to store last gauge position
var addr_pos = 0x0000
# Check initialization
if !wire
print("FRAM not found")
end
# Function to write FRAM memory, 2 bytes
def fram_write_u16(addr, data)
if !wire
return 0
end
# Split address and data into two bytes
var addr_hi = (addr >> 8) & 0x7F
var addr_lo = addr & 0xFF
var data_hi = (data >> 8)
var data_lo = data & 0xFF
# ---------------- WRITE ----------------
wire._begin_transmission(fram_addr)
wire._write(addr_hi)
wire._write(addr_lo)
wire._write(data_hi)
wire._write(data_lo)
wire._end_transmission(true)
end
# Function to read FRAM memory, 2 bytes
def fram_read_u16(addr)
if !wire
return 0
end
# Split address and data into two bytes
var addr_hi = (addr >> 8) & 0x7F
var addr_lo = addr & 0xFF
# ---------------- READ ----------------
wire._begin_transmission(fram_addr)
wire._write(addr_hi)
wire._write(addr_lo)
wire._end_transmission(true)
wire._request_from(fram_addr, 2)
var value_hi = wire._read()
var value_lo = wire._read()
var value = (value_hi << 8) | value_lo
return value
end
# Read last gauge position from FRAM
var last_gauge_pos = fram_read_u16(addr_pos)
if last_gauge_pos
print("FRAM gauge pos read:", last_gauge_pos)
end
# Call Reset option from saved position, and save zero
tasmota.cmd("GaugeZero " + str(last_gauge_pos))
fram_write_u16(addr_pos, 0)
# Function to update Gauge position on CO2 change
def co2_update(value, trigger)
var drivePos = 180 + ((int(value) - 400) * 2)
if last_gauge_pos != drivePos
tasmota.cmd("GaugeSet " + str(drivePos))
last_gauge_pos = drivePos
# Save current position into FRAM
fram_write_u16(addr_pos, int(drivePos))
end
end
# Add rule to monitor CO2 changes
tasmota.add_rule("S8#CarbonDioxide", co2_update)
Данный файл в репе. Функционально состоит из двух частей - чтение / запись в FRAM и функция чтения показания CO₂:
tasmota.add_rule("S8#CarbonDioxide", co2_update)
Данный вызов вешает вызов кэллбека co2_update при обновлении. Как видите - проще некуда. Теперь наш прибор ожил и будет что-то показывать.
Для чтения и записи значений в FRAM смотрим Datasheet. Данные у нас uint16_t (должен влезать полный лиапазон, т.е. от 0 до 3840), следовательно два байта. Адрес у нас будет просто 0 - мы пока не храним там ничего больше. Как и два байта адреса. Для записи разбиваем адрес и данные по-байтно и отправляем команду на запись: сначала адрес, потом данные:
# Split address and data into two bytes
var addr_hi = (addr >> 8) & 0x7F
var addr_lo = addr & 0xFF
var data_hi = (data >> 8)
var data_lo = data & 0xFF
# ---------------- WRITE ----------------
wire._begin_transmission(fram_addr)
wire._write(addr_hi)
wire._write(addr_lo)
wire._write(data_hi)
wire._write(data_lo)
wire._end_transmission(true)
Чтение выполняется так же. Проверяем - всё работает! Добавим немного кода для восстановления состояния и обновления:
# Read last gauge position from FRAM
var last_gauge_pos = fram_read_u16(addr_pos)
if last_gauge_pos
print("FRAM gauge pos read:", last_gauge_pos)
end
# Call Reset option from saved position, and save zero
tasmota.cmd("GaugeZero " + str(last_gauge_pos))
fram_write_u16(addr_pos, 0)
После сброса привода не забываем сразу же записать новое значение - иначе у нас будет неверная стартовая позиция при отключении питания до выхода датчика CO₂ на рабочий режим.
Подключаем наш прибор к WiFi по инструкции через стандартную процедуру для Тасмоты - точку доступа, открываем ip-адрес устройства и наслаждаемся веб-интерфейсом:

Так же прибор должен показывать показания датчиков и положение стрелки в веб-интерфейсе. В зависимости от комплектации будет либо диммер "ламповой" подсветки, либо выбор цвета для RGB. Дальше уже дело техники - следуйте инструкциям Tasmota что-бы настроить интеграцию в Умный Дом и прочее, наша прошивка отличается только базовой конфигурацией и все фичи доступны:
Поддержка MQTT;
Поддержка HTTP-API;
Поддержка нативных и облачных интеграций, таких как AWS IoT или ioBroker;
И многое другое, что вы в конфиге включить не забыли ;)
У меня довольно большой умный дом в OpenHab (около 150 устрйоств), там интеграция делается стандартно, как для любой Тасмоты. В примере у нас объявляется устройство sz_climate:
Thing mqtt:topic:openhab:sz_climate "SZ Climate" (mqtt:broker:openhab) {
Channels:
Type number : rssi [stateTopic="tele/sz_climate/STATE", transformationPattern="JSONPATH:$.Wifi.RSSI"]
Type string : bssid [stateTopic="tele/sz_climate/STATE", transformationPattern="JSONPATH:$.Wifi.BSSId"]
Type number : la [stateTopic="tele/sz_climate/STATE", transformationPattern="JSONPATH:$.LoadAvg"]
Type datetime : activity [stateTopic="tele/sz_climate/STATE", transformationPattern="JS:codegen-activity.js"]
Type switch : light [stateTopic="stat/sz_climate/RESULT", transformationPattern="REGEX:(.*\"POWER1\".*)∩JSONPATH:$.POWER1", commandTopic="cmnd/sz_climate/POWER1", on="ON", off="OFF"]
Type number : co2 [stateTopic="tele/sz_climate/SENSOR", transformationPattern="JSONPATH:$.S8.CarbonDioxide", unit="ppm"]
Type number : temperature [stateTopic="tele/sz_climate/SENSOR", transformationPattern="JSONPATH:$.AHT2X.Temperature", unit="C°"]
Type number : humidity [stateTopic="tele/sz_climate/SENSOR", transformationPattern="JSONPATH:$.AHT2X.Humidity", unit="%"]
Type number : dewpoint [stateTopic="tele/sz_climate/SENSOR", transformationPattern="JSONPATH:$.AHT2X.DewPoint", unit="C°"]
Type number : pressure [stateTopic="tele/sz_climate/SENSOR", transformationPattern="JSONPATH:$.BMP280.Pressure", unit="hPa"]
}
...
Switch sz_climate_backlight "SZ Climate Backlight" <light> (g_all_sw) {channel="mqtt:topic:openhab:sz_climate:light"}
Number:Dimensionless sz_climate_co2 "SZ Climate CO₂ [%d ppm]" <co2> (g_all_co2) {channel="mqtt:topic:openhab:sz_climate:co2"}
Number:Temperature sz_climate_temperature "SZ Climate temp [%.0f %unit%]" <temperature> (g_all_temperature,sz_hz_temperature_sensor) {channel="mqtt:topic:openhab:sz_climate:temperature"}
Number:Dimensionless sz_climate_humidity "SZ Climate humidity [%.0f %%]" <humidity> (g_all_humidity) {channel="mqtt:topic:openhab:sz_climate:humidity"}
Number:Temperature sz_climate_dewpoint "SZ Climate dewpoint [%.0f %unit%]" <temperature> (g_all_dewpoint) {channel="mqtt:topic:openhab:sz_climate:dewpoint"}
Number:Pressure sz_climate_pressure "SZ Climate pressure [%.0f %unit%]" <pressure> (g_all_pressure) {channel="mqtt:topic:openhab:sz_climate:pressure"}
Number:Dimensionless sz_climate_rssi "SZ Climate RSSI [%.0f]" <network> (g_all_rssi) {channel="mqtt:topic:openhab:sz_climate:rssi"}
String sz_climate_bssid "SZ Climate BSSID [%s]" <network> (g_all_bssid) {channel="mqtt:topic:openhab:sz_climate:bssid"}
DateTime sz_climate_activity "SZ Climate activity [JS(codegen-display-activity.js):%s]" <time> (g_all_activity) {channel="mqtt:topic:openhab:sz_climate:activity"}
В данном примере мы прицепили наши итемы к показаниям датчиков на борту (CO₂, температура, влажность и давление), а так же добавили вкл/выкл подсветки. Вы также можете управлять диммированием подсветки и/или цветом (для RGB версии), для этого надо накинуть итем с типом Dimmer.
Ну и само собой - можно отцепить стрелку от датчика и управлять напрямую, уже по команде Умного Дома, для этого просто отапрвить в MQTT команду cmnd/sz_climate/GaugeSet с payload в абсолютных шагах. Можно закинуть диммер на панель УД и крутить стрелкой вручную.
Стоимость прибора
Точную стоимость сильно зависит от кол-ва изготавливаемых экземпляров и что у вас есть уже в наличии. В моём случае чисто по железу получилось порядка 50€ за прибор, и это при условии что 3Д-принтер у меня свой и корпусные детали получаются условно-бесплатные. Основная стоимость - датчик, он один получается дороже всей остальной электроники вместе взятой. Если кому-то нужен точный расчёт то пишите в комменты - добавлю.
Выводы и мысли на будущее
Вот такое у нас с вами получилось чудо техники - что думаете по поводу?

И руки размяли и подарить не стыдно. Ну и ещё в Тасмоту хороший драйвер добавили.

Старый и новый приборы вместе - гештальт закрыт.
Вообще, устройство конечно легко кастомизируется и адаптируется под суровую реальность:
Внешний вид: я написал имена людей на циферблате (кому дарил) - получается прикольный подарок в виде уникального гаджета, который в магазине не купишь;
Прибор конечно может показывать что угодно, как с датчиков, так и с внешнего управления; Тут уже на что хватит воображения - температура, влажность, черти в ступе или остаток рабочего дня на сегодня;
На плате имеется разъём расширения, который может в себя принять в общем что угодно - I²C датчики, дисплеи и прочее;
Плата может управлять двумя двигателями - как одним сдвоенным с двумя стрелками, так и двумя отдельно;
Можно докинуть ещё одну VID6608 или заменить на VID6606 - в этом случае можно будет рулить сразу 4-мя приводами;
Можно управлять оригинальным мотором будильника и громко звонить когда надо :-)
Что думаю надо бы в будущем улучшить (возможно когда вычитаете этот обзор то уже что-то сделано, см обновления в репе):
Думаю что надо-бы добавить работу с FRAM в саму Тасмоту, это неудобно что мы читаем-пишем в скрипте, думаю можно сделать автоматическую запись и чтение при калибровке. Но вот не уверен что такое примут - наверное такой патч слишком уж специфичный;
Надо разделить один 8-пиновый разъём для двух двигателей на два по 4: такое решение оказалось очень неудобное;
Разъёмы все надо перевернуть на 180°, оказалось что невозможно поставить угловые при текущей компоновке - так было бы удобнее;
Идея с Breakout-board для двигателя оказалось не очень хорошей - это сильно усложняет конструкцию и вообще бестолковое решение. Думаю хорошая универсальная печатная крышечька с креплением проводов напрямую будет получше;
Надо-бы добавить индикацию статуса какую на плату, а то юзеру невозможно понять - она живая там вообще или нет;
Использованный USB-C коннектор работает только с USB-A-C кабелем, USB-C-C не подходит. Не критично, но безусловно минус;
Исходники проекта: https://github.com/petrows/smarthome-galoped-dekad . В репе сейчас небольшой бардак из тестовых деталей и нет нормального Readme - не было времени прибраться, наведу порядок чуть позже. Но всё тем не менее есть.
Если у вас ещё есть хорошие идеи - делитесь, прикрутим. Всем хорошего дня ;)
Комментарии (64)

tormozedison
20.12.2025 22:23«инструментальный шаговый двигатель для автомобильных приборок»
Хм, был уверен, что там массово применяются логометры. Это где две обмотки, и угол отклонения зависит от соотношения токов, но не от их абсолютных значений.

ru_vlad
20.12.2025 22:23Логометры, миллиамперметры и прочее в основном на показателях топлива и температуры,а вот шаговики на спидометре и тахометре.

tormozedison
20.12.2025 22:23Спасибо, не знал.
Логометр хорош тем, что его драйверу стабильный источник питания не нужен.

ru_vlad
20.12.2025 22:23Датчики температуры и остатки топлива, это потенциометры и сигнал с них аналоговый, а вот скорость и обороты это импульсы, их проще считать и выводить через шаговый. Так по крайне мере на старых машинах.

strvv
20.12.2025 22:23Более того, они могут как 90', так и 270+, полных 360 не будет, и поиска 0 не надо, сколько дашь соотношение токов так и покажет.
Точнее если он с пружиной само возврата, при выключении будет 0, без пружины покажет последнее значение, а включив - получим соответственно токам в катушке.

strvv
20.12.2025 22:23В спидометрах и тахометрах тоже применялись, например делала Рига, и микросхемы для логометров с spi, или частотным входом в логометрический.
Например приборки 60.хххх-ууу серии.
Я не помню хххх, он един для всех отечественных авто.

Goron_Dekar
20.12.2025 22:23Механика, подсветка, полиграфия, код.
Но не хватает, как по мне, главнейшей части - метрологии. Как датчик реагирует, какая точность, как долго приходит в равновесие с окружающей средой, какая температурная погрешность, как реагирует на влажность, пыль, дым.

xSVPx
20.12.2025 22:23Это всё есть в десятках обзоров сенсора. В целом - любой co2 бытовой датчик - показометр. Точных данных они не дают. Усугубляется все тем, что часто у них включен режим автокалибровки и как следствие он думает, что минимально намерянное скажем за неделю это 400ppm. А в жилище это совершенно не всегда так.
Но тут человек красивый монитор сделал, датчик вторичен. В целом можно было его вовсе без датчика сделать, а выводить на него то, что захочется.

Tsimur_S
20.12.2025 22:23Усугубляется все тем, что часто у них включен режим автокалибровки и как следствие он думает, что минимально намерянное скажем за неделю это 400ppm.
А что насчет датчиков с запаянной колбой эталона для автокалибровки?

xSVPx
20.12.2025 22:23У меня какой-то двухлучевой, но колба ли там с эталоном большой вопрос. В любом случае калибровка по одной точке "такое себе".
Точность - удел поверенных приборов. Но в быту она в целом и не нужна. Опасность СО2 сильно преувеличена, космонавты вон при 5000ppm работают и им нормально, былоб надо меньше им сделали бы меньше.

shaaimars
20.12.2025 22:23космонавты вон при 5000ppm работают и им нормально, былоб надо меньше им сделали бы меньше
Я может вас удивлю, но космос вообще очень плохое место обитания для человека. В частности, ваши цифры это скорее необходимый для работы максимум, чем наиболее благоприятные для организма значения, которые, в свою очередь, не "около 0ppm", как может показаться.
Скрытый текст
O2 -Induced Headaches Research and past historical data has revealed an association between reported headaches and CO2 levels among crewmembers.
• A study of data collected from Expeditions 2 to 31 (N=49) found that CO2 level, age at launch, time in-flight, and data source were significantly associated with reported headaches on the ISS.
• 19 of the 49 astronauts reported experiencing headaches (~38.7%).
• To keep the risk of headache below 1%, average 7-day CO2 needsto be maintained below 2.5 mmHg (current ISS range: 1 to 9 mmHg; 3001 standard requires <3 mmHg).
2.5 mmHg это 2600 ppm
источник https://www.nasa.gov/wp-content/uploads/2023/03/co2-technical-brief-ochmo.pdf
xSVPx
20.12.2025 22:23Ну зачем-то они на мкс поддерживают ведь 5000ppm ? Одно время вроде 2500 было т.к. при 5000 "некоторые жаловались".
Речь не о 1000 совершенно. В разы больше.
К сожалению, неангажированных исследований на эту тему ныне не найти, но в бытовом смысле очевидно совершенно неважно 800 у вас или 900 прибор показывает. Не нужна большая точность, скорее тренд важен.

shaaimars
20.12.2025 22:23Было бы возможно технико-экономически сделать 400 ppm на МКС - сделали бы. Вопрос чисто денежный.

xSVPx
20.12.2025 22:23Ну так и стоимость работы космонавта огромная. Если бы он работал лучше при 400ppm емуб их обеспечили бы.
Не о 400 речь, речь то ли о 2500, то ли о 5000... В 5-10 раз разница...
Ну т.е. как-то на этом фоне беспокоится о том, 1000 у вас или 1100 не очень верно. Показывает что-то и нормально... Вот когда обычно 1200, а стало 2400 - это повод задуматься что с вентиляцией произошло.

Radisto
20.12.2025 22:23У подводников всё ещё хуже. Хотя с другой стороны, кого попало в космонавты не берут

xSVPx
20.12.2025 22:23С подводниками вообще непонятно в чём может быть проблема, ну т.е. на атомоход можно что угодно в целом загрузить. Но не делают. Это как-бы намекает, что разницы до какого-то момента неангажированные человеки не чувствуют. Даже если предположить, что всем посрать на экипаж, всем не посрать на то, насколько хорошо экипаж делает свою работу.
Я не призываю дома 5000ppm поддерживать, да это и невозможно поди, никогда столько не видел. Но и 600 тоже совершенно неадекватная цифра. Кто-то когда-то прочитал по диагонали гост, и народ подхватил эту идею.

Radisto
20.12.2025 22:23Проблема в том, что сложно провентилировать все помещения качественно и поглотить углекислый газ полностью. Там и на выходе, насколько я слышал, далеко не ноль, а потом еще и копится из-за застоя воздуха. На МКС тоже с вентиляцией не всё отлично, при том что шум от нее, говорят, сильный, то есть еще сильнее продувать будет плохо уже с другой стороны.

sim31r
20.12.2025 22:23Не хуже, военные провели свои тесты по которым при 15 000 ppm ухудшения когнитивных способностей не обнаружено и ориентируются на эти цифры
https://pubmed.ncbi.nlm.nih.gov/29789085/Methods: Using a subject-blinded balanced design, 36 submarine-qualified sailors were randomly assigned to receive 1 of 3 CO2 exposure conditions (600, 2500, or 15,000 ppm). After a 45-min atmospheric acclimation period, participants completed an 80-min computer-administered SMS test as a measure of decision making.
Results: There were no significant differences for any of the nine SMS measures of decision making between the CO2 exposure conditions.В шахтах даже повыше, где-то цифры в 50 000 ppm видел кратковременно допустимые. Но там и когнитивные способности на максимуме не требуются и есть другие опасные и вредные факторы, на фоне которых СО2 это еще цветочки.
Это в противовес исследования где норма 400 ppm, а более 1000 уже ужас-ужас, как это например
https://escholarship.org/uc/item/222631x2

LeoI5
20.12.2025 22:23Классный проект, очень подробно все расписано, спасибо!
Предложил бы посмотреть прошивку на esphome.io, там все на порядок проще делается и сразу с умным домом home assistant подружится.
petro_64 Автор
20.12.2025 22:23Спасибо за предложение, я esphome.io не использую, но посмотрел их код быстро - можно сделать поддержку без особых проблем. Может займусь как-нибудь, как будет настроение :-)

LeoI5
20.12.2025 22:23Не призываю идти в esphome. Только обратил внимание, что там вся рутина спрятана в недра, а творцам остается только реализовывать задуманное, не погружаясь в нюансы RTOS и всего остального

KivApple
20.12.2025 22:23А если управлять шаговиком с помощью аппаратного таймера? Можно настроить на выдачу нужной частоты на ножке, а в прерывании таймера считать импульсы и отключать таймер, когда пора. Либо, если минимальной частоты 100Гц (у ESP8266) мало, можно сделать программно-аппаратный PWM, когда ножкой дёргаем мы сами в прерывании таймера и можем реализовать дополнительное деление частоты. При этом RTOS нам никак не мешает.
Ну и я бы, конечно, использовал актуальную ESP32, нежели ESP8266, на фоне стоимости других компонентов, пара евро на AliExpress за платку с ESP32-C3 считай бесплатно (то есть не должно быть проблем брать контроллер специально под проект). У таймера ESP32 можно минимальную частоту сделать на уровне 1 Гц, что должно покрывать вообще все сценарии движения стрелки.

KivApple
20.12.2025 22:23Чатгпт подсказывает, что есть ещё Remote Control Peripheral и с его помощью можно генерировать массив длительностей импульсов заранее, а потом МК сам будет их выдавать с точными таймингами. Если нужно постоянно менять частоту (например, плавный разгон), можно так. Тогда вообще без прерываний и точных задержек в задаче управления.
Но на первый взгляд моя первая версия кручения шаговика PWM тоже подходит.

xSVPx
20.12.2025 22:23С памятью есть решение изящнее, чем всё время в нее писать: мониторите питание, как пропало - пишите. Возможно понадобится конденсатор поставить, чтобы времени на записать хватало.
А какие самые маленькие адресные светодиодные ленты бывают ? Диоды видел 1.5мм, но вот лент из них найти не смог:(

petro_64 Автор
20.12.2025 22:23Да, я в статье написал про такое решение, и в репе лежит даташит на готовый кристалл который является DRAM с авто-бекапом во флеш при попадании питания и обратным восстановлением. В самой ESP32 думаю такое сделать будет сложно, у него довольно непредсказуемое потребление и может быть довольно высокое, если не повезло, а запись во флеш относительно долгая операция.

xSVPx
20.12.2025 22:23У меня в одном из прототипов используется повышайка от 0.9в и конденсатор на ней довольно могучий. Так там порядка секунды есть на все дела. Была идея использовать ионистор, но заморочки с зарядом и балансировкой, нет ощущения что будет надёжнее.
Секунда - это дофига, успеваешь сигнал сос послать итд итп. А если по этому прерыванию закрывать вайфай и вообще всё лишнее, то думаю будет еще больше. Запись во внешний sd уже не помню, но десятки миллисекунд вроде, или даже единицы, в целом запас огромный, с флешем не сравнивал правда.
Можно и отдельно, конечно поставить, тем более если плату заказывать всё равно, у нас с этим потяжелее стало, собираю поделки из полуготового.

strvv
20.12.2025 22:23Я использовал имс серии fm24c16, это feram i2c. Просто лью в эту имс с определенным периодом последовательность.
При начале цикла прокручиваю адрес от конца до начала.
Сначала ищу первое неправильное значение, и если оно найдено, ищу дальше правильное. И это начало неправильных значений - это начало текущего сохранения.
Сохраняю пару значений, правильное и неправильное, причем на адрес в функции записи действует модуль на размер блока сохранения и его начало, таким образом задействую его как круговой буфер,
Остальные ячейки - калибровочные данные.

petro_64 Автор
20.12.2025 22:23А какие самые маленькие адресные светодиодные ленты бывают ? Диоды видел 1.5мм, но вот лент из них найти не смог:(
Я нашёл только 2.7 мм ленту самую маленькую - она лезет вообще отлично. Хотелось бы конечно COB - думаю это решило бы мои проблемы с точечностью подсветки, но не смог найти тукю маленькую, увы.

xSVPx
20.12.2025 22:232.7 великоваты, СОВ мне попадались у китайцев подобной ширины. Но там какие-то заморочки с управлением группами кристаллов, впрочем уверен проходимые.

ANDRE888
20.12.2025 22:23Вау очень круто и красиво. Попробуй это поставить на поток и продавай.

xSVPx
20.12.2025 22:23Купите штук сто хотя бы для начала ? Ну т.е. давая совет во все это влезать выж готовы сами влезть :)?
Можно ли такие штуки продавать - возможно. Можно ли на этом заработать денег в Германии - шансы есть, но как и у любого бизнеса они в единицах процентов.
А постановка чего-либо на поток - это отдельная и довольно скучная работа.

HMNemo
20.12.2025 22:23Такое на Etsy должно зайти. Больших денег не принесёт, но если хобби станет самоокупаемым уже успех успех. Я тут на досуге часы делаю, дёшево и сердито) уже близко к финалу.


xSVPx
20.12.2025 22:23Из Германии да, можно пытаться продавать, хотя там 90+% покупателей из штатов. Но надо иметь в виду, что уже в 22м этси был довольно плотно завален китайчятеной, и конкурировать придется и с ней тоже :(. Ну и лично мне, с приличным товаром и в 19м без рекламы не удавалось продавать в ощутимых количествах.
Некоторые люди используют этси для расчетов нагоняя трафик самостоятельно. Ориентироваться на их показатели не имея медиа-ресурса не стоит.

HMNemo
20.12.2025 22:23Китайчина дешёвая, но не то. Я бы хотел в итоге сделать премиум устройство, интересный дизайн в красивом корпусе и коробке, как дорогой подарок человеку, у которого всё есть)) и цену в $250)) и, может, штуки три в месяц продавать.

xSVPx
20.12.2025 22:23Всяко бывает, но яб сильно не рассчитывал. 36 штук в год - это прям немало. Но "не попробуешь не узнаешь".
Конкуренция на рынке дорогих подарков довольно ожесточенная. Ну и само устройство придется прям вылизать. Боюсь как бы не ушли все деньги на корпус...
А дальше высылать в виде взяток блогерам, и вот это вот всё

ANDRE888
20.12.2025 22:23У меня уже 4 есть. После того как они начнут умирать или у меня будут появляться дополнительные помещения/комнаты обязательно возьму еще. В данном посте достаточно красивый датчик получился, чего не скажешь о продающихся сейчас фабричных. Я имею ввиду которые содержат функционал измерение/отображение/пересылка по беспроводной связи и при этом качественно выглядят. Некоторые из устройств в моем доме куплены на https://www.tindie.com/, работают исправно уже более 5 лет.

alcotel
20.12.2025 22:23Красиво, винтажно, функционально (ну, конечно, ограничено проводом питания, к сожалению). Корпус точно возьму на вооружение - даже в исполнении "7 шапочек Made in China специально для IKEA" выглядит вполне достойно и прочно. Ясен перец, не как авиационный тахометр по надёжности, но уже приближается)))
Автомобильные шаговики так и работают - немножко подкручивают стрелку к нулю при старте. Это незаметно, пока не отключить их в движении, чего обычно не бывает. Ну и подкрутка не сильно затратная по мощности - заметили же, что шаговик руками крутится без усилий.

strvv
20.12.2025 22:23А если использовать логометр, то и подкручивать не надо, тупо подавай ШИМ на 2 вывода (sin/cos) и 2 вывода притягивают 1 или 0...

alcotel
20.12.2025 22:23Типа "сельсин" на минималках? Жрёт он побольше, а шаговый всё-таки жрёт только когда шагать надо.

strvv
20.12.2025 22:23Сельсин это прямая передача фазы, а тут логометр, прибор показывает соотношение токов. И угол, без учёта сопротивления синус-косинус.
Если вести ШИМ, то целочисленное.

REPISOT
20.12.2025 22:23Аналоговый датчик CO₂
Но ведь нет. Индикатор аналоговый.
Датчик - цифровой.

alcotel
20.12.2025 22:23А царь то - не настоящий! (с)
Если копать ещё глубже, то сам датчик вполне аналоговый.


REPISOT
20.12.2025 22:23Если еще глубже копать - то вообще все датчики аналоговые. По определению. Но "почему-то" они делятся на цифровые и аналоговые. По типу выходного сигнала. Или, если хотите - АЦП внутри датчика (цифровой) или снаружи (аналоговый).

xSVPx
20.12.2025 22:23Вообще-то нет. Есть вполне цифровые датчики. Например обычный плавкий предохранитель никаких промежуточных аналоговых значений не предоставляет. Или 0 или 1.
А уж какой у датчика с ним интерфейс, i2c или 0-20ma - дело десятое.

alcotel
20.12.2025 22:23По-разному бывает. Например тот же сельсин, или холловский датчик поворота - под капотом аналоговые. А энкодер - вполне себе дискретный, цифровой. Хотя все они измеряют одну и ту же физическую величину.

ZHELEZYAKA_32
20.12.2025 22:23Спасибо за статью.
Дмитрий Коржевский реализовал похожий проект как раз на аналоговом авиационном приборе, но у него был другой подход: он не использовал микроконтроллеры и программирование. Можете найти его на YouTube — он опубликовал видео около 3 лет наз ад

petro_64 Автор
20.12.2025 22:23Да, мне в комментариях на Муське тоже про него рассказали (вот ссылка на его вариант прибора) - достойная работа! Мне такой вариант, к сожалению, не подходит - нужна интеграция с УД из коробки как минимум. Ну и винтажные компоненты отдельная проблема, а хотелось что бы любой желающий мог себе сделать.
Ещё кстати отдельная ценность комментариев - очень интересные вещи показывают, я сам такого нагуглить не смог вообще ничего, когда концепцию обдумывал.

PetruhaSkilluha
20.12.2025 22:23Вопрос, что означает название в конфигах "petro_nb" (сети)

petro_64 Автор
20.12.2025 22:23В конфигах OpenHAB? Это hostname для модуля Network:pingdevice для создания виртуальных девайсов, состояние которых отражает наличие устройств в домашней сети. В данном случае это ноутбук.
ru_vlad
@petro_64 Отлично сделано! В молодости насмотрелся на подобные "будильники" (летал). Если бы возможность купил бы не раздумывая.
Dr_Faksov
Если вы летали как член экипажа, то наверняка видели, как оформляли бортовые приборы для домашнего использования.
Я, как увидел картинку, сразу подумал - будильник! Оказалось - не ошибся. Автор сам далее показывает, ка выглядит настоящий авиационный прибор. У него есть фланец. Которым прибор в быту крепится в красивую декоративную панель с основанием.
Так что за начинку - зачёт, за оформление - неуд. Из будильника может получится только будильник, извините.
ru_vlad
Вы слишком серьезно к этому относитесь, человек сделал похожий на авиа дизайн. Да можно было взять корпус от АГД или АЧС и туда все вставить, НО зачем, во первых корпуса от авиаприборов предназначены для монтажа в панель, а значит у них есть "уши". Делать еще подставку для этого, "колхоз" лютый, можете посмотреть что со списанных АЧС делают. Здесь да ,"будильник", стилизован под авиа,