Делаем умный зарядник для машины на коленке

Введение

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

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

Краткий ликбез

Современные электромобили умеют заряжаться двумя способами — переменным и постоянным током. Делают они это посредством разъёма под названием CCS2 (Combined Charging Socket v2), который выглядит как-то так:

ee924ac6ac73db4996d53adff4ef712b.png

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

Переменным током можно заряжаться мощностью до 22кВт (3 фазы по 32А), но по факту, как мне кажется, большинство машин ограничены 11кВт (16А). Теоретически через Type2, вроде как, даже 50кВт возможно пропихнуть, но я таких зарядок не видел.

С одной фазы можно получить 7кВт (32А), но для этого нужна хорошая линия питания. Поэтому обычные зарядники для розеток, обычно, ограничены 3кВт (16А) — именно такой мы и будем делать.

Постоянным же током через CCS2 можно получать до половины мегаватта (1000В и 500А), но, конечно же, в реальности всё грустнее. По сути эта мощность ограничена ёмкостью батареи, так как литий не очень любит зарядку сильно быстрее чем его ёмкость. Например, для батареи ёмкостью 80кВт*ч мощность заряда, в среднем, не должна превышать 1.2–1.5 от ёмкости, т.е. около 100–120кВт. Охлаждением этот порог можно поднять, что электромобили и делают — при зарядке через батарею прокачивается антифриз и охлаждает её. Или нагревает, в зависимости от погоды.

По факту, у легковых машин потолок мощности зарядки 250 кВт, а чаще всего сильно меньше — от 80 до 170 кВт (в зависимости от ёмкости батареи). И мощность такую они могут развивать в очень небольшом диапазоне уровня заряда батареи, например с 10% до 40%, и то при условии что батарея находится в хорошем состоянии и имеет нужную температуру — литий не любит заряжаться в мороз.

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

IEC 62196–2 Type 2

Собственно так называется вилка, вставляемая в верхнюю часть CCS2.

d758b02d4dbaf7d772b15c72245a704f.png

В ней 7 контактов:

  • Фазы 1, 2, 3 (может быть, как на фото выше, только одна фаза)

  • Ноль

  • Земля

  • PP — Proximity Pilot, позволяющий машине понимать что в неё что-то воткнули. По факту там просто резистор на землю, показывающий какой ток этот кабель может прожевать. Для 16А кабелей он равен 680 Ом, что означает ток в 20А.

  • CP — Control Pilot, позволяющий машине и заряднику договориться о том как и когда заряжаться. Он-то и самый интересный.

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

Открою маленький секрет — зарядники переменным током Type2 они никакие не зарядники вообще. Это просто коробка с реле, парой микросхем и защитных систем.

Сам зарядник, который преобразовывает переменный ток в постоянный, нужный для зарядки батареи, находится в машине. В этом отличие от зарядки постоянным током через CCS2, где зарядник находится снаружи, а машина им управляет через провод по протоколу PLC (Powerline Communication), такому же как Ethernet через розетку — умельцы используют такие адаптеры для эмуляции CCS2. Но это тема для другой статьи.

По сути Type2 и подобные им зарядники просто договариваются с машиной о максимальном токе, который они могут/хотят отдать, проводят некоторые проверки и подключают машину к сети 220В/380В, а дальше всё происходит уже внутри электромобиля.

Безопасность

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

  • Ground Fault Current Interrupter: по сути это УЗО, как ставятся в квартирах. Он смотрит, чтобы ток из цепи никуда не утекал (например в вас) и отключает реле если видит утечку более 10–30 мА.

    Реализуется трансформатором тока (ферритовое колечко с обмоткой), надетым на фазу (или фазы) и ноль. Если есть утечка — на трансформаторе появится напряжение, ей пропорциональное.

  • Ground Check: на PE (Protected Earth) проводник подаётся напряжение и проверяется что ток уходит в заземление. Если не уходит — значит заземления у нас нет и всё плохо.

  • Залипшее реле: на случай если контакты в реле приварились и не отключаются, зарядник проверяет наличие питания после открытия реле.

  • Diode Check: в машине между линиями CP и PE находится диод и пара резисторов. Смысл диода в том, чтобы зарядник ошибочно не решил что его воткнули в машину, если между CP и землёй вдруг появится подходящее сопротивление. Об этом чуть подробнее дальше.

В нашем дендрофекальном заряднике мы реализуем лишь проверку диода. УЗО у меня стоит перед ним и так, да и заземление в наличии работающее.

SAE J1772

Так называется механизм (протокол?), по которому машина общается с зарядником. Чтобы подробно его понять, можно посмотреть отличную презентацию от проекта OpenEVSE. Статья в вики тоже достаточно подробна.

Если кратко, то работает это всё следующим образом.

Зарядник

