Авторизация
Регистрация

Напомнить пароль

Самодельное зарядное устройство для аккумуляторов Makita LXT

В одном из предыдущих обзоров я рассказывал о неоригинальных аккумуляторах Makita LXT и проблемах их зарядки. Но, на самом деле, история началась несколько раньше – в августе 2024-го года, когда в моем парке инструментов наконец появился первый шуруповерт Makita и пара неоригинальных батарей. Тогда-то впервые и встал вопрос, чем и как их заряжать. И после непродолжительных поисков и раздумий было принято решение делать свою зарядку. О том, что у меня получилось и пойдет речь сегодня.


Вступление или зачем делать самому?


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

  • Оригинальные зарядки Makita
  • Неоригинальные зарядки с желтым разъемом
  • Неоригинальные зарядки без желтого разъема

С оригинальными зарядками всё просто – они предназначены для зарядки оригинальных аккумуляторов Makita. Также в них можно заряжать совместимые аккумуляторы, которые имеют желтый разъем и поддерживают базовые команды протокола Макиты. Основные модели – DC18SD и DC18RC. Еще существует двухпортовая DC18RD, но она встречается заметно реже. Выбирать зарядный ток в оригинальных зарядках нельзя, производитель делает этот выбор за вас. В случае DC18SD это «скромные» 2.6 А, а в случае DC18RC – до 9 А, поэтому последней категорически не стоит заряжать китайские аккумуляторы, зачастую для них это оказывается слишком много.

Неоригинальные зарядки с желтым разъемом предназначены, прежде всего, для зарядки неоригинальных аккумуляторов с таким же желтым разъемом. Заряжать оригинальные аккумуляторы в них теоретически можно, но лучше не стоит, так как это может заблокировать контроллер батареи, и дальнейшая её судьба окажется под вопросом (в сети есть проект разблокировки таких батарей, но, говорят, работает не со всеми). Устройств с регулировкой тока в этой категории я тоже не встречал, в основном это что-то фиксированное между 1.5 и 3 А и зависит от конкретной модели. Заряжать аккумуляторы без желтого разъема в таких зарядка не выйдет, они туда физически не встанут.

Наконец, неоригинальные зарядки без желтого разъема предназначены для зарядки таких же неоригинальных батарей и составляют самую многочисленную группу. Здесь можно найти как зарядки форм-фактора DC18XX Makita, так и зарядки меньшего размера, напоминающие подставку под батарею, и даже зарядки форм-фактора «блок питания» с круглым разъемом на выходе. Зарядные напряжения, токи, качество изготовления и цена таких зарядок очень сильно отличается, последнее время стали попадаться даже версии без прямого контроля выходного напряжения и тока буквально «за копейки». Поэтому пользоваться такими зарядками без предварительного анализа их характеристики и схемотехники я бы не рекомендовал. Также следует отметить, что сами батареи без желтого разъема часто предназначаются для «совместимого инструмента» и могут не работать с оригинальным без их доработки.

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

Отдельно хочу добавить, что разрабатывать свое зарядное устройство и писать данную статью я начал раньше, чем разобрался с основными нюансами зарядки батарей Макита, которые описал в предыдущем обзоре, поэтому с самого начала желтого разъема в моей зарядке не было, что вы и увидите на многих фотографиях. Добавлен он был несколько позже, однако править уже написанный текст и обновлять фотографии не стал, пусть история останется в хронологическом порядке.

Конструкция


Самым простым вариантом самоделки было бы взять готовую китайскую CV/CC понижайку, добавить блок питания, регулятор, а также индикатор тока и напряжения и запихнуть это в какой-то походящий (возможно, напечатанный) корпус. Но таких проектов и без меня достаточно, вряд ли вам будет интересно читать про подобное еще раз. Да и я удовольствия от простого соединения проводов не получу, нужно что-то посложнее. Поэтому, будем собирать «с нуля». А если так, то начнем с желаемых характеристик:

  • Зарядка батарей форм-фактора Makita LXT 18 В
  • Регулируемый ток заряда от 1 до 6 А
  • Возможность корректировки напряжения заряда
  • Отображение текущего напряжения, тока (2 знака после запятой) и отданной ёмкости (3 знака после запятой)
  • Звуковая индикация окончания заряда
  • Отсутствие ощутимого разряда батареи, если во время зарядки вдруг пропадет сетевое напряжение

Чуть позже, подумав, решил сделать её еще более универсальной и добавить:

  • Возможность зарядки любых литий-ионных батарей до 5s (до 21 В)
  • Режим лабораторного источника питания 0 – 23 В, 0 – 6 А

С требованиями определились, теперь перейдем к HLD. В качестве «мозга» зарядки был выбран «народный» микроконтроллер ATMega328p. Выбрал его по нескольким причинам: во-первых, он всё еще широко распространен, и, если вдруг кто-то захочет повторить данное устройство, с мегой будет проще, чем с тем же STM32. Во-вторых, у AVR по современным меркам весьма ограниченные ресурсы, а писать программу в таких условиях значительно интересней простого закидывания кода очередным уровнем абстракций. Ну, и, в-третьих, эти меги у меня есть, так почему бы не найти им применение получше, чем лежание на полке?

Первоначально хотел, чтобы регулирующая часть была чисто аналоговой, выполненной в виде DC-DC на готовом чипе вроде XL4016, а МК лишь бы отдавал ей указания, какое напряжение (или ток) выдавать на выход. Но первое практическое испытание показало, что внешние управление XL4016 работает не очень хорошо, ведь внутреннее опорное напряжение неизвестно, а коэффициент усиления встроенного ОУ ошибки уменьшить нельзя. Получается очень нестабильная петля ОС, и схема то и дело желает перейти в генераторный режим. Да и у меги не очень высокая частота ШИМ для большой разрядности аналогового напряжения. Поэтому склонился в сторону выполнения DC-DC непосредственно на самой меге, воспользовавшись её ШИМ-генератором.

Теперь нужен экран для отображения напряжения, тока и отданной ёмкости. Сначала хотел использовать пару 8-рязрядных 7-сегментных индикаторов на MAX7219, но потом вдруг осознал – кому в наше время интересны красные сегментные индикаторы? Сейчас в моде цветные экраны с высоким PPI, как в смартфонах. И ведь такой есть у меня – им оказался небольшой IPS-дисплей с разрешением 240х240 точек и очень приятной цветопередачей, практически, маленький монитор:


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

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

Схема


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


Чтобы обеспечить на выходе напряжение 21 В, на вход необходимо подать больше. Я выбрал 24 В как стандартный номинал, найти блок на такое напряжение не составит труда. Но для того, чтобы запитать МК, необходимо 5 В, значит нужен понижающий DC-DC. Когда в устройство ставятся понижающие преобразователи, приоритет следует отдавать тем чипам, которые формируют требуемые напряжения без внешних деталей. Так надежней – если вдруг цепочка делителя обратной связи повредится, на выход может пройти более высокое напряжение, которое выведет из строя остальную часть схемы. Поэтому изначально я планировал использовать XL1509E-5.0, но в местном Чиподипе случился «пересорт» и указанной микросхемы в наличии не оказалось. Пришлось быстро искать на замену что-то подходящее по их каталогу, и таким преобразователем оказался TPS5430 (U5), после чего схема и плата были переделаны под него. В принципе, здесь подойдет любой другой DC-DC на 5 В, т.к. нагрузка небольшая, а у TPS5430 есть недостаток с точки зрения радиолюбителя – снизу корпуса у него расположен 9-й контакт, который необходимо обязательно подключить к общему проводу, без этого преобразователь не будет работать. То есть, запаять такую микросхему только паяльником не получится, нужен фен или нижний подогрев.

Для питания дисплея требуется напряжение 3.3 В. Оно получается из 5 В с помощью линейного стабилизатора AMS1117 (U3). Поскольку МК питается от 5 В, необходимо согласовать уровни напряжений выходных сигналов, идущих к дисплею. Вариантов согласования есть несколько, но я выбрал самый простой – гасящие резисторы. Такой вариант не самый красивый, но допустим, т.к. контроллер дисплея имеет в своем составе защитные диоды, идущие от каждого входа на плюс питания. Через эти диоды все излишки входного напряжения будут отправляться на питание контроллера, главное ограничить входной ток. При указанном номинале резисторов R2, R3, R6 и R7, ток через каждый не будет превышать 4.2 мА, что в сумме никогда не превысит 20 мА, которые потребляет дисплей в любом режиме. Дисплей подключается к плате через разъем J9.

За генерацию ШИМ-сигнала преобразователя будет отвечать канал А таймера 0 МК. Этот сигнал с выхода OC0A через усилитель на Q11, Q17 и Q13 идет на затвор P-канального полевого транзистора Q1. Конечно, сначала хотелось применить в схеме N-канальный транзистор, ведь у него и ниже сопротивление канала, и для управления можно использовать готовый чип вроде IR2110 или HCPL-3120. Но тогда понадобился бы отдельный источник +12 В для цепи затвора, стандартные схемы «вольтдобавки» здесь не подойдут, они все требуют непрерывной генерации, а тут преобразователь может быть выключен на неопределенное время. Поэтому, скрепя сердце, установил в схему P-канальный IRF4905, которые были куплены на Али много лет назад. Они определенно поддельные, но недавно в комментариях меня несколько утешили, предположив, что в ключевом режиме их использовать еще можно. Конечно, они значительно слабее оригинала, но у меня и мощность на нем рассеиваться будет в пределах 10 Вт, так что попробую.

Для управления ключом остановился на усилителе на дискретных компонентах. Q11 инвертирует сигнал и усиливает его по амплитуде до 12 В, затем двухтактный усилитель на Q13 и Q17 усиливает ток, чтобы быстро перезаряжать ёмкость затвора ключа Q1. Все транзисторы в усилителе переключаются быстро, потому что никогда не входят в насыщение. Q11 за счет резистора R33 в цепи эмиттера, а Q13 и Q17 – потому что включены по схеме с общим коллектором. А чтобы броски тока при перезаряде ёмкости затвора Q1 не вывели транзисторы из строя, в схему добавлен ограничительный резистор R30.

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


На осциллограмме желтым цветом показан сигнал на выходе OC0A МК, розовым – на коллекторе Q11, а голубым – на затворе Q1. На следующих осциллограммах розовым цветом показан сигнал на стоке Q1, а желтый и голубой остались прежними:


Хорошо видно, что ключ очень быстро открывается за 10 нс с задержкой 35 нс относительно управляющего сигнала. С закрытием ситуация похуже – задержка составляет 180 нс, а само закрытие около 50 нс (на осциллограмме разрешение по оси Х уже 100 нс/дел). Тем не менее, это прекрасный результат, учитывая, что данной схеме предстоит работать на частоте всего 62.5 КГц.

Остальная часть ШИМ-преобразователя достаточно стандартная и состоит из дросселя L2, диода D1, снаббера C30+R48 и выходных конденсаторов C12 – C14. Далее напряжение через нормально разомкнутые контакты 3-5 реле К1 и токоизмерительный шунт R29 поступает на выход устройства.

Реле К1 на выходе установлено по двум причинам. Во-первых, МК будет отключать аккумулятор, если вдруг во время зарядки пропадет питающее напряжения, чтобы предотвратить разряд аккумулятора на внутренние цепи обесточенного зарядного устройства. А, во-вторых, оно позволит МК разорвать цепь, если вдруг транзистор Q1 выйдет из строя, и, таким образом, защитить аккумулятор от бесконтрольного заряда. Функция аварийного отключения крайне важна при заряде совместимых аккумуляторов Makita, ведь они могут не иметь в своем составе полноценных BMS, целиком полагаясь на контроль со стороны зарядного устройства. А литий-ионные аккумуляторы ни в коем случае не следует перезаряжать, поэтому при выходе зарядного устройства из строя и отсутствии защиты имеется вполне реальный шанс возгорания аккумулятора. Дополняя этот факт использованием ключевого транзистора сомнительного качества, становится очевидно, что наличие защиты в схеме просто необходимо.

