Полностью автоматическое зарядное устройство для аккумуляторов 12V (автомобильных, ИБП и т.д.) на Arduino

Полностью автоматическое зарядное устройство для аккумуляторов 12V (автомобильных, ИБП и т.д.) на Arduino

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

Итак, как уже было озвучено в "минутке", сегодня я расскажу вам о том, как я превратил старинное зарядное устройство начала семидесятых в новое, современное, с управлением от микроконтроллера. Мысль такая пришла мне оттого, что мой друг позвал меня к себе на пиво в момент, когда у меня заряжался аккумулятор. Я бы и рад был пойти, но вот незадача - зарядное-то нужно было постоянно контролировать! Бегать к нему раз в полчаса, а то и чаще, чтобы проверить напряжение на аккумуляторе, и если бы оно превысило максимум - уменьшать мощность соответствующим переключателем на передней панели. Согласитесь, неудобно: ты постоянно прикован к заряжающемуся аккумулятору и не можешь никуда отойти, а если вдруг проворонишь нужный момент - аккумулятор тебе спасибо не скажет. С другой стороны, он и так его не скажет: он же памятник говорить не умеет))))

Шутки - шутками, а мне давно хотелось сделать что-то серьёзное на Arduino, с которым я познакомился ещё в ноябре, забрав заветную посылку от китайцев из Aliexpress с микроконтроллером, шилдом и другими ништяками на почте. И вот она, отличная возможность - бери, да делай! Так что я взял и начал, непосредственно, делать!

Схема зарядного устройства

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

Список основных компонентов

Далее было бы неплохо определиться со списком основных компонентов, которые я использовал при доработке этого устройства (всё с удобными ссылками на Aliexpress, всё для вас!):

  • 8 конденсаторов: 2 по 22 пФ, 1 на 100пФ, пару штук по 100 мФ, и для питания - один большой на 6.3 вольта и два больших на 16, например на 3300, 1000 и 1500 мФ соответственно (можно и все на 16 вольт или больше, без разницы).
  • Программируемый микроконтроллер Atmega328 с кварцем на 16 МГц и желательно шилд для него (листать несколько страниц до первого шилда, это будет самый дешевый вариант), чтобы было удобно прошивать.
  • По той же причине - зажимные сокеты для вышеназванной микросхемы. Хотя можно, в качестве эконом-варианта обойтись и обычными. Ну или припаять провода к МК и прошивать по ним другой ардуиной или прошивальщиком - как вам удобно.
  • 9 транзисторов КТ315 и 1 КТ815 (или аналоги) - выпаять из любой старой советской техники.
  • 8 белых рассеивающих светодиодов и 1 зелёный.
  • 9 релюх с катушками на 12 вольт: одна на 220 V, четыре под 12 V 16 A и четыре поменьше под 12 V 12 A. Последние 8 нужны как можно меньшего размера.
  • 40 резисторов: 15 по 560 Ом, 12 килоомных, 8 по 220, 2 по 10k и по одному экземпляру 3k3, 4k7 и 30k.
  • Парочка диодов под 12 вольт: один на полампера, второй минимум на ампер, запас не помешает. Выпаивается откуда угодно, например из дохлых БП.
  • Какая-нибудь лампочка, можно светодиод с резистором, горящие от 220 вольт. Вообще неонка бы там круто смотрелась!
  • Шестнадцатисегментный экранчик из старого системника для вывода на него текущего напряжения. Ну или три семисегментных. Или вообще забить болт на отображение текущего напряжения: это, всё-таки, автоматическое устройство, напряжение оно контролирует само, вам его знать не обязательно, в крайнем случае тестером померяете. Вместо экранчика можно просто парочку светодиодов поставить, чтобы ардуина ими перемигивала, мол, не зависла я, работаю, всё под контролем! (Нет, я ни разу не видел зависшей Ардуины, но тем не менее надо быть готовым ко всему.) 🙄
  • 3 сдвиговых регистра 74HC595
  • Ну и что-нибудь типо половинки вот такой монтажной платы (я купил на ебэе 10 штук за стакан компота):

Хочу заметить, что практически все компоненты, используемые в данном проекте, не имеют точных номиналов и могут быть заменены на аналогичные или похожие либо с минимальной адаптацией схемы и прошивки, либо вообще без каких-либо изменений. Я старался использовать те детали, которые буквально валялись у меня под рукой: например, подавляющее большинство используемых тут резисторов и транзисторов я недавно выпаял из допотопного магнитофона Vilma, останки которого после распаивания благополучно отправились на свалку. Так что потраченная сумма на покупку деталей для этого устройства не превышает $15, и то, большая часть бюджета ушла на релюхи.

Исходная версия зарядного

К сожалению, у меня не нашлось фотографии этого зарядного в исходном состоянии, поэтому всё, что я могу вам предложить на данном этапе - фото с уже снятой крышкой, открученной механической частью переключателя мощности (слева) и ручки этого переключателя (справа). Электрическая же его часть торчит сверху устройства. Также из своего родного отверстия вынут тумблер переключения напряжений (6 или 12 вольт):

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