Он генерирует ШИМ-сигнал в диапазоне от -12В до +12В между линиями CP и PE (Protected Earth, земля). Скважность (duty cycle) этого сигнала сообщает машине максимальный ток, который зарядник может в данный момент ей предоставить.

Машина обязана реагировать на изменение максимально доступного тока и изменять своё потребление соответственно. По моим тестам это происходит практически мгновенно.

Это полезно, например, на публичных или больших частных зарядках (в общих гаражах жилых домов), где на всех доступно только Х киловатт. Система, управляющая зарядниками, будет распределять энергию поровну между машинами. Если потребление не превышает порог, то все будут получать полный ток. А если оно выше, чем мощность ввода — то зарядники снизят разрешённый ток, чтобы не допустить перегрузки и выбивания вводного автомата.

Минимально возможный ток по стандарту — 6А, что, как по мне, довольно много. Почему не сделали меньше — загадка. Тем, кто заряжают свои машины солнцем, приходится вообще отключать заряд, если солнечные батареи не могут хотя бы 6А обеспечить.

Максимальный — 80А. В диапазоне от 6 до 51А скважность ШИМ вычисляется по простой формуле (амперы / 0.6), т.е. для минимального тока 6А скважность будет 10%.

Вот хорошая табличка из уже упомянутой презентации:

e219e9458bf37ac22ddecec5b891602e.png

Если зарядник не готов на данный момент заряжать машину, он должен выключить ШИМ и подавать на пин CP постоянное напряжение +12В. Это, в общем-то, эквивалентно скважности 100%. Таким образом можно включать и выключать зарядку в любое время.

Машина

Машина же, в свою очередь, вешает между линиями CP и PE диод и резисторы, снижая максимальное напряжение ШИМ с +12В до +9/6/3В в зависимости от того, что она хочет от зарядника.

Диод нужен чтобы минимальное напряжение оставалось -12В — это показывает заряднику, что это действительно машину подключили, а не просто водичка затекла в вилку и, совершенно случайно, создала сопротивление нужное. Полупроводниковая вода, вроде бы, ещё не изобретена…

Состояния, кодируемые резисторами, можно видеть в таблице ниже:

1ceeb5e733998e6ab9fab6e3de55d316.png

Состояние D достаточно интересное — оно требует от зарядника подавать питание только в том случае, если он установлен в вентилируемом месте (на улице, например). Думается, что этот режим используется если машина видит, что зарядный инвертор в ней перегревается. Мы будем считать что состояние D равно состоянию C.

В итоге, если смотреть осциллографом, «диалог» машины и зарядника выглядит следующим образом:

5e393f9475fca030bd5196dd30b444ac.png

Таким образом, для того чтобы реализовать этот протокол нам нужно уметь:

  • Генерировать ШИМ с диапазоном +/- 12В

  • Уметь измерять как минимальное, так и максимальное напряжение на линии CP за определённый период (несколько миллисекунд)

Цель

А вообще, зачем нам делать свой зарядник? На рынке полно вполне качественных устройств ценой в районе $100, которые отлично работают.

У меня были следующие цели:

  • Управление по Wi-Fi

  • Включение и выключение зарядки в нужное время. Электричество дешевле ночью. И хотя, обычно, в самой машине можно задать расписание — делать это централизованно удобнее. Плюс, у меня механический (!) двухтарифный счётчик, которому уже 30 лет и про летнее и зимнее время он не знает. Поэтому расписание нужно менять после перевода часов.

  • Зарядка до определённого уровня. В моей машине нет возможности ограничить максимальный % заряда, до которого она заряжается — всегда пытается набрать 100%.

    А т.к. эта машина используется только для локальных поездок до 80–100 км (для дальних есть другая с ДВС) — заряжать её до 100% смысла нет, это только больше деградирует батарею. Да, я знаю что 100% это на самом деле не 100% с точки зрения литиевых ячеек, скорее около 96% (у батарей электромобилей есть брутто и нетто ёмкость), но всё же.

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

  • Возможность динамического задания тока зарядки с нужной точностью

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

  • Интеграция с Home Assistant

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

Ну и это просто интересно :)

Поехали

Так как сборка дендрофекальная, я буду максимально использовать то, что есть в наличии.