Измерение выходного тока осуществляется с помощью шунта R29 сопротивлением 10 мОм. При таком номинале и максимальном токе 6 А на шунте будет падать 60 мВ и рассеиваться 0.36 Вт, что является оптимальным соотношением. Но 60 мВ – слишком мало для непосредственного измерения с помощью АЦП МК, поэтому напряжение с шунта подается на инструментальный усилитель с коэффициентом усиления 10, выполненный на U1.2. Так как опорное напряжение АЦП задается электронным стабилитроном D2 ICL8069 и примерно равно 1.22 В, максимально возможное измеряемое значение тока составляет 12.2 А. Это больше 6 А, которые я хочу снимать с устройства, но такой запас оказался полезен, позже я поясню почему.

Аналогичный инструментальный усилитель с коэффициентом усиления 1/20, выполненный на U1.1 используется для измерения выходного напряжения зарядного устройства, которое снимается непосредственно с выходных клемм. Использование четырехпроводной схемы позволяет компенсировать падение напряжения на проводниках, дорожках печатной платы, контактах реле, а также на токоизмерительном шунте, что, в свою очередь, позволяет установить шунт в минусовой провод устройства и немного упростить схему. Данный усилитель не увеличивает, а уменьшает напряжение в 20 раз, что позволяет МК измерять значения примерно до 24.4 В.

Несмотря на сложное название, инструментальный усилитель выполняет простую функцию. Это усилитель разности напряжений – он берет значение напряжения на прямом входе, вычитает из него значение напряжения на инверсном входе и усиливает полученную разницу в заданное число раз. Существует несколько известных схем инструментальных усилителей, из которых наиболее правильная – на трех ОУ. А самая простая на одном. К недостаткам простой схемы относится необходимость точного подбора резисторов делителей так, чтобы коэффициенты деления двух цепочек были очень близки, что затруднительно в серийном производстве, поэтому там применяют более сложные схемы. А для самодельного устройства вполне подойдет и простая, если предварительно подобрать мультиметром резисторы с максимально близкими сопротивлениями. Подбирать следует пары R4/R14, R5/R15, R18/R22 и R19/R23. Точное значение не так важно – это позже можно будет скорректировать программно, главное, чтобы резисторы в парах были максимально одинаковы.

Сначала я использовал в инструментальном усилителе распространенный LM358, ведь высоких требований к быстродействию ОУ здесь нет, но на этапе тестирования выяснилось, что у него прослеживается ощутимая зависимость выходного напряжения каналов друг от друга, а также от температуры. Поэтому ОУ был сменен на TL082C, где эта зависимость ниже.

Отдельно следует рассмотреть питание ОУ. Начало шкалы измерений АЦП МК лежит ровно в нуле вольт, поэтому ОУ должны иметь возможность выдавать такое напряжение на своих выходах. Казалось бы, можно просто взять R2R ОУ, но даже они не в состоянии выдать ровно ноль вольт, их минимум начинается где-то от 25 мВ и сильно зависит от нагрузки. А 25 мВ – это примерно 21 единица шкалы АЦП или 2%, и это слишком большая погрешность при измерении тока. Поэтому необходим дополнительный источник отрицательного напряжения для питания ОУ.

Чтобы не ставить еще один преобразователь, было решено получить отрицательное напряжение с помощью диодного-ёмкостного умножителя на C22, D9, D10 и C24, подключенного к выходу понижающего преобразователя U5 через ограничительный резистор R40. При нормальной работе преобразователя под нагрузкой на его выходе присутствует меандр амплитудой 24 В, который «отражается» умножителем, и конденсатор C24 заряжается напряжением порядка -22 В. Это напряжение уменьшается до -4.7 В стабилитроном D11 и используется для питания ОУ. Для преобразователя умножитель выполняет роль снаббера, уменьшая выбросы на его выходе, но и немного увеличивая нагрев.

Поскольку напряжение на выходах ОУ теперь может оказаться отрицательным, необходимо защитить от него МК. Эту роль выполняют резисторы R11 и R20, которые совместно с конденсаторами C4 и C9 также образуют ФНЧ, дополнительно фильтрующие высокочастотные помехи.

Еще одним нюансом схемы является резистор R44. Его задача – сдвинуть точку нуля токовой шкалы в область положительных напряжений. Дело в том, что за счет неидеальности ОУ и других элементов схемы, на входе АЦП МК оказывается небольшое (несколько милливольт) отрицательное напряжение смещения, которое препятствует измерению малых значений выходного тока. Да, это смещение можно скорректировать программно, чтобы получить правильные измерения на больших токах, но измерять малые токи всё равно не получится. Поэтому требуется аппаратная корректировка. Сопротивление R44 подбирается так, чтобы при отсутствии выходного тока напряжение на входе АЦП МК было чуть больше нуля, у меня это достигается на значении 620 КОм. Если вдруг корректировка окажется несколько чрезмерной, ничего страшного – отклонение в положительную сторону отлично корректируется программно.

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

В остальной части схемы нет ничего интересного. Выход канала B таймера 0 генерирует сигнал PWM
с той же частотой 62.5 КГц, используемый для управления вентилятором обдува. Этот сигнал преобразуется в напряжение элементами Q2, L1, D4, C5. В контроле результирующего напряжения необходимости нет, требуемые значения PWM всё равно подбираются экспериментально под используемую модель вентилятора.

16-разрядный таймер 1 МК используется для генерации звуковых сигналов. Его выход А управляет транзистором Q4, который подает напряжение на пьезокерамический излучатель PZ1. Использование резисторов R21 и R47 достаточно больших номиналов совместно с ёмкостью излучателя образует ФНЧ, что позволяет изменять громкость звучания с помощью длины импульсов, а для её общего повышения излучатель питается от 24 В.

На ОУ U4.1 реализован датчик снижения напряжения питания. ОУ работает в режиме компаратора с небольшим гистерезисом, обеспечиваемым положительной обратной связью через резистор R49. Пороговое напряжение срабатывания датчика – порядка 23.5 В, напряжение восстановления – около 23.7 В. U4.2 используется для анализа напряжения на 4-м контакте желтого разъема Макиты, снижение которого ниже примерно 1.3 В (установлено опытным путем) сигнализирует о проблемах со стороны батареи и необходимости остановить зарядку. К сожалению, установка желтого разъема в зарядку произошла уже на этапе отладки, когда основная плата была полностью готова, поэтому необходимые дополнительные детали разместились на отдельной небольшой плате.


На всех входах ОУ, подключенных к внешним контактам зарядного устройства применяется защита от статического напряжения на диодах D3, D5, D6 и D7.

Для измерения температуры я использовал цифровые датчики TMP100A, которые уже успешно применял в своих предыдущих проектах. Это небольшая 6-выводная микросхема в корпусе SOT23-6, позволяющая измерять собственную температуру с разрешением 0.06 градуса и общающаяся с МК по протоколу I²C, за счет чего на один интерфейс можно подключить до 8 таких датчиков.


В зарядном устройстве я использовал два – один для измерения температуры радиатора платы и другой для косвенного измерения температуры батареи. Датчики располагаются на отдельных платах и подключаются к основной плате через разъем J13.

Я намеренно оставил выводы TxD и RxD МК свободными, т.к. на этапе проектирования предполагал возможное подключение зарядного устройства к ПК по последовательному порту. Однако, по мере написания прошивки контроллера стало очевидно, что такое подключение не нужно, поэтому в финальном варианте эти выводы просто не задействуются.

Плата


Печатные платы делать не люблю, с удовольствием заказывал бы готовые, если бы их могли делать быстро. Иначе может получиться, что пока плату будут изготавливать, интерес к устройству пройдет и проект будет заброшен, поэтому приходится делать самому. В основном, использую две технологии изготовления – фоторезист и ЛУТ. Фоторезист дает значительно более высокое качество, чем ЛУТ, но и требует больше усилий, поэтому делаю этим способом большие и важные платы, а для маленьких сейчас использую ЛУТ. Изготовление качественных двухсторонних плат тоже не освоил, стараюсь разводить всё в одном слое с перемычками. Если есть возможность, предпочитаю использовать старые through-hole/DIP компоненты, потому что надо их куда-то тратить, да и разводить односторонние платы для них проще.

Основная плата зарядки получилась размерами 130х60 мм и, надо сказать, это уже предел для моего принтера. Несмотря на то, что срок годности фоторезиста Ordyl истек еще в 2017 году, плата вышла отличная, лишь немного пришлось уменьшить время экспозиции (до 60 секунд):


На фото вытравленная плата представлена в первоначальном варианте, а нарисованная – в обновленном. В процессе сборки и наладки схема претерпела небольшие изменения, рисунок платы менялся. Свою же переделывать не стал, просто удалял существующие дорожки и «креативил» новые перемычками из проволоки. Также пропаял все силовые цепи медной проволокой диаметром чуть меньше 1 мм, чтобы снизить их нагрев на максимальном токе. Для пайки использовал свой основной паяльник Т12, TS101 как-то не «зашел». Почти всю плату спаял жалом ВС2 на 285-ти градусах, кроме «тяжелых» мест, где применял ВС3. Фото собранной платы с нижней стороны не сделал – из-за доработок там получилось всё несколько страшненько, а фотографии со стороны деталей будут дальше.

Для датчиков температуры TMP100 сделал отдельные небольшие платы, позволяющие закреплять их винтами М3, прижимая микросхему корпусом к измеряемому элементу. Один датчик разместил на радиаторе ключа и диода, второй – на минусовом контакте батареи, так с ней будет хоть какая-то тепловая связь. Платы делал ЛУТом, из-за чего их качество существенно ниже основной. Вот так они выглядят вблизи:


То ли я что-то неправильно делаю, то ли мой принтер не подходит для ЛУТ, но тонер не обеспечивает равномерной защиты медного слоя, и он подтравливается. Собранная плата выглядит следующим образом:


Кроме самого датчика на ней установлен конденсатор по питанию, провода шины I²C и две перемычки, определяющие адрес датчика на шине. Все части платы, кроме самой микросхемы, защищены от электрического контакта с измеряемой деталью с помощью каптонового скотча.

Блок питания


В качестве блока питания был выбран недавно обозревавшийся тут Suswe U-shaped 24 В 10 А (фотография со страницы товара):


Блок питания не самый дешевый (в начале осени заказывал за 2155 рублей с доставкой), но это LLC, он имеет хороший запас по току и активный PFC – пора и в самодельных устройствах переходить на новый уровень. В принципе, нареканий на него нет, но есть пара нюансов. Во-первых, плата снизу чуть грязновата:


Во-вторых, изначально в блоке была плохо согнута Г-образная пластина, на которую устанавливаются высоковольтные транзисторы, из-за чего их выводы оказались на расстоянии меньше 1 мм от указанной пластины! Для 400 В это слишком мало, попадет немного пыли, повысится влажность и будет пробой. А это замена деталей, обугливание платы, в общем, ничего хорошего.

Когда стал разбирать блок, чтобы подогнуть пластину, тактильно обнаружил, что высоковольтный конденсатор более 10 минут сохраняет заряд! Все дело в том, что для достижения минимального тока ХХ в этом блоке на конденсаторе нет разрядных резисторов, а контроллер блокируется UVLO, из-за чего высокое напряжение в первичной цепи сохраняется достаточно долгое время. Так делать нельзя, поэтому добавил разрядный резистор самостоятельно:


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

Программа МК


Написание программы для МК в таком проекте – не самый сложный, но наиболее трудозатратный этап. Уже сейчас исходные коды программы занимают практически 200 КБ, а это еще даже не все желаемые функции реализованы, некоторые еще только предстоит запрограммировать.

Обычно для AVR я использую IDE от производителя – Microchip Studio. Но это затрудняет повторение проекта, ведь ПО специфическое, оно есть далеко не у всех. Поэтому в этот раз решил целиком реализовать проект на PlatformIO, open source плагине для MS Visual Studio Code, позволяющим писать программы под разные МК с использованием разных фреймворков. Среди них, кстати, есть и Ардуино, но, когда речь идет о быстром и качественном ПО для AVR, к сожалению, Ардуино нам не помощник. Поэтому проект будет написан «с нуля» без использования фреймворков. Не буду подробно описывать моменты создания и настройки проекта, перейду сразу к описанию программного решения.

