Wi-Fi программируемое ЗУ на Ардуино - Уклон (микро)

Автор SapienzSPB, 04 Апр. 2020 в 00:29

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

SapienzSPB

Всем привет!
Предлагаю Вашему вниманию самодельное ЗУ на Ардуине.  Это стартовый проект, который, я надеюсь будет развиваться. Сейчас доступны только базовые функции заряда и логирования напряжения и тока заряда АКБ.
Я  уже провел некоторую работу и на данный момент зарядное устройство имеет следующие характеристики:

Входное напряжение 12-40 Вольт
Выходное напряжение - 0 - 36В

Выходной ток - до 5 ампер (ограничен не R2R ОУ LM324 (с LMV324 планируется до 8А))
Возможность подключения к зарядному устройству через сеть wi-fi - реализована.
Возможность записывать лог-файл процесса заряда аккумулятора на компьютер - реализована.
Возможность программирования собственных алгоритмов заряда АКБ - реализована.
В качестве чипа управления используется микроконтроллер Аtmega328 в составе Arduino Nano
В качестве силовой части используются китайский шим-контроллер dc-dc преобразователей - XL4016
Для связи с компьютером используется модуль Esp8266
Для контроля тока используется датчик Холла АSC712 на 20 ампер
Разрешение уставки напряжения около 6 милливольт
Разрешение уставки тока около 5 миллиампер
Разрешение отображения напряжения - около 50 милливольт
Разрешение отображения тока - около 50 миллиампер

Планируется:
Реализация алгоритма заряда от Branimir - сделано.
Реализация алгоритма заряда от WatchCat - частично сделано.
Реализация управления через Web интерфейс - в планах
Реализация отдельного разрядного модуля связывающегося с ЗУ по Fi-Wi - в планах.
Реализация единого протокола связи, совместимого с программой от ув Vlallax (в версии ЗУ на ESP32) - в планах.

Как это работает?
Спойлер
Зарядное устройство состоит из двух блоков. Первый из них - силовая часть на ШИМ контроллере XL4016. Второй - блок управления на микроконтроллере Atmega328 (Arduino nano)
  ШИМ контроллер XL4016 увеличивает длительность импульсов на своем выходе если напряжение на пине обратной связи (FB) снижается ниже 1,25В. И соответственно уменьшает длительность импульса, когда напряжение на пине FB превышает 1,25В. Это напряжение снимается с выхода LC фильтра образованного дросселем L1 и конденсатором С13.
  Поскольку в наши планы входит регулировка напряжения в диапазоне от 0 до 40 Вольт - мы должны пропорционально уменьшить напряжение с выхода DC-DC преобразователя подаваемое на пин FB XL4016. Это делается при помощи резистивного делителя образованного сопротивлениями R16 и R17. Фокус в том что напряжение с выхода подается на вывод обратной связи не на прямую, а через компаратор  (U1:C). Он постоянно сравнивает напряжение с выхода преобразователя, поступающее с резистивного делителя, с опорным - формируемым микроконтроллером Atmega328. Если напряжение на инвертирующем входе ОУ LM324 поступающее с выхода силового блока больше чем на неинвертирующем(устанавливаемым микроконтроллером Atmega328), на выходе операционного усилителя устанавливается высокий уровень(равный 5 Вольтам), что запрещает дальнейшую работу преобразователяXL4016. Он снижает длительность импульсов на его выходе и напряжение на выходе фильтра снижается. Когда оно, минуя резистивный делитель попадет на инвертирующий вход ОУ и окажется меньше чем напряжение на неинвертирующем входе( формируемому микроконтроллером ) - на выходе ОУ установится низкий уровень, разрешающий работу ШИМ контроллера XL4016 и цикл повторится. Таким образом выходное  напряжение будет стабилизироваться посредством небольшого дрейфа, а уровень на которм это будет происходить будет устанавливать МК Atmega 328.
  К сожалению Atmega 328 не умеет формировать необходимые сигналы на своих выводах напрямую из-за отсутствия в ее составе ЦАП (цифро-аналогового преобразователя). Она может лишь генерировать ШИМ на нескольких ее портах.  Существуют простейшие интеграторы на RC цепочках для преобразования ШИМ сигнала в постоянное напряжение. Его величина пропорциональна коэффициенту заполнения ШИМ и в нашем случае находится в диапазоне от 0 до 5 Вольт. В схеме используется четырехзвенный интегратор на резисторах R14, R3, R2, R1 и конденсаторах С9, С8, С7 и С6. Четыре звена фильтра позволяют добиться более высокой скорости работы интегратора, что надеюсь, пригодится в дальнейшей работе ЗУ в MPPT режиме.
  Таким образом в ЗУ осуществляется контроль напряжения микроконтроллером и ШИМ контроллером, посредством формирования опорного напряжения для компаратора на ОУ. Точно таким же образом работает контроль тока, реализованный на операционном усилителе U1:D. С собственным интегратором образованным резисторами R6, R7, R8, R9 и конденсаторами C1, C2, C3, C4. Единственным отличием работы петли контроля напряжения от петли контроля тока является то, что ноль токового датчика свдинут вверх на 1/2 напряжения питания микроконтроллера. Это особенность работы датчика холла на микросхеме  ASC712 и не привносит никаких проблем  для наших задач, ибо на программном уровне работать с такими условиями легко.
  Надо отметить также что "с завода" Arduino Nano имеет всего лишь 8 битный ШИМ, Его крайне недостаточно. Потому в коде используются модифицированные установки таймеров чтобы расширить этот параметр до 13 бит, что позволяет более точно устанавливать выходное напряжение и ток ЗУ. 
  Для того чтобы ограничение тока и напряжения могли работать одновременно и не мешали  друг другу выводы операционных усилителей подключены к пину FB Шим контроллера через диоды D1 и D2. Это классическая схема подключения, альтернативы которой я пока не нашел. Также для согласования АЧХ интегратора и ШИМ контроллера они связаны друг с другом через своего рода делитель напряжения на резисторах R12 и R13. Их сопротивление выведено эмпирическим путем и именно с таким их значением достигается максимально стабильная работа ЗУ.