Итак, нам нужно примерно следующее:

  • Кабель для подключения машины с разъёмом Type2.

    Изначально я хотел купить отдельно разъём и собрать его сам, но найти кабель с 3+1 жилами (3 силовых и 1 сигнальная) было крайне сложно. Поэтому был заказана готовая сборка длиной 8 м и ценой около 80$, что составляет львиную долю всего девайса :)

  • Микроконтроллер для управления всем этим балаганом.

    Я взял ESP32 S3 Mini, который был в наличии. В принципе, подойдёт всё что угодно, но ESP32 по соотношению цены и качества вне конкуренции.

  • Два реле, умеющих коммутировать 30–40А, чтобы с запасом. В принципе, если точно известно где фаза, можно обойтись и одним реле, но обычно принято рубить оба проводника.

    У меня были китайские NT90RNAE5CB, с питанием обмотки 5В.

  • Что-нибудь для измерения тока и напряжения.

    Можно, конечно, сгородить что-нибудь своё, но у меня был модуль PZEM-004T, который очень удобно измеряет всё что нужно (и даже больше) и отдаёт результаты через последовательный порт (по протоколу Modbus).

  • Преобразователь питания AC/DC из 220В в что-нибудь вроде +5/+12В (зависит от выбранных реле)

  • Что-нибудь, генерирующее отрицательное напряжение -12В. Это может делать как AC/DC преобразователь, так и отдельный DC/DC.

    Изначально я взял красивый RAC10–12DK/277, который из 220В делает +12В и -12В, но в процессе экспериментов я его спалил :)

    Ждать приезда нового было лень, поэтому я взял китайский AC/DC Hilink HLK-PM01, который выдаёт +5В и какой-то копеечный step-up DC/DC который выдаёт +/- 12В

  • Экран OLED 128×128 ну или любой другой.

    Нужен для вывода всякой полезной и не очень информации. У меня был вот такой, с управлением по SPI. Можно переключить и в I2C — меньше проводов тянуть.

  • Кнопка, желательно в IP6x исполнении, для настройки тока и включения зарядки.

  • Корпус. Я взял распределительную коробку 15×6х9 см с прозрачной крышкой, чтобы было видно экран.

  • Ну и всякая рассыпуха: провода, резисторы, пара транзисторов для управления реле и TVS диод (см. схему ниже)

Также нам нужен способ делать из ШИМ, генерируемого ESP32 в диапазоне 0/3.3В, ШИМ с диапазоном -12/+12В. В идеале, для этого нам нужен rail-to-rail компаратор, например TI TLV1811

Эталонная схема реализации J1772 на нём выглядит так:

4c47dc999315dab366b44e400cf92817.png

Компаратор это такой if-else логический блок: он сравнивает напряжение на вводах +/- и, в зависимости от того, какое больше — подаёт на выход либо +12 либо -12. На схеме выше на ввод (-) мы подаём 3.3В через делитель из двух 100к резисторов, который выдаёт 1.8В. А на ввод (+) мы подаём ШИМ-сигнал с ноги ESP32.

Таким образом, когда ШИМ находится на высоком уровне 3.3В > 1.8В, компаратор выдаёт +12В на выходной контакт, а когда на низком 0В < 1.8В, то он выдаёт -12В. Вуаля!

Остальные элементы на схеме нужны для измерения уровня напряжения — ещё один делитель на резисторах 200k/66.5k для понижения напряжения с 12В до 3В, которые мы можем измерить используя ADC ESP32. Через резистор 56к он подтянут к 3.3В чтобы убрать отрицательное напряжение (voltage/level shift), которое ESP32 измерять не умеет.

Ещё есть TVS-диод, который нужен чтобы защищать цепь от возможных скачков напряжения на линии CP. Я использовал P6KE16CA с напряжением срабатывания 13.6В, у него нет полярности и подключать можно как угодно. Судя по даташиту он может рассеять до 800Вт энергии коротким пиком.

Сборка

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

Проблема в том, что они не rail-to-rail и напряжение на выходе при подаче +12.5В (которые выдавал мой DC/DC) падает до 11В, при этом на отрицательной линии всё более-менее нормально.

По стандарту J1772 напряжение может быть в диапазоне от 11.6 до 12.6 или около того. В итоге моя машина просто отказывалась воспринимать зарядник и выдавала ошибку. Пришлось достать из закромов ещё один регулируемый DC/DC step-up и выставить на нём около 13.5 вольт, что дало нужные 12.2В на выходе LM358.

Больше колхоза!

Плата питания

Собирать будем на двух макетных платах — делать разводку и ждать производства мне было лень, тем более элементов, вроде бы, не много.

На одну плату поместим высоковольтную часть:

  • Релюхи

  • AC/DC

  • DC/DC

Получится что-то вроде такого монстра Франкенштейна:

b844932e1f9976940178774af72a1c2e.jpg

Слева 3.3v регулятор TSR1–2433, он в принципе не обязателен т.к. ESP32 уже имеет его на борту, но т.к. он был — я решил чтобы был небольшой запас по току. Ибо нам нужно к 3.3в подтягивать ADC преобразователь и компаратор. Скорее всего можно обойтись без него.

Красный это +/- 12В DC/DC, от которого используется только +12, справа регулируемый DC/DC который даёт 13.5В (выше я писал почему). Сверху два реле и AC/DC на 5В.

Реле