Основная функция устройства – зарядка аккумуляторов или управляемый понижающий DC-DC преобразователь с контролем выходного напряжения и тока. Для повышения КПД сейчас большинство таких преобразователей используют PWM, то есть, работают за счет изменения продолжительности управляющих импульсов. Описываемая зарядка не является исключением, сигнал PWM формируется МК аппаратно с помощью канала А таймера 0. Таймер 8-разрядный, работает от тактовой частоты МК, равной 16 МГц, что дает результирующую частоту PWM 62.5 КГц – не очень много по современным меркам, но вполне достаточно. Для поддержания выходного напряжения и тока на заданном уровне, их значения измеряются с помощью встроенного в МК 10-разрядного АЦП и подаются на вход ПИД-регулятора, который управляет шириной генерируемых импульсов. Так петля управления замыкается.

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

Основная часть кода написана на языке С/С++, однако, так как речь идет о достаточно слабом по современным меркам МК AVR, не обошлось и без ассемблера, и некоторые функции написаны на нём. Здесь хочу отдельно отметить, что программирование на ассемблере под AVR мне очень нравится, так как позволяет раскрыть полный потенциал этих МК. Система команд достаточно простая, есть четкие тайминги их выполнения, а разработчику доступно много регистров общего назначения. Всё это позволяет писать компактные, быстрые и эффективные куски ассемблерного кода.

Отдельно отмечу интересную особенность gcc, используемого для компиляции исходного кода в PlatformIO – ассемблерные файлы здесь имеют расширение (*.s). Причем, если вы укажете расширение с маленькой буквой (*.s), для компилятора это будет чистый ассемблерный файл, поддерживающий только синтаксис ассемблера. Если же указать расширение с большой буквы (*.S), это уже будет ассемблерный файл с поддержкой некоторых директив компилятора С, таких как, например, #define. Это позволяет подключать заголовочные файлы С/С++ с определениями различных констант МК непосредственно в ассемблерный код, чтобы избежать указания их числовых значений напрямую. По этой причине все ассемблерные файлы проекта имеют расширение *.S.

Timer 0, АЦП и ПИД

В документации меги сказано, что при максимальном разрешении АЦП хорошо работает на тактовой частоте от 50 до 200 КГц, а каждое преобразование занимает 13 тактов, что дает только 15 тысяч преобразований в секунду. На практике же можно поднять эту частоту до 1 МГц, и АЦП всё еще будет неплохо работать, что даст уже до 77 тысяч преобразований в секунду. Тогда преобразование займет 13*16 = 208 тактов МК, то есть, даже меньше интервала между соседними импульсами PWM, который составляет 256 тактов. Это позволяет запускать новое преобразование АЦП прямо в коде обработчика прерывания таймера, то есть, синхронизировать процесс измерения с частотой PWM, что должно положительно сказаться на точности измерений.

Разрядность АЦП – всего 10 бит. При максимальном напряжении 24 В, разрешение измерений составляет 23 мВ, то есть, не позволяет устройству оперировать даже сотыми долями вольта. Поэтому я решил суммировать 4 последовательных измерения, чтобы повысить итоговое разрешение до 6 мВ. В реальности, конечно, это не означает, что я могу получать точный 12-битный результат каждые 4 измерения, но на длинной дистанции это работает. Ток будет измеряться с разрешением 3 мА, что тоже приемлемо, а измерения тока и напряжения будут происходить попеременно, чтобы получить максимально релевантный результат.

В итоге, я получаю новые 12-битные значения тока и напряжения через каждые 8 прерываний таймера или 7812.5 раз в секунду. И каждый раз, получив эти значения, запускается алгоритм ПИД и корректирует ширину импульсов PWM. Это позволяет получить приемлемое для зарядного устройства время отклика регулирующей цепи.

Сам алгоритм ПИД, примененный в зарядке – упрощенный. По сути, он является ПИ-алгоритмом, так как не использует дифференциальную составляющую, потому что в моих предварительных экспериментах от неё было больше помех, чем пользы. Также ПИ-коэффициенты не вынесены в настройки, а жестко заданы в коде и являются степенями двойки, чтобы упростить вычисления слабенькому 8-разрядному МК. Но это сильно не сказывается на качестве работы алгоритма, ведь на выходе стабилизатора установлены конденсаторы суммарной ёмкостью 940 мкФ, а чтобы зарядить или разрядить такую емкость нужно время.

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


Затем ПИД-алгоритм обновляет значение интегратора и высчитывает новый коэффициент PWM. Первоначально я сделал его 8-разрядным, так как именно такая разрядность у таймера меги. Однако, эксперименты показали, что в этом случае выходное напряжение имеет слишком большую амплитуду хаотичных пульсаций – до 200 мВ, причем эта амплитуда меняется в зависимости от того, какое именно постоянное напряжение сейчас создается на выходе стабилизатора. Очевидно, что 8 разрядов для управления PWM не хватает, ведь это всего лишь 256 возможных градаций, что дает мгновенное разрешение стабилизатора около 100 мВ.

Тогда был введен программный dithering — размер коэффициента PWM был увеличен до 16 бит, из которых старшие 8 идут непосредственно в регистр таймера, а младшие 8 суммируются в дополнительной 8-разрядной переменной. Если после выполнения очередной операции сложения возникает переполнение и устанавливается флаг переноса С, то значение коэффициента PWM в регистре таймера увеличивается на 1 для следующего импульса. Так как коэффициент PWM обновляется один раз за 8 прерываний таймера, такое решение фактически добавляет 3 дополнительных бита к разрешению, поэтому после его внедрения хаотичные пульсации значительно снизились.

Еще один нюанс управления PWM заключается в том, что мега ни при каком значении регистра OCR0A таймера не позволяет получить на выходе абсолютный логический ноль. То есть, полностью выключить PWM лишь изменением его коэффициента невозможно, даже при значении 0 в сигнале остаются короткие иголки длительностью 62.5 нс. Поэтому приходится полностью отключать генерацию выходного сигнала таймера с помощью регистра управления TCCR0A в моменты, когда преобразователь нужно выключить.


Но еще более интересная особенность была найдена значительно позже, когда устройство уже было полностью собрано и смонтировано в корпус. Оказывается, из-за того, что момент старта измерения АЦП полностью синхронизирован с частотой PWM, если плавно увеличивать коэффициент PWM, есть такой диапазон его значений, когда генерируемая в момент закрытия ключа помеха попадает на момент сэмплирования входного сигнала преобразователем и результат измерения искажается! Искажается не очень сильно (где-то на 20 единиц АЦП или на 2%), но внешне это проявляется как наличие у стабилизатора участка с отрицательной передаточной характеристикой, где увеличение коэффициента PWM приводит к уменьшению выходного напряжения. Поскольку проявлялась эта особенность при выходном напряжении около 6.8 В, то есть, вне рабочего диапазона зарядки, можно было бы просто закрыть на это глаза. Но я люблю ночью спать спокойно, а не мучаться в кошмарах, поэтому решил недостаток устранить.

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

Следующим вариантом была попытка перевода АЦП в режим автоматических измерений и, таким образом, отвязки момента старта измерения от частоты PWM. Это тоже помогло, участок с отрицательной передаточной характеристикой исчез, однако, выводимые на экран измеренные значения начали хаотично прыгать в десятых долях. Логично, ведь теперь помеха попадала на момент измерения периодически, а не только в узком диапазоне коэффициентов PWM. То есть, изначальное решение синхронизации АЦП и PWM было правильным.

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

Очевидно, что сдвигать измерение надо не менее, чем на 1 такт АЦП или на 16 тактов МК. Но слишком далеко переносить тоже нельзя, ведь само измерение занимает 208 тактов, а через 256 тактов придет новое прерывание и, если начать измерение слишком поздно, результат не будет готов к следующему прерыванию. Посчитал команды, оказалось, в обычной ситуации я запускаю измерение через 43 такта от начала обработчика, поэтому решил переносить «назад», то есть, на более раннее время. Написал дополнительную ветку кода, обсчитал её – 26 тактов, то есть, на 17 тактов раньше. Отлично, это ровно то, что нужно! Дальше подобрал оптимальное значение порогового коэффициента, и проблема действительно ушла – участок с отрицательной характеристикой исчез, а показания остались стабильными, как и прежде. Это была маленькая победа.

В коде, кроме дополнительной ветки добавились всего две строчки:


Измерения

Дальше надо подумать об отображении измеренных значениях напряжения и тока. Если для ПИД хорошо, что он вызывается достаточно большое число раз в секунду, то для отображения такая частота не нужна. А вот усреднение показаний, чтобы они меньше прыгали – было бы очень желательно. Поэтому решил вычислять среднее из 256 последних измерений напряжения и тока, это даст частоту обновления 30.5 Гц, чего более, чем достаточно для отображения.

Теперь, когда есть пригодные для отображения результаты измерений, надо их, собственно, отобразить. Вряд ли кому-либо будет интересно видеть «голые» значения, считанные из АЦП, они неинформативны. Для отображения их надо преобразовать в удобочитаемые числа, отражающие привычные нам вольты и амперы. АЦП – штука линейная, поэтому преобразование будет тоже линейным, для чего достаточно двух калибровочных коэффициентов – смещения и множителя. То есть:

Vdisp = (Vadc + Vofs)*Vk
Idisp = (Iadc + Iofs)*Ik

Числа с плавающей точкой для AVR – это как обычному человеку пробежать марафон: может и реально, но лучше не надо, поэтому я использую только целочисленную арифметику. Напряжение и ток должны отображаться с двумя знаками после запятой, то есть максимальные значения составят 2400 и 999. В 8 бит такие числа не помещаются, поэтому придется использовать 16. А если уж использовать 16 бит, то можно и пределы увеличить в 10 раз, до 24000 и 9999, соответственно. Это положительно скажется на точности, да и значения будут в понятных единицах – в милливольтах и миллиамперах.

Максимальное значение, считываемое из АЦП равно 1023*4 = 4092, поэтому перепишем формулу следующим образом:

VdispX1000 = ((Vadc + Vofs)*Vk)/4096
IdispX1000 = ((Iadc + Iofs)*Ik)/4096

Тогда Vofs и Iofs будут корректирующими коэффициентами, позволяющими выставить правильное начальное смещение измерений, а Vk и Ik – множители тока и напряжения, численно равные максимально возможному измеренным величинам (то есть, примерно 24500 и 12200). Код преобразования измерений не будет выполняться часто, быстродействие тут не нужно, поэтому пишу его на си:


Но, к сожалению, без ассемблера и тут не обошлось – в алгоритме требуется деление на 4096 или сдвиг вправо на 12 разрядов. Я бы мог еще понять, если gcc не умеет эффективно сдвигать на 4 разряда, но на 8-то сдвиг делается простым присвоением регистров! Но нет, gcc всё это уложил в цикл из 12 итераций, из-за чего его код выполняется 84 такта. Да, с точки зрения работы программы это мелочь, такие преобразования вызываются считанные разы в секунду, но я люблю оптимальные программы, поэтому переписал эти две функции на ассемблере:


Не считая времени на вызов и возврат, такой сдвиг выполняется всего 9 тактов, то есть, в 9 раз быстрее gcc.

Следующей интересной задачей оказался подсчет отданной в аккумулятор ёмкости. Хоть это значение во многих случаях и не очень полезно, без него зарядное устройство теряет всю свою привлекательность – человеку обязательно нужно видеть увеличивающееся число. Это завораживает, это как смотреть на горящий огонь или печатающий 3Д-принтер, это индикатор прогресса, индикатор жизни, и только так человек понимает, что зарядка работает. Поэтому делать обязательно надо. Но как?

Опуская все этапы размышлений, подробно описанные в комментариях в файле timer_int.S, скажу, что, на самом деле, это достаточно просто. У меня есть измерения выходного тока, выполняемые с некоторой периодичностью. Если численно умножить каждое такое измерение на интервал времени между соседними измерениями, мы и получим ёмкость, отданную за этот интервал. А если сложить несколько таких измерений за некоторый промежуток и снова умножить – получим ёмкость, отданную за этот промежуток. То есть, всё, что надо делать – это просто складывать значение тока после каждого измерения, а непосредственно перед выводом пользователю умножать эту сумму на определенный коэффициент.

Подсчеты показали, если я хочу иметь возможность считать до 100 Ач, для сложения измерений без потери точности нужна переменная размером 44 бита. Или 6 байт. Это много для AVR, но, к счастью, все эти 48 бит не нужны для отображения результата – ведь достаточно трех цифр после запятой. В итоге, после расчета всех коэффициентов у меня получился вот такой простой код:


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

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