Компараторы напряжения и тока на ОУ U1:С и U1:D имеют огромное усиление. Оно избыточно и мешает нормальной работе ЗУ. Для его ограничения, а также предотвращения самовозбуждения на высокой частоте были введены цепи коррекции АЧХ с помощью R18/C10 и R11/C5. Их номиналы также выбраны эмпирическим путем и не подлежат обсчету.

Если у сообщества есть что добавить или скорректировать в текущей схеме - прошу высказываться. Я много не знаю в этой топологии и допускаю, что где-то мог ошибиться.
Схема, плата, герберы, 3Dмодели, исходный код ЗУ, WiFi переходника, логера
Спойлер

находятся в репозитории по адресу https://drive.google.com/drive/folders/1bXLFiqD_cJWHJ8oovo8J3kcEkR2EFQ0M?usp=sharing
Фотовиды
Спойлер




Видеоматериалы
Спойлер

1. Тест точности ЗУ - https://youtu.be/GfInjRXSICg
Группа в Telegram https://t.me/UklonGroup

Примечание
Спойлер
Концепция претерпела некоторые изменения. Основной мыслью стало желание создать своего рода экосистему.  В нее входят (пока) зарядные устройства и нагрузки. Все они сбрасывают данные на логер внутри сети. Планируется также создать продвинутую нагрузку с встроенным измерителем внутреннего сопротивления, которая также будет слать данные на логер.  Таким образом можно собирать неограниченное количество устройств и они все будут логироваться в одном месте - логере с SD картой, на который можно зайти и посмотреть графики с любого устройства зарегистрированного в данной экосистеме.  Мне кажется это гораздо удобнее чем выделять SD карту каждому из устройств, а потом переключаться между ними. Я ниразу не программист, поэтому мой код будет выглядеть диллетантски, но он работает уже очень долго и стабильно. Надеюсь опытные коллеги помогут довести его до ума.

Последнее обновление 2022.01.23

Иван77

[user]SapienzSPB[/user],
Отличная работа, нужная, спасибо!
Осталось определиться с производством печатных плат.
   Ну и хотелось бы первых результатов.
Ездю и ездю.

SapienzSPB

