| Next revision | Previous revision |
| supervooc [2025/09/17 15:51] – created gadmin | supervooc [2025/09/18 06:55] (current) – gadmin |
|---|
| 123 | ===== Общие принципы работы SuperVOOC ===== |
| | ==== Ток ==== |
| | SuperVOOC отличается от других протоколов зарядки тем, что увеличивает скорость зарядки не за счёт повышения напряжения, а за счёт увеличения тока. Увеличение тока требует качественного кабеля, поэтому SuperVOOC использует собственные кабели со встроенным чипом, который подтвержает телефону и зарядке готовность пропускать большие токи. Компании Oneplus/Oppo/Realme выпустили больше количество версий кабелей, у части имеется маркировка на манжете USB A разъема с указанием допустимого тока, а у других присутствует только ревизия - одна буква или вообще отсутствует маркировка. Несмотря на то, что сейчас прикладываются 10-12A кабели, никто не наблюдал потребление больше 8A. |
| | ==== Напряжение ==== |
| | За счет повышения тока SuperVOOCу не требуется регулятор напряжения, поэтому на выходе зарядки напряжение совпадает с напряжением, которое требуется аккумулятору. |
| | У флагманов была сделана еще одна доработка: двойная батарея, у которой каждая часть может заряжаться независимо, удваивая скорость. За счёт этого на телефон подается буквально удвоенное напряжение. |
| | ==== Используемые инструменты ==== |
| | Для измерения протокола SuperVOOC я использую: |
| | * USB-тестер ChargerLab KM003C. Он умеет определять и пропускать SuperVOOC. Дальше его показания будут считаться объективными данными, снимаемыми с зарядки. Из тестера берется два параметра: |
| | * Ток зарядки |
| | * Напряжение зарядки |
| | * Внутренний лог телефона, который я получаю на десктоп через поднятый по сети adb с помощью команды adb logcat. Из лога можно извлечь несколько категорий записей. |
| | * Записи healthd. Это встроенный в Android менеджер аккумулятора, который логгирует процесс зарядки. Важно, что этот уровень использует низкоуровневый сервис от вендора, поэтому он видит несколько приукрашенную картинку. Например, он получает напряжение, приведенное к одной ячейке, видимо среднее значение от напряжения двух ячеек. В этом логе есть следующие параметры: |
| | * Уровень зарядки l |
| | * напряжение в mv v |
| | * Температура t |
| | * enum с здоровьем аккумулятора (здоров/убит) h |
| | * emum со статусом аккумулятора (заряжается/разряжается) st |
| | * ток аккумулятора как ток потребления - ток зарядки . Отрицательное значение соответствует зарядке. с |
| | * максимальное значение заряженности в микро(!)ампер-часа. На самом деле похоже на константу fc |
| | * число полных циклов зарядки за всё время жизни аккумулятора cc |
| | * однобуквенный статус зарядки (проводная зарядка/usb-порт/беспроводная зарядка) chg |
| | * Записи charge_time от сервиса vendor.oplus.hardware.charger-V7-service. Он знает истинную картину зарядки, разделяет зарядку по фазам SuperVOOC и CDP/DCP (стандартные USB 5V2A), а также ведет двойную бухгалтерию процентов заряженности soc (честный state of charge) и ui_soc (то, что отдается в healthd) и такую же двойную бугалтерию по времени до завершения зарядки (time to full charge): ttf и ui_ttf. |
| | * У сервиса vendor.oplus.hardware.charger-V7-service есть еще записи типа read content, но их содержимое пока не расшифровано |
| | Наличие нескольких источников разной степени доверия приводят к тому, что данные нужно сопоставлять между собой и становятся видны допустимые неточности в замерах и отметках времени. Так, при сопоставлении времен logcat и тестера приходилось сдвигать показания на секунды, после чего оказывалось, что точность отметок плывет. |
| | ==== Общие наблюдения за процессом зарядки ==== |
| | Процесс зарядки можно разделить на нескольк фаз. Начальную фазу, когда идёт согласование протокола можно игнорировать, она длится буквально пару секунд и в логе тип зарядки определяется как cdp/dcp. |
| | Вторая фаза самая важная - это собственно SuperVOOC. Она длится 33-40 минут до примерно 97-98% заряда по ui_soc, что соответствует 95-96% честного soc. |
| | Третья фаза - это опять cdp/dcp на 5V. Это очень сомнительная фаза, потому что в это время пользовательский интерфейс будет писать 100% заряда и продолжать заряжать до написания Full charge. По логам есть три точки "завершения". Лог charge_time перестаёт следить за процессом когда ui_soc достигает 100%. Но зарядка продолжается. Где-то через минуту измененяется статус зарядки с 2 (BATTERY_STATUS_CHARGING) на 5 (BATTERY_STATUS_FULL). А еще через 2.5 минуты статус меняется на 3 (BATTERY_STATUS_DISCHARGING) и вот это уже точно всё. Но все эти события происходят на 40+ минут, что не так красиво как рекламировать 36 минут. |
| | Дальше мы будем говорить только про основную фазу svooc. |
| | ==== Сравнение графиков напряжения ==== |
| | {{:compare_voltage.png?1024|}} |
| | Начнём с изучения графика напряжений. У нас есть напряжение, которое создаёт зарядка и напряжение на контактах аккумуляторной батареи. В логах charge_time нет напряжения, будем брать его из логов healthd. Мы помним, что healthd обманывают, подсовывая ему напряжение в пересчете на одну ячейку из двух. Поэтому кроме графика напряжения зарядки добавим на график еще одну линию: половину напряжения на зарядке.И становится видно, что в фазе svooc зарядное устройство буквально следует за напряжением на аккумуляторе. Это сильно отличается от линейных графиков Power Delivery. В реальности зарядка скорее всего отстаёт от напряжения, но пока непонятно насколько именно. |
| | |
| | Фаза cdp/dcp малоинтересна. Подаём 5 вольт, аккумулятор показывает 4.4-4.5 вольт, причём после ухода с svooc напряжение слегка снижается<del>, потому что аккумулятор перестали пинать</del>. |
| | Переключение фаз выглядит вот так: |
| | <code> |
| | 09:31:57.224 2145 2145 D healthd : system healthd: battery l=98 v=4576 t=34.6 h=2 st=2 c=-1848 fc=5920000 cc=93 chg=a |
| | 09:31:57.407 2145 2145 D healthd : system healthd: battery l=98 v=4574 t=34.5 h=2 st=2 c=-1838 fc=5920000 cc=93 chg=a |
| | 09:31:57.791 2145 2145 D healthd : system healthd: battery l=98 v=4574 t=34.5 h=2 st=2 c=-1417 fc=5920000 cc=93 chg=a |
| | 09:31:57.900 2145 2145 D healthd : system healthd: battery l=98 v=4574 t=34.5 h=2 st=2 c=-1417 fc=5920000 cc=93 chg=a |
| | 09:32:02.529 2145 2145 D healthd : system healthd: battery l=98 v=4483 t=34.5 h=2 st=2 c=0 fc=5920000 cc=93 chg=a |
| | 09:32:07.649 2145 2145 D healthd : system healthd: battery l=98 v=4474 t=34.4 h=2 st=2 c=0 fc=5920000 cc=93 chg=a |
| | 09:32:11.438 2145 2145 D healthd : system healthd: battery l=98 v=4474 t=34.4 h=2 st=2 c=0 fc=5920000 cc=93 chg=a |
| | 09:32:12.774 2145 2145 D healthd : system healthd: battery l=98 v=4467 t=34.4 h=2 st=2 c=-20 fc=5920000 cc=93 chg=a |
| | 09:32:17.891 2145 2145 D healthd : system healthd: battery l=98 v=4491 t=34.4 h=2 st=2 c=-557 fc=5920000 cc=93 chg=a |
| | 09:32:23.008 2145 2145 D healthd : system healthd: battery l=98 v=4491 t=34.3 h=2 st=2 c=-558 fc=5920000 cc=93 chg=a |
| | 09:32:28.128 2145 2145 D healthd : system healthd: battery l=98 v=4491 t=34.3 h=2 st=2 c=-559 fc=5920000 cc=93 chg=a |
| | 09:32:33.256 2145 2145 D healthd : system healthd: battery l=98 v=4490 t=34.3 h=2 st=2 c=-559 fc=5920000 cc=93 chg=a |
| | </code> |
| | Резюмируем: напряжение в фазе svooc просто следует за суммарным напряжением батареи. |
| | ==== Ток зарядки ==== |
| | {{:compare_current.png?1024|}} |
| | Сравнение токов зарядки и аккумулятора осложнено тем, что с аккумулятора снимается ток с учётом тока потребления. И в целом график это подтвержает тем, что графики совпадают с точностью до провалов на аккумуляторе, которые вызваны активностью телефона. |
| | Видна попытка взять 7 ампер, но это длится буквально секунду. Что не сложилось - неизвестно. Температура, наличие тестера на линии или еще что-то. Дальше видно, что протокол долго сидит на 5A и потом снижает ток ступеньками, причём ступеньки в основном равны 1А и немного 0.5А. |
| | Фаза cdp невнятная: берем 1.1-1.2A c зарядки, до аккумулятора доходит 3.5А. Возможно это потери на преобразовании 5V в 4.6V аккумулятора. |
| | ==== State of Charge ==== |
| | Уровень заряженности устройства в процентах - это простая конструкция с точки зрения пользователя, но имеющая свои тонкости под капотом. Скорее всего уровень является нелинейной (или линейной, но по-разному на разных регионах) функцией от напряжения аккумулятора. Лог charge_time вносит еще один уровень косвенности - честный soc и нечестный уровень наружу ui_soc. Разница между ними в reserve_soc=2 на 100%. То есть ui_soc = soc * (100/(100-reserve_soc)). |
| | Если еще вспомнить, что charge_time ориентируется на ui_soc, то смысл вычисления честного soc вообще неясен. Возможно, что после получения 100% в ui_soc проценты зарядки перестают обновляться, но статус BATTERY_STATUS_CHARGING сменяется после достижения 100% в честном soc. Но, поскольку этого нет в логах, это всего лишь гипотеза. Будем считать, что эти 2% увеличивают жизнь аккумулятора. |
| | ==== Time to full charge (ttf) === |
| | Еще один элемент двойной бухгалтерии - это время до полной зарядки, которое существует в двух переменных: честном ttf и "для интерфейсов" ui_ttf. Почему их два можно догадаться: честный ttf может резко меняться, когда зарядка изменяет силу тока, а ui_ttf меняется консервативнее, единичные выбросы сглаживаются. |
| | Вот несколько примеров значений |
| | <code> |
| | # самое начало, до переключения в svooc. |
| | 08:57:52.598 2337 7247 D charge_time: type=cdp/dcp,reserve_soc=2,soc=4,ui_soc=4,current=-226,avg=1100,ttf=9080(02:31:20),ui_ttf=9080(02:31:20) |
| | # только переключились в svooc, оба времени оптимистично уменьшились |
| | 08:57:54.599 2337 7247 D charge_time: type=svooc,reserve_soc=2,soc=4,ui_soc=4,current=-330,avg=2000,ttf=4648(01:17:28),ui_ttf=4648(01:17:28) |
| | # а вот участок, на котором видно, что честное ttf снизилось до реальных значений, а ui_ttf продолжает считать по-старому |
| | 08:58:35.647 2337 7247 D charge_time: type=svooc,reserve_soc=2,soc=5,ui_soc=5,current=5078,avg=2522,ttf=3690(01:01:30),ui_ttf=4886(01:21:26) |
| | 08:58:36.647 2337 7247 D charge_time: type=svooc,reserve_soc=2,soc=5,ui_soc=5,current=5078,avg=3164,ttf=3017(00:50:17),ui_ttf=4885(01:21:25) |
| | 08:58:37.648 2337 7247 D charge_time: type=svooc,reserve_soc=2,soc=5,ui_soc=5,current=5078,avg=3802,ttf=2616(00:43:36),ui_ttf=4884(01:21:24) |
| | 08:58:38.649 2337 7247 D charge_time: type=svooc,reserve_soc=2,soc=5,ui_soc=5,current=6916,avg=4807,ttf=2253(00:37:33),ui_ttf=4883(01:21:23) |
| | # и только через пару минут значения выравниваются |
| | 09:00:14.754 2337 7247 D charge_time: type=svooc,reserve_soc=2,soc=10,ui_soc=10,current=4889,avg=4875,ttf=2128(00:35:28),ui_ttf=2128(00:35:28) |
| | # и последний пример, где в завершающей фазе честный ttf начинает выдавать пессимистичные значения, |
| | # а ui_ttf продолжает считать по-старому. В результате ui_ttf накидывает только 3 минуты, вместо десяти |
| | 09:33:48.634 2337 7247 D charge_time: type=cdp/dcp,reserve_soc=2,soc=96,ui_soc=98,current=140,avg=224,ttf=792(00:13:12),ui_ttf=213(00:03:33) |
| | 09:33:49.635 2337 7247 D charge_time: type=cdp/dcp,reserve_soc=2,soc=96,ui_soc=98,current=140,avg=140,ttf=1327(00:22:07),ui_ttf=212(00:03:32) |
| | 09:33:50.635 2337 7247 D charge_time: type=cdp/dcp,reserve_soc=2,soc=96,ui_soc=98,current=211,avg=154,ttf=1196(00:19:56),ui_ttf=211(00:03:31) |
| | </code> |
| | |