Графика

Для проекта я выбрал 16-битный IPS дисплей разрешением 240х240 точек, управляемый контроллером ST7789. Почему именно такой – прежде всего потому, что он у меня был. Чтобы быстрее подключить дисплей и начать с ним работать, я обратился к помощи Ардуино – там есть много готового кода для различных устройств, в который можно подглядывать в процессе работы над своими проектами. К сожалению, брать его в неизменном виде зачастую нельзя, т.к. написан он, мягко говоря, не очень.

Для данного дисплея в Ардуино есть отдельная библиотека, которая называется Adafruit_ST7735_and_ST7789_Library. Скачиваем её и начинаем разбираться, параллельно подглядывая в даташит на сам контроллер. И первые вопросы возникают тут же – дисплей подключается к МК по протоколу SPI, и в Ардуино SPI инициализируется в режим 2 (выдача очередного бита данных по переднему фронту тактового сигнала), в то время как даташит показывает, что нам нужен режим 3 (выдача данных по заднему фронту). Как такое может быть, и почему код Ардуино работает у множества людей?

Провел тест, и он показал, что дисплею действительно нужен режим 3, хотя он работает и в режиме 2, только менее стабильно – помните, для согласования уровней сигналов МК и дисплея я использовал простые резисторы? Я начал постепенно увеличивать их сопротивления, уменьшая таким образом временные характеристики соединения, и в режиме 2 дисплей начал давать сбои, в то время как в режиме 3 продолжал еще работать нормально. Почему же дисплей вообще работает в режиме 2? Оказывается, если внимательно посмотреть осциллограммы сигналов на шинах SPI, можно заметить, что тактовый сигнал запаздывает относительно сигнала данных на несколько наносекунд. Дисплей достаточно быстрый, и вот это небольшое, практически незаметное «цифровому глазу» запаздывание позволяет ему правильно принимать данные во втором режиме SPI. Интересно, Atmel сделали это намеренно?

В итоге, мой код инициализации дисплея получился сильно меньше того, что в Ардуино:


Ну, а дальше началось самое интересное. Чтобы обновить изображение на дисплее целиком, ему нужно передать 240*240*2 = 115200 байт = 921600 бит в 16-битном режиме цветности. Это весьма много для скромной меги, SPI которой может работать максимум на 8 МГц. И режима 8-битной цветности, которого бы вполне хватило для моей задачи у дисплея тоже нет (есть режим 12 бит, но он совершенно неудобен). В принципе, тут можно честно сказать, что этот дисплей «великоват» для меги. Но МК уже выбран, часть кода написана и другого дисплея под рукой нет, так что продолжаем продолжать.

Основное, что надо выводить на дисплей в зарядном устройстве – это текст. Значит, снова идем в наш любимый Ардуино, чтобы подсмотреть вывод текста там (Adafruit_GFX_Library). Но то, что я увидел просто повергло меня в ужас. Вывод текста там реализован двумя вложенными циклами, внутри которых для каждого закрашенного пикселя шрифта вызывается отдельная функция drawPixel, которая выбирает на дисплее новое «окно» размером один пиксель, после чего заполняет его нужным цветом. Мало того, что это крайне медленно, так еще и не позволяет перетирать одну строчку текста другой – ведь на дисплей передаются только закрашенные пиксели и текст от двух строчек просто наложится. Сами авторы библиотеки об этом знают, но считают, что реализовать по-другому просто невозможно:


Моргание измеряемых значений на экране неприемлемо, таким устройством будет невозможно пользоваться, надо делать что-то свое. Подумав, я решил взять из библиотеки Ардуино само графическое изображение открытого шрифта Open Sans (чтобы не изобретать велосипед), а весь код его вывода написать с нуля и на ассемблере, так как очевидно, что на Си он будет недостаточно быстрым.

Эксперименты с SPI показали, что помещать в регистр SPDR данные можно не чаще, чем один раз в 18 тактов, иначе передача сбивается. Это дает максимальную пропускную способность в 889 КБ/сек или 7.7 FPS на выбранном дисплее. Немного, но для зарядного устройства вполне хватит – большинство мультиметров производят всего 3 измерения в секунду и это всех устраивает, значит, здесь тоже можно ориентироваться на такую частоту. В общем, требуется написать такой код вывода символа, который будет выводить изображение вместе с заднем фоном и подавать очередной байт в регистр SPDR ровно через 18 тактов.

Ситуацию несколько усложняет формат, в котором хранится шрифт в Ардуино – для уменьшения места, занимаемого в памяти, от каждого символа хранится только центральный прямоугольник, где имеются закрашенные пиксели, и он для каждого символа свой. То есть, код вывода должен будет рисовать вокруг символа рамочку цветом заднего фона, рисовать сам символ и, что самое главное, делать это в реальном времени, подавая очередной байт в SPDR ровно через 18 тактов!

%symb%

И такой код был написан, это функция PrintGlyph в файле display_asm.S. Она устанавливает окно в контроллере дисплея по внешнему размеру символа, после чего попиксельно выводит символ в рамке слева-направо сверху-вниз. За счет того, что символ выводится с закрашенным задним фоном, становится возможно замещать на экране одну строку текста другой без моргания. А учитывая, что ширина всех цифр в шрифте Open Sans одинаковая, это позволяет красиво обновлять любые цифровые значения. Именно то, что было нужно.

Дальше я написал функцию FillRect, которая закрашивает указанный прямоугольник указанным цветом. С помощью этой же функции можно рисовать вертикальные и горизонтальные линии, если задать ширину или высоту прямоугольника достаточно малой. Функция спроектирована точно таким же образом, чтобы подавать очередной байт в регистр SPDR ровно через 18 тактов. Только здесь это сделать было значительно проще.

Поскольку для несложных графических интерфейсов данных двух функций вполне достаточно, решил ими и ограничиться. Конечно, можно было бы еще написать код вывода небольших спрайтов, однако, ПЗУ такого простого контроллера как ATMega328 банально на них не хватит – ведь даже небольшая иконка 32х32 пикселя будет занимать целых 2 КБ или 1/16 от всего объема ПЗУ! Так что интерфейс будет без иконок.

Считывание энкодера

Более продвинутые контроллеры вроде STM32 умеют работать с энкодером аппаратно, в меге же приходится все делать руками. Однако, ничего сложного в этом нет – за поворот энкодера отвечают два сигнала: DATA и CLOCK. Если опустить все подробности внутреннего устройства, то можно сказать, что мы отлавливаем, например, передний фронт сигнала CLOCK и в этот момент анализируем уровень сигнала DATA, который и определяет, в какую сторону был повернут энкодер. Это несколько упрощенный, однако, вполне рабочий алгоритм. Его можно реализовать с использованием прерываний PCINT, но у меня уже «прижился» код, который периодически считывает уровни сигналов и формирует соответствующие команды для основной программы.


Этот код запускается каждое 8-е прерывание таймера, то есть, с частотой 7 812,5 Гц, что позволяет отлавливать примерно до двух тысяч тиков энкодера в секунду, чего более чем достаточно для любого применения. А вот анализ нажатия кнопки энкодера производится уже в обработчике таймера на С++, который вызывается 100 раз в секунду:


Программа различает три вида нажатия на кнопку – короткое (обычное), долгое (более 1 секунды) и сервисное (6 секунд). Короткое и долгое обрабатываются в соответствии с алгоритмом текущей функции, а вот сервисное вызывает безусловный перезапуск кода микроконтроллера. Сделано это на случай потенциального логического зависания кода прошивки или других ошибок программы, однако, пока что ни разу по назначению не использовалось.

TWI

Для считывания температуры с датчиков TMP100 программа должна поддерживать протокол TWI. К счастью, базовые функции его поддержки присутствуют в меге аппаратно, поэтому понадобилось лишь обернуть их небольшой интерфейсной оберткой. Поскольку TWI использует прерывания, также написал основную часть кода на ассемблере. Из особенностей тут можно отметить только лишь запрещение прерываний TWI при старте обработчика и последующее разрешение прерываний контроллера – так сделано для того, чтобы минимизировать временное отклонение (или джиттер) вызова основного прерывания таймера. Если вдруг прерывание таймера придет во время обработки прерывания TWI, оно прервет его. Конечно, в более сложных микроконтроллерах приоритет прерываний можно задавать, но здесь пользуемся тем, что есть.


Общий подход работы с TWI в зарядке – асинхронный, обмен данными с датчиками инициируется в коде прерывания таймера на С++, а его результат анализируется в момент обработки следующего прерывания. Также на последнем шаге осуществляется коррекция скорости вращения вентилятора обдува.


1-wire

Для зарядки совместимых батарей Макита с желтым разъемом в программу была добавлена поддержка протокола 1-wire, который используется для обмена данными между зарядкой и батареей. Если в двух словах, то поддержка полностью программная, состоит из двух частей – примитивного ассемблерного кода, который выполняется каждое прерывание основного таймера и кода на С++, который управляет работой ассемблерного. Более подробно этот протокол и его реализация были рассмотрена в предыдущем обзоре, повторять их необходимости нет, так как никаких обновлений в код за это время внесено не было.

Генерация звука

Вы же знаете, что оригинальная зарядка Makita DC18RC умеет играть небольшие мелодии? Если не знали, то быстрая установка и снятие аккумулятора с зарядки (до 5 секунд) изменяет текущую мелодию, можете поэкспериментировать. А раз оригинальная зарядка умеет, надо и самодельную научить, ведь ничего сложного в этом, на самом деле, нет.

Для генерации звуковых сигналов используется 16-разрядный Timer 1, работающий в режиме Phase Correct PWM. Максимальное значение счетчика и, соответственно, частота выходного сигнала задается регистром ICR1, что при входной частоте 2 МГц позволяет получить на выходе практически любой звуковой тон. А значение регистра OCR1A задает ширину импульса, которая определяет громкость воспроизводимого сигнала. Осталось прикрутить какой-либо «плеер» музыки, и дело в шляпе.

Музыкой профессионально я никогда не занимался, но в институте увлекался разными трекерами (типа Fast Tracker, Impulse Tracker, Open ModPlug Tracker и т.д.), пытался подбирать мелодии, редактировать и даже писать что-то свое. Поэтому базовое понимание основ имеется, для такой простой задачи, как управление одноголосым синтезатором таких знаний вполне хватит. Постараюсь кратко их изложить.

Итак, мелодия состоит из нот, каждая из которых однозначно определяет основную частоту генерируемого звукового сигнала. Всего разных нот – двенадцать, дальше они начинают повторяться, но уже в соседней октаве. Соседние октавы отличаются друг от друга по частоте ровно в два раза, а ноты распределены по каждой октаве равномерно, если смотреть на логарифмической шкале. То есть, соседние ноты отличаются друг от друга в корень двенадцатой степени из двух или в 1,0595 раза. Это так называемый равномерный строй, который сейчас повсеместно используется. Добавляя к этой зависимости отправную точку – ноту Ля 4-й октавы (обозначается А4), частота которой составляет 440 Гц, можно вычислить весь звуковой ряд. Кстати, для этого я написал отдельный скрипт на языке Perl — sound.pl.

Традиционно считается, что для практического большинства мелодий достаточно 88 разных нот, звучащих в диапазоне от 27.5 Гц до 4186 Гц, поэтому на классическом фортепиано 88 клавиш. Более низкие частоты человек попросту не слышит, а более высокие – не различает, поэтому при построении мелодий нет смысла их использовать. То есть, с точки зрения информации для хранения ноты достаточно 6.5 бит. Самым простым решением было бы использовать для этого отдельный байт, тогда с его значением не надо проводить никаких манипуляций. Но ведь в мелодии у нот кроме тона есть еще и продолжительность, которую тоже надо хранить. То есть, получается, для одной ноты надо уже два байта.

Казалось бы, какая мелочь в наше-то время эти два байта на ноту. Однако, микроконтроллер у нас «плюшевый», и памяти у него всего 32 КБ, так что попробуем уложиться в один байт. Для этого, прежде всего, ограничим количество разных нот – их будет только 32, от Ми 4-й октавы (Е4) до Си 6-й октавы (В6). Такого количества нот вполне хватит для воспроизведения основной партии практически любой популярной мелодии, а другие в зарядке и не нужны. Зато нота теперь будет занимать 5 бит, позволяя использовать три оставшихся для указания её длительности, что дает 8 различных вариантов. Точнее, их будет 7, потому что 8-й со значением 0 будет использоваться для указания дополнительных действий, таких как окончания мелодии, продления звучания текущей ноты (если она длиннее 7-ми тактов) и паузы.