Спасибо! Постольку поскольку фронт работ был проделан не маленький и просто описать все займет достаточно большое время и силы - буду выкладывать материалы по мере готовности. Разводка заводской платы в данный момент начата.  Но постольку поскольку все хочется сделать по уму - отрисовка идет ооооччччень медленно. За три вечера осилил только вход и выход силовой части.  Впереди еще управление, питание , интегратор и тд.  В общем не могу обещать скорые герберы, но работа движется. Та плата которая выложена в репозитории - относительно стабильно работает и может быть рекомендована для самостоятельного изготовления посредством ЛУТ.  В ближайшее время сниму видеоролик в котором покажу интерфейс и точность работы контроллера. Так же будет цикл статей по организации работы устройства и программированию собственных профилей заряда.  Так что постепенно все поясню. 

SapienzSPB

Потихоньку начинаем разбирать код. Начнем с главной вкладки программы.
Вообще-то таких вкладок в данном проекте 11. Каждая отвечает за свое направление. К примеру вкладка Menu содержит весь интерфейс контроллера. Вкладка Profili - алгоритмы заряда. SetPwm - управляет установкой опорных напряжений. Вкладки очень удобны когда код разрастается до нескольких тысяч строк.
На первой вкладке я все закомментировал. Вопросов вроде возникнуть не должно. Если есть - задавайте. 
Спойлер


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

SapienzSPB

Сердце любого контроллера - его величество Таймер. Именно он позволяет запускать функции в нужный момент, вести подсчет времени, задержек, дельт, отсылки данных, опроса датчиков и многое другое.  Обеспечивать многозадачность, с легкостью добавлять или вырезать модули кода. И все это под его руководством будет работать не мешая друг другу. На скрине пример таймера обеспечивающего приемлемую точность +-20 секунд в сутки и при этом поедающий наименьшее количество ресурсов(я их штуки две скопипастил и штуки три придумал - этот оказался быстрее всех). Отсутствие данного обязательного элемента добавит кучу геморроя автору устройства. Его присутствие позволяет сделать сколь угодно сложный девайс собирая его из модулей как лего. 
Спойлер
Вроде все закомментил. Если что - спрашивайте.
Кстати специально даю скрины из-за подсветки синтаксиса. Ибо код пропущенный через форматирование форумного движка нечитабелен от слова совсем. Весь код показанный здесь будет выложен в репозитрии для свободного скачивания.

SapienzSPB

#5
Ниже приведен общепринятый алгоритм опроса датчиков напряжения и тока.

Спойлер
static unsigned int Value = 0;                      // создаем временную переменную для хранения заначений с АЦП
for (int i=0; i<128; i++){                                   // останавливаем программу на 128раз*128мкС = 16,3 мС и начинаем опрашивать порт АЦП
  Value =Value +analogRead(UbatPin);    // накапливая сумму в переменной
}
Value =Value /128;                                    // затем вычисляем среднее арифметическое разделив сумму 128 замеров на количество замеров
UbatForLcd = Value * Ubatcorrect;             // затем переводим значение напряжения в удобоваримый человеком формат умножив его на коэфициент пересчета
Value =0;                                                      // очищаем переменную для следующего вызова опроса напряжения 
Итак почему я против такого подхода. 
Во первых колоссальное замедление времени выполнения программы. Опрос одного датчика длится 16 мС а четырех уже 65 мС. Для силовой электроники слишком большая задержка.
Во вторых зачастую бывают моменты когда нужно срочно закрыть открытый транзистор, из-за возникновения в его цепи короткого замыкания. Как показывает практика закороченный полевой транзистор IRF3205 на аккумулятор 12V 7.5AH при условии, что его закрыли в течение 2 мС остается живым. И вот представьте ситуацию, когда контроллер начал опрос датчика тока который длится 16 мС и случается КЗ. Контроллер видит что с датчика приходит сигнал о перегрузке, но пока не закончит опрос - отреагировать не сможет. Через 10 мС переход транзистора пробит тепловым перенапряжением. Я хочу избежать данного случая.
В третьих при таком подходе мы всегда получим значение кратное количеству разрядов (без промежуточных значений). Я использую метод который позволяет получить промежуточные значения - как при оверсемплинге.
Спойлер
Опрос датчиков обязан проводиться при каждом круге программы. Это позволит отреагировать на внештатные ситуации.
Профи программирования конечно же скажут, что Float использовать не комильфо. Что он замедляет расчеты и ест ресурсы.
Я могу ответить, что все продиктовано необходимой скоростью реакции схемы считывания, управления и защиты. Если у системы есть запас по быстродействию - почему бы не использовать Float. Тем более что скорости современных микроконтроллеров позволяют им основное время выполнения программы простаивать. Пусть считают себе на здоровье.  :-)
Как видите добавить дополнительный АЦП в прошивку совсем не сложно. Нужно только вместо встроенного АЦП опрашивать внешний и присваивать полученные значения уже готовым переменным.  Дальше прошивка сама разберется что делать с этими данными.

