PC FAN CONTROLLER: Minimum Viable Product (firmware)
Выложил минимально рабочую версию прошивки контроллера вентиляторов! Это далеко не финальный вариант, в нём ещё будут корректироваться ошибки (которых там наверняка полно, поскольку функционал достаточно богатый и я ещё не всё успел проверить). И хотя без управляющего софта бОльшая часть плюшек недоступна, но это уже по-настоящему рабочая версия, а инженерная версия управлялки у меня сейчас в работе и я очень надеюсь, что в каком-то виде я смогу её выпустить до НГ.
ЧТО НОВЕНЬКОГО:
Думаю, для начала будет полезно привести список фич прошивки, а потом уже я остановлюсь на некоторых из них более подробно:
✔️ Плавная линейная регулировка ШИМ и питания. Резкие изменения не допускаются.
✔️ Автоматическое определение состава оборудования для каждого из 6-ти каналов:
- ШИМ,
- датчик оборотов,
- MOSFET,
- DC-DC,
- вольтметр.
✔️ Автоматическое определение особенностей подключенных вентиляторов:
- тип (3/4 провода),
- максимальные обороты,
- минимальные стабильные обороты,
- наличие "ступеньки" между 99% и 100% ШИМ,
- возможность работы тахометра при 0% ШИМ.
✔️ Возможность работы каждого из вентиляторов в нескольких режимах:
- нормальный (управление по датчикам температуры),
- ручной (управление через ПО),
- тихий (минимальные обороты),
- турбо (максимальные обороты),
- выключен.
✔️ Возможность быстрого выбора профиля мощности для каждого из вентиляторов, например, для нормальной работы и для работы под экстремальной нагрузкой.
✔️ При выходе вентилятора из строя, его нагрузка перераспределяется между рабочими вентиляторами в соответствии с настраиваемой таблицей коэффициентов.
✔️ Отслеживание внешних (программных) датчиков температуры (например, MB, CPU, GPU, HDD) через управляющее ПО.
✔️ Для каждого из датчиков настраивается уровень его влияния на каждый из вентиляторов.
✔️ При потере связи с датчиком (физическим или программным) есть возможность автоматического запуска зависимых от него вентиляторов на максимально предусмотренную другими настройками мощность.
✔️ В общей сложности система может обслуживать до 35 датчиков.
✔️ При пониженных температурах вентиляторы полностью отключаются.
✔️ ПИД-регулятор для поддержания стабильных оборотов при изменении напряжения питания или нагрузки на винт.
✔️ Предупреждения и алармы на:
- понижение общего питания,
- понижение питания каждого из вентиляторов (по сравнению с ожидаемым),
- снижение оборотов (по сравнению с ожидаемыми),
- остановку вентилятора,
- проблемы с оборудованием (нет связи),
- превышение температуры на датчиках,
- отсутствие показаний программных датчиков (от управляющего ПО),
- нехватка оперативной памяти,
- проблемы с конфигурацией.
✔️ Два режима работы: обычный и профессиональный (долго, шумно, надёжно).
✔️ Чередующиеся страницы Flash для хранения конфигурации.
✔️ Выбор наиболее свежей и наиболее полной страницы конфигурации при загрузке.
✔️ Отладочный логгер в UART.
✔️ Объектная модель абстракции оборудования (прошивка может легко быть масштабирована на другой состав и количество оборудования, могут применяться разные драйверы устройств без необходимости внесения изменений в основную логику прошивки).
ПОДРОБНОСТИ:
Хоть я и надеялся не возвращаться к вопросу тестирования вентиляторов, но обнаружилась ещё одна проблемка, которой пришлось уделить внимание: некоторые вентиляторы имеют неприятную особенность, при которой обороты нелинейно и очень резко возрастают при переходе от 99% к 100% ШИМ (кочерга на графике ниже). Проблема тут в том, что при использовании ПИД-регулятора (для поддержания стабильных оборотов), эта особенность приводит к появлению автоколебаний когда целевые обороты находятся где-то между оборотами на 99% и на 100% ШИМ, а это недопустимо. Так что пришлось делать детектирование такой особенности и вносить изменения в алгоритм, позволяющие избежать автоколебаний.
В остальном, с детектированием параметров вентиляторов и с их последующей работой никаких особенных проблем не возникло. Причём, благодаря моим подписчикам в Telegram, я расширил номенклатуру тестируемых кулеров, добавив два 9-амперных монстра и два микровентилятора 2x2см и все они успешно прошли тестирование и помогли скорректировать несколько мелких ошибок, а стало быть, девайс стал более надёжным и должен работать с большинством продаваемых кулеров.
Ещё я сделал алгоритм перераспределения нагрузки со сбойных вентиляторов на те, которые ещё в работе. По умолчанию нагрузка делится примерно поровну на каждый из оставшихся, т.е. если один из 6-ти кулеров зафейлился, то на оставшиеся пять перераспределится по 20% его нагрузки. Можно было это сделать как-то более хитро, учитывая мощность каждого кулера ну и можно ещё анализировать уровни влияния кулеров (как выпавших, так и оставшихся) на датчики и таким образом распределять нагрузку не от балды, а по определённым правилам. Но, я решил что всё равно в итоге всё будет зависеть от физических параметров системы (расположение кулеров, их размеры и реальная мощность), поэтому в любом случае такие вещи будут требовать ручной настройки (ну, или можно забить и не париться). В общем, возможность есть и это хорошо.
Далее, я немного переделал алгоритм опроса OneWire-линий подключаемых DS18B20 - теперь датчики будут найдены независимо от того, к какой из линий они будут подключены и можно их переключать туда-сюда даже "на лету".
Отдельного внимания заслуживает механизм сохранения конфигурации во Flash-памяти микроконтроллера. На один экземпляр полной конфиги я выделяю одну страницу Flash'а, т.е. 2КБ. Этого оказалось достаточно, чтобы влезли все системные настройки, конфигурации всех 6-ти каналов кулеров (железо + настройки подключенного вентилятора) и осталось место ещё на 35 датчиков температуры! Я не стал ограничивать максимальное количество подключаемых цифровых DS18B20 - не вижу в этом особенного смысла. А ограничение в 35 датчиков распространяется на все доступные их типы: внутренние, подключаемые и софтовые. При этом внутренние датчики использовать не обязательно, их можно отключить в прошивке, либо удалить их после сканирования. Так что, 35-ти штук должно быть более чем достаточно.
Так вот, про сохранение конфиги: одна страница с полной конфигурацией занимает 2КБ. Это слишком много чтобы при внесении изменений в настройки использовать ОЗУ в качестве временного буфера. Поэтому я сделал чередование нескольких страниц Flash, так, чтобы можно было напрямую переписать всё из активной страницы настроек в новую и вносить изменения только в том месте, где нам это необходимо.
Плюсов у этого решения несколько:
➕ Во-первых это экономия ОЗУ. Вместо 2Кб у нас задействуется из стека только небольшой участок под ту структуру, которую мы хотим обновить или добавить. Остальное копируется из предыдущей страницы.
➕ Во-вторых это, конечно же, повышение ресурса Flash-памяти, используемой под конфигурацию. Количество занятых под это дело страниц настраивается перед компиляцией прошивки и на данный момент я использую 4 страницы. Минимально можно настроить 2, это понятно. А максимум ограничен свободным объёмом флеша, оставшимся в микроконтроллере от прошивки.
➕ А главное это то, что при записи новой страницы предыдущая активная конфигурация на другой странице не стирается. И если что-то пошло не так, внезапно выключилось питание или ещё какой-то Fatal Error случился, то запоротая страница не окирпичит устройство и не приведёт к необходимости повторного сканирования железа и вентиляторов. А всего-навсего будет загружена предыдущая, а если сказать точнее, то наиболее полная и наиболее свежая из полных страниц конфигурации. Такой, своего рода, Dual BIOS, как в материнках делают. Только тут их можно настроить больше чем Dual.
Для мониторинга и управления я, как и планировал, использовал USB Custom HID, который хорош тем, что не надо ставить никакие драйверы и достаточно системного драйвера USB HID. Обмен идёт пакетами по 64 байта и этого объёма достаточно, чтобы передавать любые, используемые в прошивке структуры и даже ещё остаётся запас под развитие. Сейчас ещё я периодически вношу изменения в перечень команд/ответов и прочие особенности протокола, но когда это дело б/м устоится я сделаю небольшой документик по нему.
Ну и дополнительно я запилил простенький логгер в UART, который выводит самую основную инфу о происходящих в железке событиях. Я сейчас осторожно подумываю о том, чтобы в дальнейшем продублировать возможность полноценного мониторинга и управления на UART, но пока это только Tx.
Вообще, весь проект у меня получился самописный (за исключением HAL/USB/CMSIS), потому как у меня были очень серьёзные опасения относительно того, что прошивка не влезет в 128К, да и насчёт ОЗУ были вопросы. Но в следующей версии вполне возможно что я переключусь на LVGL, ну и в сторону всяких там boost и stl можно будет посмотреть, если будет такая потребность.
И отдельно стоит отметить получившуюся структуру проекта, при которой я могу элементарно просто переделать прошивку под контроль одного единственного вентилятора или наоборот, 20-ти или 30-ти вентиляторов. Могу сочетать разные аппаратные средства, всякие внешние ШИМ-контроллеры и датчики напряжения. Могу добавлять другие типы температурных сенсоров и прочее и прочее. В общем, очень гибкая штука, которую, в принципе, можно встраивать куда угодно.
ЧЕГО ВООБЩЕ НЕ БУДЕТ:
❌ Отказался от идеи использования ресурсов MAX31790. Всё делается программно. О причинах я подробно писал в предыдущем посте, но если в двух словах, то чип дорогой, чип редкий и при этом далёк от идеала. Тянуть его за собой в следующие версии устройства нет никакого смысла.
❌ Также отказался от идеи автоматической регулировки питания дигипотами на основе встроенных в них датчиков температуры (до инициализации микроконтроллера). В принципе, ничто не мешает это сделать, но смысла особого нет. Зато вместо смысла есть резкие скачки напряжения при запуске устройства. А нам это не надо.
❌ Передумал переписывать STM'овские библиотеки для USB Custom HID. Пока работал над протоколом обмена, пришёл к выводу, что запрашивать репорты от девайса я не буду. А вместо этого буду всё делать управляющими командами по специально выделенному под эти цели репорту (SET REPORT). Обработка GET REPORT была одним из моментов, которые приходилось делать путём внесения изменений в STM'овские Middleware-библиотеки для USB. И эти изменения были одной из причин, по которым я хотел эти библиотеки переписать. Всего таких причин было три, из которых ещё одну, а именно необходимость вносить правки в исходники после каждого изменения проекта в CubeMX, я поборол дополнительной строчкой в скрипте пост-процессинга для проекта в MX. Эта строчка всего-навсего удаляет один свежесгенерированный файлик, а его копия с уже внесёнными требуемыми изменениями хранится в отдельной папочке и именно она впоследствии и компилируется. И остаётся последняя причина - лицензирование STM'овских Middleware под SLA0044, которая не допускает редистрибуцию под MIT или ещё чем-то. Ну и, как, говорится, чёрт с ним. Просто опубликую под несколькими лицензиями, как это обычно делается и всё. Зато сэкономлю кучу времени!
А ЧТО ЕЩЁ БУДЕТ:
Следующим шагом я хочу доделать инженерный вариант управляющей софтины. В которой будут все возможные функции по конфигурированию, но она будет в вырвиглазном дизайне, в ней не будет возможности работы в бекграунде и, скорее всего, не будет возможности добавлять реальные софтовые датчики (только тестовые). После чего выложу проект на Гитхабе, а дальше буду думать про вторую версию платы и полноценную версию управлялки. Неожиданно так получилось, что мой коллега - очень крутой спец по UX (не преувеличиваю, мы с ним много работаем и мне очень нравится его подход к делу) согласился помочь в разработке дизайна для этой самой управлялки. А это очень хорошо. Это даёт шанс, что на этот раз дизайн будет не "программисту так было удобнее", а действительно для людей.
Ура, товарищи!
Что касается прошивки, то в ближайших планах на её развитие у меня намечено следующее:
➖ Система автоматического определения уровня влияния вентиляторов на датчики. Тут пока сложно сказать, будет это реализовано средствами прошивки или средствами управлялки, но фича такая очень нужна.
➖ Аппроксимация зависимости оборотов от управляющего сигнала (или потребляемого тока) и вычисления нагрузки на вентилятор на основе получившейся функции.
➖ Аппроксимация оборотов вентилятора для определения их стабильности (нужно для определения характеристик вентилятора).
➖ Подумаю насчёт дублирования управления через UART.
➖ Как минимум экранные шрифты требуют замены, а возможно что и весь интерфейс (с переходом на LVGL).
➖ Надо будет крепко подумать насчёт ПИД для поддержания стабильной температуры на датчиках. Для одной пары датчик-вентилятор тут ничего сложного нет. А вот как быть когда их много и они все друг на друга влияют... вот тут я пока даже примерно не представляю себе как бы это можно было сделать. Вполне вероятно, что придётся ограничиться жёсткой связкой датчик-вентилятор.
Надо сказать, что неожиданно проект получается очень интересный (хоть и после долгой паузы), так что, буду работать и держать вас в курсе! Оставайтесь на связи.