Что касается длительности нот – она измеряется в тактах, продолжительность которых зависит от темпа мелодии. Темп задается в традиционных для музыки единицах, BPM (Beats Per Minute) – количестве ударов в минуту. При этом, для размера 4/4 (наиболее популярный музыкальный размер) один удар состоит из четырех тактов. Таким образом, если взять темп 125 ВРМ 4/4, на одну секунду будет приходиться 2.083 удара или 8.333 тактов. То есть, продолжительность одного такта составит ровно 120 миллисекунд. Поскольку у меня в коде есть таймер, выполняющийся с частотой 100 Гц, удобно повесить музыкальный плеер на него. В данном случае новый такт будет наступать через 12 вызовов таймера.

Просуммировав всё сказанное выше, был написан код музыкального плеера, уместившегося в 35 строчек:


А для упрощения задания нот в исходном коде были написаны небольшие макросы, с использованием которых закодированная мелодия выглядит следующим образом:


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

Интерфейс пользователя


Поскольку в зарядке используется цветной графический дисплей, обойтись простым накидыванием на экран показаний тока и напряжения не выйдет, необходимо проработать полноценный графический интерфейс. Это удобно делать на ПК в хорошем графическом редакторе, например, в фотошопе. А чтобы нарисованный интерфейс потом было несложно перенести в код МК, при рисовании следует использовать только те графические примитивы, которые умеет рисовать МК. То есть, в моем случае это строки текста размером 12 и 18 пунктов, линии и закрашенные прямоугольники. Что касается цветов, то так как экран 16-битный, можно использовать всю палитру RGB.

Поскольку я взял шрифты из библиотеки Арудино, первым делом следует подобрать аналогичный размер шрифтов на ПК. Точнее, я буду подбирать разрешение картинки, чтобы требуемый размер шрифта в пунктах в фотошопе соответствовал символам точно такого же или близкого размера как в библиотеке. И таким значением оказалось 140 пикселей на дюйм. По мне, весьма странное разрешение, т.к. не соответствует никаким стандартным, но и каких-либо сложностей это тоже не вызовет.

Итак, определившись с разрешением, можно начать рисовать интерфейс. Первым экраном, который я сделал был экран режима лабораторного источника питания:


В принципе, экран получится достаточно простой и, в то же время, информативный. В верхней строке выводится текущий режим работы – Power Supply. В центральной части слева выводятся мгновенные значения напряжения, тока и мощности, а справа расположены индикаторы текущего режима работы – CV или CC и индикатор включения выхода OUT. Ниже более мелким шрифтом отображается счетчик отданной ёмкости и время работы в режиме блока питания. На следующей строчке отображается температура зарядного устройства с префиксом С (Charger), температура батареи с префиксом В (Battery) и текущая скорость работы вентилятора в процентах от максимальной. В самой нижней строке отображаются заданные значения напряжения и тока, тут же и происходит их изменение.

Следующим был нарисован экран режима зарядки аккумуляторов:


Экран имеет пять различных вариантов отображения. В каждом из них в верхней строке отображается текущий режим работы – Charger. В центральной части слева отображается выбранный режим зарядки (CC/CV или ССС) и выбранный зарядный ток. Чуть позже я добавил туда третью строчку с отображением включенных опций зарядки, но в макеты изменения вносить уже не стал. В предпоследней строке отображается текущая температура зарядного устройства и время зарядки аккумулятора, а в самой нижней строке отображается выбранный профиль зарядки.

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

Второй вариант (Invalid battery) отображается в случае вставки в зарядное устройство не той батареи, которая ожидается для выбранного профиля зарядки. Контроль типа батареи осуществляется по её напряжению, которое в данном варианте отображается в нижней части экрана оранжевым цветом.

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

Четвертый вариант (Charge complete) отображается по завершению зарядки батареи до тех пор, пока она не будет отключена от зарядного устройства. Здесь в центре экрана более крупным шрифтом выводится итоговая отданная зарядным устройством ёмкость.

И, наконец, последний экран (Battery error) отображается в случае возникновения в процессе зарядки каких-либо проблем со стороны батареи. Такими проблемами могут быть или снижение напряжения статусного контакта батареи (для Makita-совместимых батарей), или её перегрев. В этом варианте в центральной части экрана отображается текущее напряжение и температура батареи, а также, если идет зарядка Makita-совместимой батареи, состояние 4-го контакта интерфейсного разъема строкой FAIL или OK. Я решил, что выход из критической ситуации должен быть обязательно ручным, поэтому дополнительно на экране отображается пункт Continue, позволяющий продолжить зарядку.


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

Остальные экраны особого интереса не представляют, поэтому просто приведу их макеты без детального пояснения. Надеюсь, тут и так всё понятно:


Корпус


Теперь, когда схема отлажена и работает, а программная часть, по большей части, написана, настает время придать устройству законченный вид, поместив его в корпус. Но какой корпус использовать? Сначала я думал скачать из интернета готовый сокет LXT и просто прикрутить его к коробке подходящих размеров, но так и не смог найти такого варианта сокета, который бы мне понравился. Параллельно я размышлял, где буду хранить готовую зарядку, и все сошлось к тому, что надо в некоторой степени повторить корпус DC18SD/RC. Тогда и внешний вид будет красивым, и хранить её можно будет в кейсе MacPac 2 вместе с шуруповертом. Тем более, что размеры оригинальной зарядки позволяют разместить в этом корпусе мою плату и выбранный блок питания. Поэтому, запускаю любимый SolidWorks и рисую:


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

Большим преимуществом современного 3д-моделирования является возможность создавать сборки из нескольких деталей – это позволяет легко, просто и правильно разместить внутри корпуса все компоненты, точно убедиться, что они туда влезут, а также досконально проработать способы их крепления. Поэтому дополнительно создал приближенные модели основных компонентов, после чего разместил их в корпусе:


Входной разъем для подключения сетевого кабеля решил использовать стандартный, IEC с выключателем-индикатором и предохранителем. Он несколько крупноват, зато имеет три контакта и позволяет подключать к устройству провод защитного заземления PE. Возможно, наличие заземления и не обязательно для зарядки, но уж точно необходимо блоку питания, поэтому в моем устройстве оно быть должно. Вариант прямого ввода сетевого кабеля внутрь устройства без дополнительного разъема я считаю крайне неудобным и не рассматриваю, так что будет крупный IEC. Разместил его с левой стороны на задней стенке корпуса заподлицо.

В качестве разъема для обновления прошивки решил использовать DB-9F, такие в далекие времена ставили в ПК на ком-порты. Только я установил в устройство «маму», а не «папу», как в ПК. Этот выбор был осознанным, чтобы минимизировать вероятность убивания устройства статикой при случайном прикосновении к разъему пальцем. Также это исключает случайное подключение в этот разъем кабелей старой компьютерной периферии. Разъем установил на заднюю стенку корпуса справа, но только немного утопил его вглубь.

К сожалению, в процессе размещения компонентов пришлось увеличить корпус по высоте на 15 мм, иначе не помещался вентилятор охлаждения. Такое увеличение никак не скажется на возможности хранить зарядку в MacPac’е, так как там по высоте имеется вполне достаточный запас, однако, поместить зарядку в обычный кейс от инструмента уже не выйдет. Этим пришлось пожертвовать ради хорошего охлаждения.

Наконец, чтобы корпус было возможно распечатать на 3д-принтере без сумасшедшего количества поддержек, разделил его на три части – нижняя крышка, основная часть и сокет LXT. Между собой части соединяются с помощью маленьких шурупов 2х6 и вплавляемых резьбовых втулок М3. Корпус распечатал из черного PETG:


Печать не обошлась без косяков – в основной части корпуса оказалось навесание с углом примерно 65°, которое распечаталось не очень хорошо. Поэтому пришлось немного обработать деталь наждачкой. А чтобы вернуть PETG его былой блеск – еще и пройти потом дихлорметаном.

Контакты для аккумулятора разработал полностью свои, вырезал их из кусочка листовой латуни толщиной 0.8 мм, специально купленной для этого в интернет-магазине:


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


Панель для механической защиты экрана выпилил из оргстекла толщиной 4 мм, она будет закрепляться в корпусе с помощью клея В7000:


Затем приступил непосредственно к сборке. Сначала вплавил все резьбовые втулки


Затем прикрутил сокет LXT, установил стекло, экран, энкодер и выходные терминалы. После этого прикрутил к отрицательному контакту батареи датчик температуры:


Далее установил блок питания и основную плату, а также соединил всё проводами:


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


В итоге, получилась вот такая симпатичная (на мой взгляд) зарядка:


Испытания


Первые же испытания зарядки большим током показали, что ТКС обычного китайского «шунта» в виде SMD-резистора 2516 слишком велик, значение выходного тока отклонялось более чем на 2% при умеренном нагреве. Тогда я попытался использовать в качестве шунта константановую проволоку, и мне даже удалось отрезать кусочек с сопротивлением 10 мОм, но оказалось, что у константана слишком велико значение термо-ЭДС, из-за чего показания при нагреве также уплывали. Делать было нечего, оставался дорогой манганин, поэтому в Китае были заказаны вот такие красавцы:


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

Дальнейшие испытания зарядки прошли успешно – пока плата не была установлена в корпус, она отлично выдавала ток 5 А даже без какого-либо активного охлаждения. В корпусе с вентилятором 6 А дались ей так же легко, поэтому было решено увеличить максимальный предел до 8 А. И термические испытания показали вполне умеренный нагрев при работе с таким током – за полчаса работы на КЗ точка максимального нагрева на корпусе оказалась около выходных терминалов, где температура составила только 40 градусов (тепловизор занижает):


Радиатор же нагрелся до 60-ти:


При работе на нагрузку (8 А 21 В = 168 Вт) максимальная температура корпуса составила те же 40 градусов:


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

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


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

Желтый разъем Makita


К сожалению, в таком виде применять зарядку по её прямому назначению было невозможно, т.к. имевшиеся в наличии совместимые аккумуляторы Макита без подключения желтого разъема не включали зарядный транзистор, а заряжать батарею через силовой терминал в обход штатной BMS было попросту небезопасно. В деталях этот момент был подробно описан в предыдущем обзоре, поэтому здесь лишь подведу итог, что надо было добавлять в зарядку желтый разъем.

Для этого на Али был приобретен вот такой кабель-переходник, с одного конца которого находится желтый разъем для установки на зарядку, а с другого – разъем JST PH (с шагом 2 мм).


Поскольку плата была уже полностью собрана и переделывать ничего не хотелось, все необходимые дополнительные компоненты были установлены на отдельную небольшую плату, схема которой приводилась ранее. Компаратор U4.2 был переоборудован для сравнения статусного напряжения батареи с пороговым значением около 1.4 В и подключен к ранее не используемому в зарядке выводу MISO, а вывод РС3 использован для реализации протокола 1-Wire. После этого зарядка стала «полноценной» и её доработки, к счастью, закончились. Правда, основную печатную плату я так и не обновил до конца, по-хорошему, надо бы разместить все компоненты на ней.

Режим ССС


Так как для управления процессом зарядки используется микроконтроллер, становится возможным реализовать совершенно любой алгоритм заряда аккумулятора, что было бы весьма затруднительно сделать в чисто аналоговой схеме. Одним из таких решений и стал алгоритм, который я назвал Continuous Constant Current или сокращенно ССС.

В этом режиме аккумулятор всегда заряжается заданным постоянным током, независимо от текущего напряжения. А чтобы избежать перезаряда, раз в 10 секунд зарядный ток отключается, после чего осуществляется контроль напряжения холостого хода аккумулятора, и, если оно превышает 4.2 В на банку, заряд считается завершенным. Конечно, так можно заряжать только аккумулятор без БМС, иначе она отключит его раньше по превышению напряжения банок.

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

Выводы


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

Конечно, весь проект оказался достаточно трудоемким, и занял значительно больше времени и сил, чем изначально предполагалось, но зато в процессе разработки мне удалось немного глубже разобраться с аккумуляторными технологиями Makita LXT и поделиться этим с вами.

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