SapienzSPB

#6
Пришло время поговорить  от том как можно опросить кнопки контроллера для того что бы он понял команды пользователя.
Во первых определимся с тем какой вид клавиатуры будем использовать. Во всех своих проектах (с разными вариациями) я использую клавиатуру с пятью кнопками занимающую один порт АЦП.
Спойлер
Из плюсов
Во первых - такой метод управления экономит порты
Во вторых - он расширяем, если требуется большее количество кнопок
В третьих - обходится трехпроводным подключением
Есть и минусы
Подвержен наводкам со стороны силовой части (реально нестабильно ведет себя, без фильтрующего конденсатора у пина аналогового входа).
Не исключены ложные срабатывания из-за "подгоревших контактов", нечетких нажатий или изношенных кнопок. Все это случается, конечно, но не сказать чтобы часто и не критично для самодельного устройства. В дальнейшем можно принять меры для того чтобы сбои происходили как можно реже. 
Америку я не открою и скажу что любой пример от ардуино разработчиков подойдет. Конкретно в своем проекте я использую такой код:
Спойлер
Он хоть и не самый понятный и оптимальный на данный момент - содержит все необходимое для его модификации и расширения. Когда понадобится двойное нажатие - все можно сделать не меняя концепции. Долгое удержание, сверхдолгое удержание, ускорение при удержании, секретное комбо - без проблем.
Обратите внимание на то что переменная KodKnopki  используется как для выявления нажатия, так для выявления какая кнопка нажата, так и (будущем) для сообщения программе какая конкретно кнопка нажата. Для нее можно выделить отдельную переменную, но так ИМХО экономичнее.
Помимо этого если посмотреть на схему - станет видно что уровней для нажатия не пять, а шесть. И скрытое шестое можно использовать для каких либо сервисных функций, калибровки, переназначения, вращения клавиатуры или сброса контроллера.
Также можно обратить внимание на то что в данном примере появились локальные статические байтовые переменные ShagAntidrebezga  и TimerAntidrebezga. Они не видны из любой другой части программы и не уничтожаются при окончании исполнения функции. Их значение сохраняется от вызова до вызова функции OprosKnopok().

Ну вот..  осталось посмотреть как работают меню и можно делать хоть зарядник, хоть стиральную машину.... ;-D

SapienzSPB

Остался последний шаг в создании скелета нашего ЗУ - написание меню. На них отображается информация, а так же меняются установки.
На скрине ниже показаны простенькие менюшки для понимания как оно работает.  Для навигации используется глобальная переменная Menu. Изменяя ее мы можем перемещаться по экранам контроллера, быстро добавлять или убирать дополнительные менюшки, организовывать их в нужном порядке, менять содержимое отображаемой информации.   
Спойлер
На этом этапе мы получили все необходимое для того чтобы сделать любое устройство интерактивным. С кнопками, менюшками, настройками и контролем датчиков.  Далее, добавляя или убирая дополнительные модули - можно приспособить проект под разные задачи. Зарядка АКБ, измерение сопротивления, настраиваемый термостат или любое другое нужное устройство.
Позже поговорим о том как сохранять настройки в энергонезависимую память. ЗУ будет запоминать установки и восстанавливать их из памяти при включении.

SapienzSPB