Схема управления реле предельно простая:

6f95b3084b02f15b57e694c5b1d5cc79.png

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

Разве что может ещё стоит дополнительно притянуть ноги ESP32, управляющие реле, к земле через 10к резистор — чтобы при включении и перезагрузке контроллера реле не срабатывали.

Также некоторые ноги ESP32 могут при перезагрузке на несколько миллисекунд уходить в высокий уровень, что будет опять же вызывать срабатывание реле. Это плохо потому, что если у вас машина заряжается или просто подключена к заряднику, а вы его перезагружаете, срабатывает реле, в машину без предупреждения идёт 220В — ей может это не понравится. Плюс, у меня ещё и УЗО иногда выбивало при этом из-за каких-то переходных процессов.

Путём научного перебора на ESP32 S3 мне подошли ноги 37/38.

Далее собираем низковольтную часть (ESP32, драйверы реле, компаратор и прочая мелочь) на другой плате, получится что-то такое уродливое:

46ca3be76fa332693f32d11396af0185.jpg

Сюда же, к каким-нибудь свободным ногам ESP32, припаиваем шлейф для экрана (SPI и питание), провода к кнопке, и шлейф, идущий к PZEM-004T, для считывания показаний тока и напряжения.

Так как у ESP32 программируемая коммутационная GPIO матрица, то использовать можно практически любые пины для чего угодно. Есть некоторые ограничения, как те же вышеупомянутые нестабильные ноги при перезагрузке. Плюс, при использовании Wi-Fi доступен только ADC1, на ESP32-S3 это пины с 1 по 10. Вообще есть такой вот хороший мануал по ногам ESP32-S3.

Готовим корпус, сверлим отверстия для водонепроницаемых кабельных вводов и проверяем как провода будут заходить. Тут используются провода в 2.5 мм^2, для 16А это подходящая толщина — 1.5 квадрата уже неплохо греются на таком токе.

bb9fcc564b9d7e468e6486ff25cb84d5.jpg

Монтируем PZEM-004T:

e0620bccf38a28653739547127d00d72.jpeg

Так как это дендрофекальная сборка, то обязательно большое количество термоклея!

Поверх неё монтируем плату питания:

904d42453ac1fe310c60f2a4e0904bf4.jpg

Силовые провода припаиваем к ней снизу, а также одеваем кольцо трансформатора тока от PZEM-004T на один из силовых проводов чтобы измерять ток (сфоткать всё это дело забыл).

Рядом ставим плату с логикой и подключаем её шлейфом (по нему идёт +3.3/+12/-12/земля и два контакта к реле). К ней же припаиваем вывод CP от автомобильного кабеля, по которому и будет идти сигнализация J1772:

19e8291d4fb1aa3d90b8721aaf7dc3af.jpg

Приклеиваем к крышке экран, сверлим отверстие для кнопки и устанавливаем её. По короткому нажатию переключается максимальный ток, по длинному — включается и выключается зарядка.

Чудо-девайс готов!

4c9a3bd9990039056e9f11604eecd56d.jpeg

Софт

Можно было, конечно, написать прошивку на чистом ESP-IDF или Arduino Framework, но так как я ленивый и мне хочется иметь простую интеграцию с Home Assistant — я буду использовать такой прекрасный проект как ESPHome. Он имеет кучу драйверов для разной периферии и подключается к HA по нативному протоколу безо всяких MQTT и прочего.

Для разработки state machine и эмуляции автомобиля я использовал чудо-приблуду, состоящую из диода, резисторов и тумблера. Тумблер позволяет переводить «машину» из состояния «воткнута» (State B) в состояние «хочу заряжаться» (State C/D) путём подключения резистора 1.3k параллельно с 2.74k.

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

Также в процессе выяснилось, что модуль ADC в ESPHome хоть и умеет семплировать измерения, но алгоритм там только один — усреднение. А нам нужно знать максимальное и минимальное напряжение за период, поэтому пришлось добавить эту возможность в сенсор ADC.

Ещё из интересных проблем: формула вычисления скважности в зависимости от тока почему-то потребовала прибавления 3 ампер.

По стандарту, если мы хотим заряжать током 6А, то скважность должна быть 10% (6/0.6=10). Но, почему-то, мне пришлось к силе тока прибавить 3, чтобы получить нужную величину — т.е. формула становится (x+3)/0.6. Возможно я где-то накосячил в схемотехнике, или ШИМ в ESP32 какой-то не такой, осциллографа под рукой не было чтобы глянуть.

YAML для прошивки ESPHome я залил на гитхаб: https://github.com/blind-oracle/esphome-evse

Небольшое видео с примером работы UI:

Заключение

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

Главное, если сами решите собрать что-либо подобное — это безопасность. Не забывайте про УЗО и заземление.

© Habrahabr.ru