На этом у меня всё, всем добра!

Исходные коды прошивки, корпус и макеты экранов доступны в моем репозитории:

https://github.com/kdekaluga/makita_charger

Страх и ненависть самодельщика
У меня был реноватор, три шуруповерта, аккумуляторная болгарка, лобзик, сабельная пила, гайковерт, несколько насадок Starlock и целое множество бит всех сортов и расцветок, пилки, а также отрезные круги, пара фрез, перфоратор, коронки и 2 дюжины сверл разного диаметра. Не то чтобы это был необходимый запас для самодельщика, но если начал покупать инструменты Makita, становится трудно остановиться. Единственное, что вызывало у меня опасение – это аккумуляторы. Ничто в этом мире не бывает более беспомощным, безответственным и бесполезным, чем человек, у которого села батарея в инструменте. Но я знал, что рано или поздно такое случится и мне придется заряжать эту дрянь.
Добавить в избранное
+86 +105
свернутьразвернуть
Комментарии (53)
RSS
+
avatar
+13
Ох монументально!
Осталось запустить в серию, думаю я первый готов купить!
+
avatar
+6
Спасибо. Боюсь только, что цена даже серийного производства окажется слишком высокой для большинства покупателей :)
+
avatar
+3
За хорошую вещь думаю многие готовы будут заплатить адекватную рыночную цену.
+
avatar
+1
Шедевр!!! Не перевелись еще инженеры на земле Русской! К сожалению запустить в серию вряд ли получится, особенно у нас. Если бы я мог то поставил бы не меньше сотни плюсов.
+
avatar
+3
Сильно! Я просто купил за 1к зарядку не оригинал. Попозже взял еще оригинальную в комплекте.
Китайские акки заряжаю через не оригинал, оригинальные акки через оригинальную.
Есть еще китайские акки с круглым гнездом, заряжаются через мелкое ЗУ типа телефонного.
+
avatar
+5
  • HeXeR22
  • 18 марта 2025, 20:29
Монументально, согласен! Почему-то в голове первая мысль была «Kirich наоборот») Отличный подход, но не к разборке и разбору принципов работы а наоборот созиданию.
Но. Режим блока питания, экран, в целом все эти возможности и даже больше есть в IMAX b6, b6neo еще компактнее и мощнее, есть и более дорогие и крутые модельные зарядки. И по цене они не так уж и дороги, а блок питания можно использовать едва ли не любой…
Второе НО: есть у меня проблема, собрал я отцу мощные аккумуляторы для инструмента, 10 и 9 а/ч (4 рядный 18650 и 2 рядный 21700), заряжать их нужно большим током (хочется ведь быстро), вывел я балансировочный разьем, и силовой хт60, выглядит это немного колхозно и немного мешается в работе. Но главное не это. Отцу 65 лет, дал я ему b6neo и вроде объяснил, как пользоваться, но сложно ему кучу кнопочек нажимать и понимать что там написано.
Так вот я к чему, собственно: если запускать данную зарядку в массы, думаю было бы удобно добавить несколько кнопок «профилей», которые один раз настроил, прилепил на корпус наклейку с надписями, какой профиль под какой акум. Даже в рамках макитовского формата, есть китайские акумы на 1300мА, есть, допустим 5 а*ч и есть 10 а*ч, пишем на них цифру профиля, человек берет акб, смотрит какая там цифра, нажимает цифру профиля и ставит его на зарядку.
Возможно сумбурно описал и с ошибками, с телефона пишу и тороплюсь, заранее извиняюсь)
+
avatar
+4
Спасибо. Да, я полностью согласен, что большинству людей будет проще с готовыми кнопочками-пресетами, поэтому даже и не думал ни о каком промышленном производстве)

В принципе, если есть желание, можно их добавить и в данную зарядку как вместо, так и вместе с энкодером.
+
avatar
+6
Шедевр. Полностью законченный проект от написания прошивки до корпуса. Такое сейчас не каждый сможет, особенно на ассемблере.
+
avatar
+6
Спасибо. Теперь я на собственном опыте осознал, сколько времени занимают такие проекты )
+
avatar
+3
  • fazerr
  • 18 марта 2025, 20:36
Подход очень тщательный. Особенное наслаждение доставило описание программной части. Спасибо!
+
avatar
+5
Спасибо. Я не был уверен, что описание программной части вообще будет кому-то интересно. Хорошо, что это оказалось не так )
+
avatar
+4
Doom бы туда вкрячить…
+
avatar
+1
  • vlo
  • 18 марта 2025, 21:02
куда «туда» — в 2к оперативки и 32к пзу?
+
avatar
+3
Когда стал разбирать блок, чтобы подогнуть пластину, тактильно обнаружил, что высоковольтный конденсатор более 10 минут сохраняет заряд!
Восхищен вашим самообладанием.
Я бы просто громко вспомнил о женщине с низкой социальной ответственностью. :)
+
avatar
+1
  • HeXeR22
  • 18 марта 2025, 22:07
Вспомнилось что-то: Только настоящий джентльмен, наступив ночью на кошку, назовет ее кошкой)
+
avatar
+1
Восхищен вашим самообладанием.
На самом деле, я больше переживал за блок питания) Потому что понимал, что от прикосновения рукой к конденсатору максимум ожог будет, ток ведь локально только идет. А вот прикоснулся я в том месте, где стоят транзисторы первички — мог запросто через палец на затвор подать 200 В, что однозначно бы его спалило. И как бы начать эксплуатацию нового БП с замены транзисторов не хотелось.
+
avatar
+2
  • Skylab
  • 18 марта 2025, 21:56
… а весь код его вывода написать с нуля и на ассемблере
Уровень программирования — Бог.
+
avatar
0
Моё почтение! Как хобби-проект это бомба. Но как устройство для реальной работы не очень. Во-первых все эти свистелки-перделки в виде экрана, алгоритмов не нужны. Во-вторых возникает вопрос с надёжностью: сгореть может вместе с квартирой. Ну и третье — как оно будет работать в условиях стройки: пыль, влажность, вибрации? Но за проделанную работу однозначно респект!
+
avatar
+2
Да, большинству не нужны, это так. Но мне нравится, когда зарядка показывает мгновенные значения, сразу можно оценить состояние аккумулятора.
Во-вторых возникает вопрос с надёжностью:
А что именно вам кажется ненадежным?
как оно будет работать в условиях стройки: пыль, влажность, вибрации?
Это не зарядка для стройки) Для стройки (и, вообще, профессионального применения) имхо проще брать оригинальный инструмент, чтобы не задумываться о таких вещах и иметь возможность обратиться по гарантии.
+
avatar
+1
С появлением на рынке китайских деталей, многие теоретические знания потеряли актуальность. Например, при ремонте аппаратуры я нахожу много неисправных резисторов, что для меня дико. Часто выходят из строя кварцы. Вот скажите, что будет при внезапной остановке тактового генератора? Это я и называю надёжностью, когда при выходе из строя, например, кварца мы не получим пожар.

У инженеров Макита есть неоспоримое преимущество перед нами — у них есть опыт. Поэтому как инженер я склоняюсь в поклоне перед вашими знаниями и упорством, но как эксплуатант я это покупать или сам собирать не буду.
+
avatar
+2
Вот скажите, что будет при внезапной остановке тактового генератора?
Ничего. В меге включен watchdog на уровне фьюзов, а интервал программно устанавливается на 0.125 секунды. В худшем случае на выход в течение этого времени будет поступать напряжение питания, затем сторожевой пес сбросит МК и из этого состояния он больше не выйдет. С аккумулятором за такой интервал определенно ничего не случится.
я нахожу много неисправных резисторов, что для меня дико.
Если вдруг что-то случится с резистором в цепи обратной связи, последствия действительно могут быть печальными. Но давайте посмотрим на ситуацию честно — во-первых, вероятность этого низкая, т.к. по этим резисторам не течет большого тока. Во-вторых, с такой же вероятностью то же самое может произойти и в оригинальной зарядке, и никто не знает, какие последствия будут там. Фотографии сгоревших Макит в интернете есть, конечно, там утверждается, что виноваты батареи, но кто знает, как оно на самом деле. И, наконец, в третьих, если мы рассматриваем возможные электронные проблемы, мне кажется, с большей вероятностью какой-то отказ произойдет в БМС китайской батареи — они и сомнительного качества могут быть, и при эксплуатации вибрацию испытывают, и токи там больше.

То есть, если вы совершенно не используете китайские батареи, вам и зарядка такого типа не нужна, вы всё будете заряжать оригиналом. А если же вы используете китайские батареи, то, скорее, следует думать об их безопасности, чем о безопасности данной зарядки. Да и сравнивать эту зарядку тогда надо с китайскими, а там вообще может быть что угодно, вплоть до отсутствия прямого контроля напряжения вторички (недавно обзор был).
у них есть опыт
А еще у них есть задача сокращения времени заряда. Поэтому, например, DC18RC заряжает током до 9 А. А чем выше ток заряда, тем выше вероятность негативных последствий. Поэтому тут еще подумать надо, что безопасней. Я, например, по этой причине DC18SD взял — ну, не готов я 3 Ач заряжать током 9 А.

Отсюда простой вывод — лучше не оставлять заряжаться аккумуляторы без присмотра. Хоть оригиналом, хоть такой зарядкой.
+
avatar
+1
Огромное уважение автору, и за проект, и за отличную статью!
А можно нубский вопрос, для чего нужен и как работает конденсатор С27 между входами ОУ?
тактильно обнаружил, что высоковольтный конденсатор более 10 минут сохраняет заряд
Когда-то тактильно измерил напряжение на конденсаторе фотовспышки, до сих пор помню ощущения ;)
добавил разрядный резистор самостоятельно
А зачем его разряжать, с заряженным при следующем включении бросок тока будет меньше.
Сначала я использовал в инструментальном усилителе распространенный LM358
На всякий случай, может кому-то пригодится: есть относительно недорогие готовые инструментальные усилители с неплохими характеристиками: TPA1286. Нужен всего один точный резистор для выставления коэффициента усиления.
+
avatar
+3
для чего нужен и как работает конденсатор С27 между входами ОУ?
TL;DR: для стабилизации усилителя датчика тока.

Изначально, когда я проверял концепт программного ШИМ, в качестве датчика тока установил резистор 0.5 Ом, с которого снимал достаточный для АЦП сигнал уже при 1 А. Концепт заработал, после чего я нарисовал схему, добавив в неё усилитель тока — казалось бы, что могло пойти не так? В реальности проверил такую конфигурацию я уже только на собранной плате, и оказалось, что она совершенно не работает. Показания тока, считанные АЦП, заметно менялись даже от простого прикосновения пальцем к земляной клемме выхода. В тот момент я в первый раз подумал, что ничего не получится :) Но стал экспериментировать, менять резисторы, подключать конденсаторы.

И вдруг оказалось, что если снизить сопротивление резисторов обвязки ОУ в 100 раз (входные с 10 К до 100 Ом) и добавить вот этот конденсатор, то усилитель тока переставал реагировать на странные помехи и начинал работать стабильно. Этот вариант и оставил. Кстати, временная постоянная, вносимая данной цепочкой составляет 20 микросекунд, то есть, даже не оказывает заметного влияния на полосу усилителя тока.
и как работает конденсатор С27
Думаю, основная проблема в том, что помеха идет по земляному проводу. Я выяснил это, когда временно добавил в цепь питания земли МК дроссель с индуктивностью несколько мГн. Соответственно, конденсатор между входами ОУ сглаживает эту помеху, не позволяя ей сильно менять считываемые значения.
с заряженным при следующем включении бросок тока будет меньше.
Думаю, разряжаться он всё таки будет, просто очень медленно. И если следующее включение произойдет, например, через сутки, он уже будет разряжен. Поэтому, с этой точки зрения практической пользы от отсутствия резисторов нет. А вот с точки зрения безопасности — есть, ведь шанс полезть внутрь через 10 минут после выключения достаточно велик.
+
avatar
+2
И вдруг оказалось, что если снизить сопротивление резисторов обвязки ОУ в 100 раз (входные с 10 К до 100 Ом) и добавить вот этот конденсатор, то усилитель тока переставал реагировать на странные помехи и начинал работать стабильно.
Полезный опыт, спасибо.
Немного погуглив, нашёл похожее решение у классиков Хоровица/Хилла:
http://the-epic-file.com/text/bookz/aoe_3/ch_05/aoe3_05_16.htm#x_05_16_04
Дополнительная информация
+
avatar
+2
Интересно, спасибо. У меня именно тот случай был:
Если подключение кабеля, прикосновение к схеме карандашом или просто приближение рук приводит к изменению напряжений смещения, то, возможно, имеет место высокочастотные наводки
Только источником у меня выступает собственный же преобразователь. Наверное, надо было еще и плату несколько иначе разводить, силовую часть полностью отдельно ставить.
+
avatar
0
  • Leoniv
  • 19 марта 2025, 00:59