Настало время поговорить о том как сохранять настройки в энергонезависимую память и восстанавливать их при загрузке контроллера.
Для данных задач в программе есть две функции  eepromSave() и  eepromRead()
eepromSave() - (условно) вызывается в двух точках программы: когда пользователь поменял значения установленных токов и напряжений и когда пользователь переместился по меню.
eepromRead() - (условно) вызывается один раз в блоке инициализации настроек контроллера Setup().
Для сохранения параметров используется функция EEPROM.put(x, y); где x = номер ячейки энергонезависимой памяти , а y = значение переменной(которое нужно сохранить)
EEPROM.put примечательна тем, что перед записью в ячейку сначала читается ее содержимое, а запись производится только если считанное содержимое отличается от того, которое планируется записать.  Таким образом экономится ресурс ячеек памяти.  Могу порекомендовать записывать ячейки с шагом 4 байта.  Это позволит в дальнейшем менять типы переменных  в программе не опасаясь, что они наползут на соседние ячейки памяти. Код для реализации бэкапа параметров достаточно простой и пояснять по нему особо нечего.
Спойлер
Единственное что могу отметить - номер ячейки хранящей номер меню - выставляйте последней.  Если вдруг будут проблемы с записью в память -  вы с большей долей вероятности узнаете об этом по незапоминанию последнего актуального пункта меню.
В следующий раз создадим свой первый профиль заряда, декларируемый большинством производителей  Ca-Ca батарей.

SapienzSPB

#9
Давайте поясню как внутри контроллера устанавливать ток и напряжение.
В меню установки напряжения отображается значение переменной UbatMax
В меню установки тока отображается значение переменной IbatCharge

Алгоритмы же управляются собственными переменными Ulim(для напряжения) и Ilim(для тока)
Соответственно алгоритму можно сказать снизить ток вполовину от установленного: Ilim=IbatCharge/2
Или отследить достижение напряжения АКБ до установленого: if (UbatLcd>=UbatMax)
Можно вообще проигнорировать пользовательские установки и жестко прописать свои напряжения и токи: Ulim=16.3 , Ilim=0,12

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

Для тех кто читает это в первый раз - все может показаться неочевидным.  Для тех кто следил за моими выкладками и изучал код - все должно быть предельно понятно. 

Ниже небольшой пример не сложного собственного профиля заряда WatchCat(). Подразумевает, что значение тока выставленного пользователем равняется 1/10 этикеточной емкости аккумулятора. Пользовательские настройки напряжения - игнорируются. 
WatchCat() вызывается функцией Zaryad() из таймера 10 раз в секунду
Спойлер
Состоит из пяти шагов:
1. Если батарея очень разряжена - заряжаем током 0,05С до достижения ею напряжения 12В.
2. Когда батарея достигла напряжения 12В - увеличиваем ток до 0,1С
3. Когда батарея достигла напряжения 14,4В - снижаем ток до 0,05С и увеличиваем напряжение до 16,5В
4. Когда прекратился рост напряжения и тока - продолжаем зарядку в течение двух часов.
5. По истечению двух часов - выставляем буферное напряжение 13,8В и индицируем конец зарядки.
Спойлер

К данному алгоритму заряда можно выделить собственное меню по образу и подобию уже описываемых ранее.  Расположить его можно так же где будет удобно. Для старта зарядки можно повесить на среднюю кнопку клавиатуры флаг WatchCatStage=1;
Спойлер

Иван77

[user]SapienzSPB[/user], спасибо!
   Вы один, из немногих практиков, кто создает очуменные вещи на этом форуме! Не останавливайтесь, пожалуйста!
Ездю и ездю.

Alex_Soroka

Цитата: SapienzSPB от 15 Апр. 2020 в 00:48
WatchCat() вызывается функцией Zaryad() из таймера 10 раз в секунду 

вы делали тест на стабильность вашей программы ? сколько часов работает без зависаний и переполнения стека?
особенно в варианте "нажимаю кнопки все подряд и часто а ЗУ отчитывается по ВайФаю"?
Что будет с ЗУ если отвалится ВайФай сеть? если будут "битые пакеты"?

SapienzSPB

Конкретно это Зу по понятным причинам не проходило тест на долговечность. Но одно из прошлых отвёз этими выходными на дачу. Аптайм 1 год 36 дней. Хотел даже фотку сделать - да лень за телефоном спускаться было. То есть оцениваю работу программы как стабильную.
Вопрос по поводу кнопок не до конца понял. Стэк в работе с ними не переполнится даже если очень захочет не зависимо от того будет обмен данными по вай фай или не будет.
Если отвалится вай фай сеть ядро ЗУ на это начихает.
Передающий модуль перезагрузится по вачдогу и связь восстановится.
Если будут битые пакеты из Зу в модуль связи - парсер модуля связи проигнорит их. На принимающей стороне web интерфейса - парсер проигнорит их. Программа логер - проигнорит.  :-)
Ps. Ах да. Припоминаю что когда модуль связи разрабатывал его максимальный аптайм был 43 дня. Соответственно потом я с ним работал и выключал его стартуя аптайм заново.