Принцип работы исходного устройства

Само зарядное устройство построено по простому принципу - на первичную обмотку трансформатора подаётся 220 вольт, соответственно на вторичной также появляется переменное напряжение. Мощностью можно управлять благодаря тому, что со вторичной обмотки есть несколько выводов (всего 9). Это означает, что между первым и каждым из последующих восьми выводов получается всё большее количество витков, а чем больше витков, как известно, - тем выше напряжение (то есть ток или мощность - как вам будет угодно). Эти 8 выводов приходят на тот самый переключатель, с помощью которого вы и выбираете текущую мощность заряда аккумулятора.

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

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

Выбор способа коммутации вторичных обмоток

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

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

Ах, да! Чуть не забыл! На самом деле со вторичной обмотки было не 9 а 10 выводов, первых два были один для шести вольт, другой для двенадцати, оба шли к тумблеру, а уж потом к диодному мостику:

Но так как я не планировал заряжать аккумуляторы на 6V - от этой функции я отказался, поэтому выкинул тумблер (из конструкции, а не вообще) и заизолировал провод для шести вольт, а двенадцативольтовый пустил с трансформатора напрямую на диодный мост.

Так как же всё-таки коммутировать? Тут уже либо транзисторами, либо тиристорами, либо с помощью реле. И я выбрал последний вариант, ведь релюхи меньше транзисторов / тиристоров и, в отличие от них, совсем не греются, если взять их с запасом по току. Так я и сделал - купил 8 небольших релюшек с катушками на 12 вольт, 4 штуки на 16 ампер и 4 на 12. По размеру они как раз умещались в свободное пространство внутри корпуса зарядного:

Алгоритм работы устройства

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

Для начала введём 3 важнейших параметра:

// Максимальное напряжение * 10 byte maxVoltageX10 = 148;

// Напряжение * 10, при котором уже нельзя увеличивать мощность byte powerUpMaxTreshold = 142;

// Напряжение * 10, при котором мощность повысится принудительно byte powerUpMinTreshold = 136;

Умножены на 10 они во-первых потому, что при их вычислении удобнее пользоваться целыми числами - никаких округлений и т.д., во-вторых потому, что на экран, фактически, и выводятся такие числа, а запятая - она как-бы виртуальная, поэтому незачем делать в коде никому не нужные вычисления, и так понятно, что это 14.8, 14.2 и 13.6 вольт соответственно.

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

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

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

// Если между повышением мощности по powerUpMinTreshold и её понижением прошло менее, чем столько миллисекунд, то powerUpMinTreshold снизится на 1 unsigned int powerUpMinTresholdTimeout = 60000;

Как видно из комментария, благодаря этому параметру powerUpMinTreshold будет снижаться на одну десятую вольта каждый раз, как мозги будут понижать мощность менее чем через powerUpMinTresholdTimeout миллисекунд после её повышения. Всё, проблема решена: пощёлкают релюхи один раз, пощёлкают второй, а на третий они уже 10 раз подумают перед тем, как щёлкнуть. Ха-ха-ха, не с теми связались!

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

Я сразу запланировал, что питание всей системы будет осуществляться от самого аккумулятора, а 220 вольт - подключены через реле, управляемое мозгами (то есть Ардуиной), благодаря чему у нас будет возможность отключить подачу питания на устройство в случае аварийной ситуации или по завершению зарядки аккумулятора. Более того, от реле будет меньше искрения, чем от засовывания вилки в розетку, так что этот вариант ещё и надёжнее. Про её подключение будет, естественно, написано ниже, ведь пока мы обсуждаем лишь теоретические вопросы.

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

// Задержка в миллисекундах перед включением зарядки unsigned int powerOnDelay = 2000;

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

if (powerLevel == 1)

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

Кстати, в коде есть весьма интересный параметр:

// Уровень мощости (начальный) byte powerLevel = 0;

Он, как вы уже догадались, устанавливает начальный уровень мощности и был введён на очень ранней стадии разработки прошивки и на данный момент используется там просто как текущий уровень. Любопытно то, что если сейчас его увеличить, то условие, описанное в предыдущем пункте, никогда не сработает, то есть 220 вольт на первичную обмотку трансформатора так и не попадут, а значит устройство заряжать аккумулятор не будет. Пичалька.

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

// Время, через которое можно повышать мощность на один уровень, в миллисекундах int powerUpTime = 5000;

То есть между двумя повышениями мощности должно будет пройти как минимум 5000 миллисекунд, за которые напряжение уже может подняться выше powerUpMaxTreshold и тогда повышать мощность будет уже не нужно.

Что касается понижения мощности, то тут вообще всё просто: программа периодически проверяет, а не превышает ли текущее напряжение максимально допустимый уровень, и если превышает - мощность надо снижать:

// Понижение мощности if (voltageX10 > maxVoltageX10)

📎📎📎📎📎📎📎📎📎📎