У ХХ не такой диффусилитель, здесь конденсатор — фильтр для дифференциальной помехи. На устойчивость усилителя не влияет.
+
avatar
0
На устойчивость усилителя не влияет.
В теории, да. Но на практике получалось вообще непонятно что, например, конденсатор между инверсным входом и выходом ёмкостью даже 5 пФ приводил в оригинальной схеме (с резисторами 100К/10К) к возбуждению петли регулирования. Конденсатор 1 нФ между входами вообще всю работу ломал, насколько я помню. А с резисторами 1К/100 Ом и конденсатором 100 нФ схема полностью стабильна, что с ней ни делай. Поэтому и не люблю аналоговую схемотехнику.
+
avatar
0
  • Leoniv
  • 19 марта 2025, 03:27
Вопрос устойчивости — сложный, особенно если часть петли в цифре. И не всегда тормознутое более устойчиво. Часто бывает наоборот, добавляя в регулятор D-компоненту повышается устойчивость. Это и понятно — уменьшается запаздывание фазы на частоте единичного усиления. Точно так же можно и в аналоговой части добавлять ускоряющие цепочки. Но тут обычно блуждание в потемках.
+
avatar
0
  • Leoniv
  • 19 марта 2025, 00:57
C27 потихоньку вредит :)

Зеленый график — АЧХ этого диффусилителя без конденсаторов. Красный график — с конденсатором 100 нФ между входами ОУ. Синий график — плюс цепочка 1 кОм/100нФ на выходе.

+
avatar
0
О, спасибо за АЧХ, интересно посмотреть.
C27 потихоньку вредит :)
Ну, конечно, АЧХ он вредит, но по вашему графику видно, что влияния от него на 10 КГц нет вообще. А у меня ПИД работает с еще более низкой частотой, так что всё, что выше уже не особо важно. А вот без него показаний вообще нормальных было не прочесть, они менялись практически от положения руки. Прямо терминвокс какой-то.

Ну, и интересный момент, что влияние от выходной RC-цепочки значительно больше, чем от этого конденсатора. Но это я предполагал и по номиналам.
+
avatar
0
  • Leoniv
  • 19 марта 2025, 03:20
Очень нехороший пик, а это почти 20 дБ, т.е. в 10 раз. На этой частоте будут усилены шумы и помехи, а еще это признак проблем с устойчивостью.

Выходная цепочка 1 кОм + 100 нФ, а тут 200 Ом + 100 нФ.
+
avatar
+6
  • qwerewq
  • 18 марта 2025, 22:28
Потрясающая работа проделана… Респект и уважуха, как говорится.
+
avatar
0
Насколько крутецкая, монументальная т затратная была проделана работа, сам обзор только чего стоит. Настолько и не понятна ее цель. Я понимаю, что это удовольствие, а может задел на будущее, проба пера так сказать. Но черт! Все ради того чтобы заряжать дешёвые китайские копии макитоаккумов?
Я каюсь, конечно я еще не читал всю статью, прочёл только начало, но там это все о чем было сказано, это желание регулировать ток самому.
+
avatar
+1
Все ради того чтобы заряжать дешёвые китайские копии макитоаккумов?
А почему, собственно, нет? :) Надо же их чем-то заряжать.
это желание регулировать ток самому.
Ну, да, началось всё именно с этого. А потом оказалось, что ей, например, очень удобно подзаряжать автомобильный аккум. При этом, она оказалась значительно проще и тише любого другого имеющегося варианта. Плюс, ёмкость отданную считает.
+
avatar
0
  • leg42
  • 18 марта 2025, 23:17
Да уж, мне очень и очень далеко. Купил пилу redback 40 вольт. В комплете 2 Акб EB20B.
А зарядки оказалось нет, заказал пришла но! Совсем другой корпус Fuxtec EC20 4 вывода C- T ID C+
а у аккумулятора 5. P+ C+ ID T P-
Соеденил P- C- ID ID T T C+
И вот голову ломаю, заряда нет. Блок выдаёт 40в акб 35
+
avatar
+1
К сожалению, тут вам ничем не помогу. Даже у Макиты 40-вольтовую серию не щупал.
+
avatar
0
  • INN36
  • 18 марта 2025, 23:39
а весь код его вывода написать с нуля и на ассемблере, так как очевидно, что на Си он будет недостаточно быстрым
И тут я понял, что это край. Дальше имеет смысл полистать на расслабоне, по диагонали… ;)

Всего разных нот – двенадцать
Вспомнился старинный анекдот про Игоря Николаева и пять нот. Но под таким суровым текстом он скорее всего будет неуместен.)
+
avatar
+1
Вспомнился старинный анекдот про Игоря Николаева и пять нот. Но под таким суровым текстом он скорее всего будет неуместен
Да ладно, что уж, жгите )
+
avatar
+2
  • INN36
  • 19 марта 2025, 01:03
Журналист Николаеву:
— Игорь, вы написали много шлягеров, но почему их мелодии так сильно похожи?
— А вы попробуйте придумать что-то новое, если нот всего пять!
— Вообще-то нот семь…
— Семь???
+
avatar
0
  • Leoniv
  • 19 марта 2025, 00:35
Прекрасная работа! Полезными являются критические комментарии, но тут критиковать нечего. С очень большой натяжкой попробую что-то высказать критическое. Не в порядке важности замечаний, а в порядке их следования по тексту статьи. Для внимательного просмотра схемы решил ее скачать, но на этом сайте это оказалось проблемой, пришлось url картинки выковыривать из html.

1. «у AVR по современным меркам весьма ограниченные ресурсы, а писать программу в таких условиях значительно интересней» — воспринял это как стёб :)
2. «Поскольку МК питается от 5 В, необходимо согласовать уровни напряжений выходных сигналов, идущих к дисплею. Вариантов согласования есть несколько, но я выбрал самый простой – гасящие резисторы.» — да, способ не очень красивый. Чтобы не завалить фронты, нужны низкоомные резисторы. Но тогда страшно за защитные диоды. Лучше поставить полноценные делители. Хотя в данном проекте, вроде, ничто не мешало запитать ATmega от 3.3 В?
3. «Q11 инвертирует сигнал и усиливает его по амплитуде до 12 В» — для большей скорости усиление можно было делать каскадом с ОБ, а не ОЭ. Но в данном случае скорости более чем хватает.
4. «необходимость точного подбора резисторов делителей так, чтобы коэффициенты деления двух цепочек были очень близки, что затруднительно в серийном производстве» — наоборот, в интегральных инструментальных усилителях получается гораздо лучшее согласование компонентов, чем при дискретной реализации. К тому же, там резисторы находятся при одинаковой температуре, а для дискретной схемы даже градиенты температуры на плате вызывают снижение подавления синфазного сигнала. Что касается схемы на 3-х ОУ, они есть разные, одна из конфигураций накладывает менее жесткие требования на точность резисторов при условии большого усиления. Кроме этого, у схемы есть еще достоинства — регулировка усиления одним резистором, высокое входное сопротивление по обоим входам (усилитель на одном ОУ имеет низкие и РАЗНЫЕ входные сопротивления, есть конфигурация на 2-х ОУ, исправляющая это, автор David Birt).
5. «R2R ОУ, но даже они не в состоянии выдать ровно ноль вольт, их минимум начинается где-то от 25 мВ и сильно зависит от нагрузки. А 25 мВ – это примерно 21 единица шкалы АЦП или 2%, и это слишком большая погрешность при измерении тока.» — можно просто сместить шкалу вверх на какие-нибудь 100 мВ, потеряем незначительную часть шкалы АЦП. Диффусилители имеют вывод REF, относительно которого они представляют свое выходное напряжение. Здесь он заземлен (резисторы R4, R18), но можно его подключить к опоре 100 мВ. Эту опору можно мерить еще одним входом АЦП и вычитать. Но правильней делать калибровку и вычитать опору вместе со смещением ОУ. Такой прием использую в своем ЛБП PSL-3604. Хоть там двухполярное питание ОУ, но сами ОУ могут иметь отрицательное смещение, что погубит точность без принятия этой меры.
6. «Еще одним нюансом схемы является резистор R44. Его задача – сдвинуть точку нуля токовой шкалы в область положительных напряжений.» — если сделать как в пункте 5, то это будет лишним.
7. «Платы делал ЛУТом, из-за чего их качество существенно ниже основной.» — почему-то сильно подтравливаются полигоны. Такое замечал при плохом тонере, старался использовать фирменный. Но в последнее время с ним напряг, поэтому попробовал купить новый ктиайский картридж. Взял CACTUS. Результат — отличный.
8. «Написание программы для МК в таком проекте – не самый сложный» — как по мне, так это сложнее составления схемы и изготовления механики. Сколько проектов похоронило ненаписанное ПО!
9. «дает результирующую частоту PWM 62.5 КГц» — интересный факт: STM32F334 может генерировать 8-битный PWM частотой до 18 МГц.
10. «На практике же можно поднять эту частоту до 1 МГц, и АЦП всё еще будет неплохо работать, что даст уже до 77 тысяч преобразований в секунду» — из моего опыта, точность измерений при повышении частоты преобразований выше 15 кГц заметно падает. Но конкретные результаты не сохранил.
11. «Еще один нюанс управления PWM заключается в том, что мега ни при каком значении регистра OCR0A таймера не позволяет получить на выходе абсолютный логический ноль.» — надо включить инверсное управление выходом OC и загружать инвертированный код. Тогда будет абсолютный ноль, но не будет абсолютной единицы, что тут и не надо.
12. «поделился проблемой с супругой, и она спросила, зачем я провожу измерения именно в то время, когда на вход попадает помеха» — афигеть, где таких супруг выдают?
13. «это даст частоту обновления 30.5 Гц, чего более, чем достаточно для отображения» — это же очень много, обычно делают не более 10 Гц.
14. «сохраняет в глобальную переменную g_buffer» — наверное, буфер может принадлежать классу дисплея, данные всегда должны принадлежать кому-то конкретному. А в эту функцию просто передавать на него указатель.
15. «отлавливать примерно до двух тысяч тиков энкодера в секунду» — так быстро для энкодера и не надо. Обычно опрашиваю раз в 1 мс. С энкодером есть ряд нюансов. Шаг вперед и назад должен производится в одной точке, чтобы небольшое качание энкодера туда-сюда не приводило к постоянному inc (или dec). Переключение должно совпадать с моментом механического щелчка. Надо давить дребезг, для чего я использую тот факт, что на каждый щелчок меняется 4 состояния энкодера и требую последовательного их прохождения. Но все равно обработкой доволен не полностью. Аппартная обработка в STM32 предназначена для других энкодеров, которые на валах двигателей. Она не давит дребезг.
16. «Корпус распечатал из черного PETG» — это вкусовщина, конечно, но корпус из-под 3-D принетера на мой взгляд ужас-ужас из-за плохой текстуры поверхности. Портит все впечатление об устройстве. Особенно плохо выглядит на последнем фото. Вроде, простая прямоугольная коробка, но из нормального пластика, была бы лучше?
17. «Не то чтобы это был необходимый запас для самодельщика» — вроде, тоже самоделю, но зачем столько инструмента — не понимаю. Это же забарахляет жизненное пространство.
18. «мне придется заряжать эту дрянь» :))) Пока у меня в жизни не было ни одного аккумуляторного инструмента. Вот думаю — доживу ли я свой век без них?