SapienzSPB

Наверное заметили что алгоритм WatchCat() использует dU и dI - производные напряжения и тока для вычисления скорости падения/нарастания величин.
Модуль который занимается их вычислением простой и маленький.
Вот он:
Спойлер
Данные обрабатываются с произвольным интервалом. Я использую 20 секунд.
Добавить вторую производную не составит никакого труда. Просто скопипастить 4 строчки.
Поскольку почти все переменные в прошивке - глобальные - они доступны в любой момент, в любой части кода, любой функции которой они понадобятся.

Alex_Soroka

Цитата: SapienzSPB от 21 Апр. 2020 в 22:53
Если отвалится вай фай сеть ядро ЗУ на это начихает.
Передающий модуль перезагрузится по вачдогу и связь восстановится.
Если будут битые пакеты из Зу в модуль связи - парсер модуля связи проигнорит их.
это в последовательной-то программе процедурного программирования?  ;-D это фаантастика ...
и как насчет временных задержек реалтайма процесса заряда - выдачи тока - ничего не запинается при этом?
сделайте сами для себя стресс-тест работы зу при проблемах связи, при одновременном просмотре осциллом что там выдается из зу.

SapienzSPB

Временные задержки фиксированы и составляют 100 миллисекунд.  ;-). При этом ничего не запинается. Ослик подтверждает.  Никакой фантастики все строго по физике.
Алекс, я же ещё не показывал как связь реализована. С чего вдруг Вы решили что она будет на что - то влиять?

Alex_Soroka

Цитата: SapienzSPB от 25 Апр. 2020 в 10:25
Временные задержки фиксированы и составляют 100 миллисекунд.  ;-)
агащас, толькот вот ТСР стек об этом не знает, у него по RFC таймауты ожидания могут быть до 30 сек, насколько я помню.
а у вас процедурное программирование, оно в реалтайме работает чудесато, и не рекомендуется для построения реалтайм систем с повышенными требованиями к надежности.
Вачдог это хорошо, но это подпорка-костыль а не решение  :hello:

ЦитироватьАлекс, я же ещё не показывал как связь реализована. С чего вдруг Вы решили что она будет на что - то влиять?
да знаю я как на Ардуино связь реализуют  B-) вы же свой ТСР стек не писали, значит у вас как у всех - процедура на процедуре, что внутри процедур и как обрабатывается коллизии и критические проблемы связи - не знает никто, даже "сообчество" которое писало эти библиотеки.
Мне по большому счету, все равно что вы там и как пишете.
Просто вы делаете ЗУ, а это реалтайм, поэтому "залипание" в режиме работы приведет к вскипячению АКБ и разрушениям.
Процедурное программирование, особенно "с классами и наследованиями" широкой дорогой к этому приведет.
Ведь те кто просто вас скопирует не будут все это читать - а потом начнутся "голоса из зала" с разрушенными АКБ вашим гениальным ЗУ  :hello:
ничего личного  :hello:

SapienzSPB

Алекс, а с чего Вы решили что я пользуюсь TCP?
Ардуино вообще не рассматривается как система построения долгоиграющих серьезных устройств, однако же мне интересно, я делаю, у меня работает. Если наблюдаю какие-то чудеса - разбираюсь где ошибка и исправляю ее.
По поводу реалтайма - Kass уже подробно разжевал, что это такое. Я его услышал, понял и перестроил текущие проекты именно под него. Так что надеюсь с реалтаймом проблем не будет.
То что Вы подразумеваете под реалтаймом - я понимаю как время реакции системы. В моем случае оно достаточно низкое - ибо железное. Так что ПО не контролирует ток и напряжение от слова совсем. Оно только задаёт режимы ограничений железному DC-DC  преобразователю. А у железа сами понимаете скорость и точность выше микрокроконтроллеров.
На лавры гениального ЗУ я не претендую. Эта ниша к сожалению уже занята  :-D
Моя цель научить последователей процедурному программированию на примере простенького цифрового импульсного ЛБП. О надёжности расскажет только время и пользователи которые решат повторить разработку.