Найти в Дзене

Ардуино. Полиномиальная аппроксимация заряда аккумулятора

Вот в этой записи я писал, что хочу попробовать реализовать на Ардуино отображение заряда аккумулятора с помощью полиномиальной аппроксимации, как это давно уже делают во взрослых устройствах. Плюсы такого решения в том, что заряд аккумулятора отображается сообразно тому сколько запаса энергии осталось в аккумуляторе. Процент заряда воспринимается пользователем более адекватно. Т.е если мы знаем, что заряда 10% хватит на 2 часа, то это именно так и должно быть. Минус такого решения — не универсальность. Аккумулятор штука очень динамическая и не линейная. Его ёмкость и напряжение зависят от токов заряда и разряда, количества циклов, возраста аккумулятора, химического состава, температуры и прочих менее значимых факторов. Производителя взрослых устройств такими данными снабжает поставщик аккумулятора, дополнительные данные собирают разработчики у себя в лабораториях. Это следует понимать как то, что зарядно-разрядные кривые будут справедливы только в комбинации конкретного устройства, аккумулятора и зарядника.

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

Как на зло, лаборатории под рукой нет, а поставщик аккумулятора не снабдил меня зарядно-разрядными кривыми, да и контроллера заряда на моем аккумуляторе нет. Поэтому данные я собирал сам. На это ушло несколько дней. У меня установлено 2 аккумулятора 5000 мА*ч, соединённых параллельно. Следовательно, общая ёмкость 10 000 мА*ч. Устройство от такого аккумулятора работает 26 часов. Модуль ТР4056 заряжает такой аккумулятор около 12-ти часов. Естественно за короткий срок собрать все данные не возможно, но нам и не надо. Пусть будет труба пониже, дым пожиже. Но это всё же лучше, чем просто линейная аппроксимация. На сбор данных и их обработку ушло 4 дня.

Алгоритм примерно такой:

1. Прежде всего снять напряжение с батареи во время разряда и заряда;

2. Сделать графики;

Вот примерно так у меня получилось:

-2

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

Я делал по данным из интернета, учитывая время разряда своего аккумулятора и средние токи заряда и разряда — по факту обычная пропорция. Вроде всё просто, но провозился полдня. :)

-3
-4

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

4. После того как у нас появилась таблица «напряжение-процент заряда» и график, можно попробовать построить полиномиальную аппроксимацию. В LibreOffice calc — это: «вставить линию тренда», далее выбрать «формат линии тренда» — полиномиальный, поставить галку «показать уравнение».

В результате вы увидите часть аппроксимирующей кривой и ваш полином.

-5

Но, к сожалению, это вам не поможет, даже если это будет взрослое устройство. :)

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

Во-вторых, обратите внимание на коэффициенты, например, 6,8E-13. Это очень маленькое число. У Arduino Mega 2560 тип данных Float — это 4 байта, точность получится 6-7 знаков после запятой. Тип Double — 8 бит и 15-16 знаков после запятой, не поддерживается данным микроконтроллером. Если мы заставим микроконтроллер вычислять то, что он не умеет, на выходе получится лабуда. Не верите? Проверьте сами.

Нужно решить две задачи:

- поменять местами напряжение и проценты;

- подобрать полином и коэффициенты попроще. Чтобы микроконтроллер смог посчитать.

Я начал было разбираться с LibreOffice calc, но довольно быстро понял, что задачу я решу, но потрачу неделю. Ну либо потрачу 3 дня и решу задачу на Python.

Задача полиномиальной аппроксимации распространённая. Решил поискать online сервис. И такой, к моему счастью, нашелся: https://stats.blue/Stats_Suite/polynomial_regression_calculator.html

Очень он меня выручил и сэкономил время. Даже напряжение и проценты менять местами не пришлось. :)

Вставил из буфера свои данные, выбрал точность, нажал рассчитать.

Вот что у меня получилось:

-6

График конечно мелкий, но нам он не очень уж и нужен. Кому интересно, вот покрупнее:

-7

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

Полином, описывающий заряд батареи, график выше:

y(x)=−486.8010x⁴+6961.1683x³−37045.1501x²+87023.3144x−76186.5712

Для разряда батареи чуток посложнее:

y(x)=17.8640x⁵−354.0801x⁴+2652.2137x³−9392.6518x²+15714.372x−9877.3302

-8

Далее «забиваем» эти уравнения в свою программу и получаем…

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

По традиции: больше полиномов и точного отображения заряда аккумулятора вам в ленту.