Часто думал о том, что при описании готовых проектов никогда нет описания прошивки. Только ссылка на скачивание. А схемы и чертежи подробно рассматриваются. В результате по журнальным статьям невозможно научиться делать такое же, они не учат писать прошивки. И вот в этой статье подробно рассмотрена программа. Ощущения двойственные. Хорошо, но очень тяжело разбираться. С ассемблером — вообще невозможно. И очень плохо, что вставки текста в виде картинок. Должен быть текст, даже если форматирование и подсветка синтаксиса исчезнет.

Какой на выходе выброс тока при переходе CV-CC (например, при внезапном КЗ)?

Сколько времени ушло в сумме на проект?

Ну и еще раз — проект прекрасен, все придирки высасывал из пальца, теперь он болит :)
+
avatar
+1
  • stump
  • 19 марта 2025, 00:43
17.Leoniv «Не то чтобы это был необходимый запас для самодельщика» — вроде, тоже самоделю, но зачем столько инструмента — не понимаю. Это же забарахляет жизненное пространство.
Написал наш участник, имеющий фрезерный станок :-)
+
avatar
0
  • Leoniv
  • 19 марта 2025, 01:02
Вот именно, один. А не 9 инструментов, перечисленных в обзоре. По-моему, весь этот аккумуляторный инструмент имеет смысл только в стоительстве. Чем я категорически не занимаюсь.
+
avatar
0
А чем, кстати, фрезерный от сверлильного отличается? Устойчивостью к радиальной нагрузке на вал?
+
avatar
0
  • Leoniv
  • 19 марта 2025, 03:23
В первую очередь наличием координатного стола. Ну и шпиндельный узел намного серьезней. У меня конус Морзе 3, куда можно поставить цанговый патрон и прочую оснастку. Фрезеровать со сверлильным патроном довольно стремно.
+
avatar
0
Ого, вот это комментарий, он даже в экран не влазит :)
1. воспринял это как стёб :)
Вовсе нет. У меня сейчас по работе шаблон на шаблоне и шаблоном погоняет. Задачи не алгоритмические, а из разряда «куда бы еще шаблон впихнуть». После такого программирование под AVR (особенно на асме) — отдых.
2. Но тогда страшно за защитные диоды. Лучше поставить полноценные делители. Хотя в данном проекте, вроде, ничто не мешало запитать ATmega от 3.3 В?
Там ток 4 мА через них, выдержат. По поводу питания — по даташиту надо не менее 4.5 В для 16 МГц, иначе бы именно так и поступил.
5. но можно его подключить к опоре 100 мВ. Эту опору можно мерить еще одним входом АЦП и вычитать.
Согласен, в своем лабораторном БП я тоже примерно так делал. Здесь не стал, наверное, потому, что в наличии R2R ОУ всё равно нет, думал сначала вообще на ширпотребе LM358 сделать, а там 100 мВ не хватит.
7. Такое замечал при плохом тонере
У меня тонер еще фирменный, что с принтером шел. Наверное, у меня не такой принтер, придется смириться :) У меня Pantum 2500W. Хотя картридж дополнительный от кактуса я к нему еще пару лет назад прикупил, но пока ни разу не использовал. Надо будет попробовать.
8. как по мне, так это сложнее составления схемы и изготовления механики
Это может быть долго, порой неинтересно (из-за однообразности), но не самое сложное. В случае данной зарядки у меня три раза было желание бросить, и ни один из них не был связан с программированием. Первый и третий были связаны с аналоговой схемотехникой, а второй — с невозможностью заряжать аккумуляторы без желтого разъема.
9. STM32F334 может генерировать 8-битный PWM частотой до 18 МГц.
Ого, F3 серию не смотрел, но это же 4.6 ГГц тактовая частота? Или там какие-то хитрости?
10. из моего опыта, точность измерений при повышении частоты преобразований выше 15 кГц заметно падает.
Сам проверял и разница с 100 КГц была в 1, редко 2 единицы, причем, при низкой частоте показания были устойчивыми, а при более высокой — просто начинали чуть прыгать. Может быть, вы смотрели на более старых чипах и сейчас что-то поправили?
11. надо включить инверсное управление выходом OC и загружать инвертированный код
Хм, интересное замечание, спасибо! Позволит сэкономить пару тактов)
12. где таких супруг выдают?
Очень часто человеку, длительно решающему какую-то достаточно сложную задачу свойственно смотреть на неё и свое решение однобоко, как будто её можно решить только таким способом. В этом случае общение с человеком, не вовлеченным в задачу может дать неожиданные результаты)
13. это же очень много, обычно делают не более 10 Гц.
Конечно. Я тут хотел сказать, что этого будет вполне достаточно, чтобы, скажем, выводить значения с комфортной частотой 5 Гц.
14. А в эту функцию просто передавать на него указатель.
Тут «один поток», можно работать и со статическим буфером, чтобы избежать передачи лишних параметров. Ведь всё равно кроме вызывающего кода этим буфером сейчас никто не пользуется, тогда зачем указатель? )
15. С энкодером есть ряд нюансов
Да. Мой вариант — не очень хороший, ибо не давит дребезг и не контролирует прохождение полного цикла. Обдумываю, чтобы его доработать. Давить дребезг, кстати, можно или аппаратно, или требованием, чтобы два последовательных считывания возвращали одинаковый результат.
16. Особенно плохо выглядит на последнем фото. Вроде, простая прямоугольная коробка, но из нормального пластика, была бы лучше?
Нет. Во-первых, в реальности корпус выглядит лучше, чем на фото, фото всегда подчеркивают дефекты 3д-печати, которые не так сильно заметны в жизни. Во-вторых, для вещи такого применения это не имеет совершенно никакого значения, ведь она не ставится для украшения, а используется строго по её (достаточно узкому) назначению. Я больше скажу — я даже не пытался улучшить печать уменьшением высоты слоя и/или снижением скорости, хотя это вполне возможно. Только деталь бы печаталась 12 часов, а не 3 ) И, в-третьих, мне нужен был корпус, который повторяет форму зарядки от Макиты, чтобы он вошел в «штатное место» макпака. Но, при этом, он должен быть чуть выше — такой готовый не найти. А напечатать — легко.

Но если уж прямо не нравится текстура, можно печатать из ABS — он токсичен (при печати), но значительно легче обрабатывается. Как механически, так и химически. Многие печатают, шкурят, красят и получают деталь, практически аналогичную заводской.
18. Пока у меня в жизни не было ни одного аккумуляторного инструмента. Вот думаю — доживу ли я свой век без них?
Ну, это вам решать :) Аккумуляторный шуруповерт у меня уже лет 15, вещь крайне удобная. Как по прямому назначению, так и для сверления, если не нужна особая точность, например, при сборке мебели. Остальному аккумуляторному инструменту раньше не доверял, типа, не сравнится с мощностью сетевого. Но сейчас частично меняю свое мнение, т.к. иногда свобода от провода компенсирует меньшую мощность.
И очень плохо, что вставки текста в виде картинок. Должен быть текст, даже если форматирование и подсветка синтаксиса исчезнет.
Я с вами полностью согласен. Но этот обзор уже на пределе по объему текста, поэтому на такую жертву я пошел осознанно, иначе материал бы просто не вместился. Я даже думал, что если не уложусь, придется и основной текст вставлять картинками :)
Какой на выходе выброс тока при переходе CV-CC (например, при внезапном КЗ)?
Именно КЗ обрабатывается отдельно, поэтому там все быстро:

Время реакции на КЗ составляет примерно 40 мкс, остальной ток идет уже от выходной ёмкости (кстати, тут еще старая версия кода, где не было полного отключения ШИМ). А вот выходные характеристики в режиме CV сильно хуже аналоговых стабилизаторов, но это было прогнозируемо с самого начала. Переход CV-CC, емнип, более-менее, но это потому, что у многих аналоговых СС не очень) К сожалению, сейчас уже осциллограммы не смог найти, т.к. снимал их в самом начале проекта (начинал именно с ШИМ). Могу переснять.
Сколько времени ушло в сумме на проект?
Сложно сказать, т.к. занимался в свободное от работы и других дел время. Но много. Начал в августе прошлого года, более-менее закончил к НГ, но потом занимался изучением особенностей зарядки Макиты, после чего дорабатывал.
все придирки высасывал из пальца, теперь он болит :)
Вовсе нет, всегда интересно и полезно читать аргументированную критику, ведь практически всегда есть возможность сделать лучше) Вопрос лишь только, где остановиться)
+
avatar
0
  • Leoniv
  • 19 марта 2025, 03:16
У меня сейчас по работе шаблон на шаблоне
После такого программирование под AVR (особенно на асме) — отдых.
Хм, действительно так может быть. Очень жаль, что я не программист.

по даташиту надо не менее 4.5 В для 16 МГц
Ну там 4.5 В это для 0 — 20 МГц. На графиках рисуют до 17 МГц при 4 В. Но на практике работает на 16 МГц при 3.3 В, для хоббийных проектов вполне можно использовать, разгон совсем небольшой.

Здесь не стал, наверное, потому, что в наличии R2R ОУ всё равно нет
Это спасает не только от неидеальной «рэйловости» возле земли, но и просто от смещения, если оно отрицательное.

В случае данной зарядки у меня три раза было желание бросить, и ни один из них не был связан с программированием.
Мне тяжело дется программирование. Там всё можно сделать по-разному, на каждом шагу приходится принимать решения. Что выматывает. И постоянно есть чувство неудовлетворенности от некрасивой структуры программы. А как сделать красиво — непонятно.

но это же 4.6 ГГц тактовая частота? Или там какие-то хитрости?
Да, эквивалентная частота тактирования для таймеров HRTIM именно такая. Там используется DLL (delay-locked loop).

Может быть, вы смотрели на более старых чипах
На ATmega8.

чтобы два последовательных считывания возвращали одинаковый результат
Смотря с какой частотой опрашивать. У механического дребезга есть своя характерная частота, если опрашивать быстро, то и при дребезге соседние значения будут одинаковые. Можно делать по-другому — требовать прохода промежуточного состояния. Но надо сказать, что проблема остается. Через лет 5 энкодеры начинают плохо работать (окисляются контакты?) — при быстром вращении пропускают события.

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

обзор уже на пределе по объему текста
Не знал про ограничение. Как раз планирую обзор самодельной паяльной станции, очень похожий на этот, тоже хотел написать с разбором программы. Но когда сам почитал, то уже сомневаюсь, что это надо делать. Я хоть и довольно плотно в этой теме, но читать про чужую программу очень тяжело.
+
avatar
+1
  • stump
  • 19 марта 2025, 00:35
Обзор:
!!!
+
avatar
+1
Проект супер. Отдельный плюс за нормальные шрифты :)

Хотя мне лично жаль, что автор кажется умышленно усложнял себе задание. Выбрав слабенький МК и выжимая из него все соки. ИМХО, было бы прикольно, увидеть подобный проект, использующий связку из ESP32 + IPS/AMOLED экрана, которых сейчас множество расплодилось от китайцев, ну и платку чтобы можно было заказать заводскую, тогда и Bluetooth/WiFi из коробки сделать можно со всеми плюшками (типа извещения об окончания заряда на мобилку, или обновлений прошивки на лету).
+
avatar
0
увидеть подобный проект, использующий связку из ESP32 + IPS/AMOLED экрана
Вот именно с ESP я практически не работал, опыта нет. Но знаю, что в 8266 нет аппаратного ШИМ, это категорически не подходит для данного проекта. А в ESP32 как обстоят с этим дела?
+
avatar
0
  • vedroid
  • 19 марта 2025, 03:06
В ESP вроде с ШИМ работают с помощью docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/mcpwm.html И еще что-то здесь вспомогательное docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/pcnt.html
+
avatar
0
Посмотрел, в ESP32 есть LEDC, похоже, он умеет аппаратно, причем с тактовой частотой 80 МГц (это 78 КГц при 10 бит). Тогда вполне можно сделать.

С другой стороны, здесь говорят, что аппаратного PWM нет. И кому верить? )
+
avatar
+1
  • topolys
  • 19 марта 2025, 01:30
Плюс.Очень интересно было почитать!
+
avatar
0
  • vedroid
  • 19 марта 2025, 02:49
Похоже здесь первичное это процесс, то есть это хобби (заполнение свободного времени). Потому что, как уже писали, ничего не мешает взять более мощный/современный MCU, и потратить меньше времени на реализацию и вероятно на дальнейшую поддержку/развитие проекта тоже.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.