В наши дни можно утверждать, что телефон перестал быть устройством только для звонков. Он позволяет нам оплачивать покупки, находить правильную дорогу, вызывать такси. Ситуация, в которой у вас садится батарейка, становится одной из самых стрессовых. Остаться ночью на незнакомой улице без телефона довольно неприятно. При этом расход батарейки растет во многом как следствие расширения возможностей.
Производители как железа, так и софта, стараются решить эту проблему. Для Яндекса она тоже актуальна, потому что наши сервисы — это то, что должно быть под рукой у человека в любой момент. Мы по-разному над этим работаем и в рамках эксперимента создали устройство для измерения тока, который потребляется телефоном с батарейки. Теперь мы умеем мерить мгновенные значения тока с батарейки телефона (Nexus, iPhone и др.) в миллиамперах 500 раз в секунду, сохранять эту метрику на диск и считать по ней среднее потребление.
Под катом я расскажу, как у нас это получилось. Будет много фото железок, но заранее прошу прощения за качество — снимки сделаны в боевых условиях.
С самого начала у нас была какая-то тактика
Несколько месяцев назад, когда мы начинали прикручивать нагрузочное тестирование телефонов к Яндекс.Танку (это наш opensource инструмент для тестирования производительности), мы столкнулись с тем, что одну из самых важных метрик — потребление тока с батарейки — мы не можем замерить достоверно, а на некоторых телефонах не можем замерить вообще. Например, вот как выглядит график потребления тока на iPhone, полученный стандартными средствами от Apple:
Все три запуска теста значение потребления вообще не изменялось и было равно 1/20. Удивляет использованная единица измерения — 1/20 означает, что если телефон дальше будет работать с тем же энергопотреблением, то сядет он за 20 часов. То есть, метрика получается очень неточная и не очень интерпретируемая. Кроме того, цифры в сыром виде получить нельзя, только разве что скриншот сделать и приложить его к тикету.
С Android девайсами ситуация выглядит лучше, но все равно далека от идеала. Ток замерять можно, читая из /proc/…
циферку, но лучше не делать это слишком часто — опросом значения можно просадить производительность телефона и испортить тесты. На разных девайсах циферка находится в разных местах файловой системы. На части Android телефонов вообще отсутствует железка, измеряющая ток, поэтому на них не получится программными средствами снимать потребление. На Nexus, которые мы взяли как reference, значение в /proc
меняется раз в 20 секунд.
В общем, мы решили попробовать измерять потребление хардверно и таким образом убить всех зайцев разом: так можно мерить вообще на всех девайсах, включая ноутбуки и холодильники. Мы знали о существовании Power Monitor, но цена устройства (примерно $800 за штуку, а на каждый телефон потребуется свой девайс), и его несовместимость с Linux (а значит, и сложности с автоматизацией), заставили задуматься о своем велосипеде. Аналогичная ситуация наблюдается с осциллографами и другими измерительными устройствами общего назначения на рынке — покупать дорого, автоматизировать сложно.
Существует еще проект BattOr, по описанию это примерно то, что мы хотим. Сам я не пробовал связаться с авторами, но коллеги говорят, что команду купил Google и с тех пор от них ничего не слышно и на почту они не отвечают. Совпадение? =)
Для начала, в качестве proof-of-concept, мы собрали схему с шунтом, аналогичную представленной в этой статье. Ток мы измеряли в разрыве провода USB. Поскольку значение тока ожидалось небольшое, до 500 мА, пришлось усиливать напряжение с помощью инструментального усилителя, а не снимать его напрямую с шунта ардуинкой.
После еще некоторых танцев с бубном нам удалось получить на экране ноутбука график потребления телефоном тока с USB. Тут мы поняли, что таких измерений нам не хватает — мы мерим не ток с батарейки, а ток с USB, телефон запасает энергию в батарейке, и мы не можем сопоставить график потребления тока с тем, что происходит на телефоне. Решили, что нужно вытаскивать батарейку из телефона и использовать вместо нее внешнее питание, а USB во время тестов вообще не втыкать.
Электроника работает на белом дыме
Как известно, все, чему нас учили на уроках физики и электротехники, — ложь, никаких электронов не существует, а устройства работают на белом дыме. И если этот белый дым выходит, то устройство работать перестает. В очередном эксперименте белый дым вышел из Arduino и мы ее потеряли. Оказалось, что между “0” на входе нашего блока питания и “-“ на его выходе — 88 вольт переменного напряжения. После еще нескольких экспериментов с разными БП мы поняли, что не все они одинаково хороши, но есть такие, которые нам подходят. И мы стали использовать эти подходящие. Также мы решили больше не использовать схему с шунтом и инструментальным усилителем и вместо этого взять готовый модуль измерения тока к Arduino на базе MAX471, которая по сути то же самое, только в виде микросхемы. Еще мы рассматривали вариант на базе датчика Холла (ACS712), но, изучив документацию на этот чип, увидели, что он сильно шумит и решили даже не пробовать.
Для того, чтобы питать современный телефон не от встроенной батареи, а от внешнего источника, мало его разобрать и вытащить батарею — уж слишком умны современные батареи. Поэтому мы вытаскиваем из батареи контроллер и подключаемся уже к нему.
Чтобы вернуть модифицированный таким образом iPhone (или другое устройство) в собранное состояние, мы сверлим корпус и выводим два проводка.
Вот такая коробочка у нас получилась в результате. Правда, в метро ее лучше не возить, телефон, провода, вот это все… могут не понять =)
Что нам это дает
Мы уже начали внедрять тестирование наших приложений на энергопотребление, так что ждите улучшений в этой области. Процитирую коллег, которые пользуются нашей коробочкой.
Для получения релевантного результата теста при прямых замерах батарейки этим устройством достаточно пяти минут. Если же замерять «как раньше», то есть смотреть на скорость уменьшения % заряда батареи — то требуется 6-8 часов, плюс не забывайте про человеческий фактор. То есть, время теста сократили с 8 часов до 5 минут: почти в 100 раз.
Текущий разброс результатов замера ± 15%. Это не идеал и надо погрешность уменьшать. Однако, теперь доверие к результату повысилось за счёт исключения человеческого фактора и существенно меньшего времени на 1 замер. Достаточно выполнить за полдня много-много замеров и отсечь результаты, пострадавшие от внезапных всплесков непонятной активности на телефоне.
Стало возможным кросс-платформенное, и кросс-девайсное сравнение значений. Единица измерения — mA, а не «скорость уменьшения процентов заряда», которая зависит от платформы, объёма батареи, «свежести» батареи, не говоря уже про запущенные процессы… Сравнить только mA при одном и том же запущенном Я.Сервисе на Andoird и на iOS — нельзя. Надо добавить поправочный коэффициент — сколько жрёт каждая платформа, без Я.Сервиса. Но, это опять-таки вопрос на пол дня замеров (и это с кофе-поболтать).
Пара слов про софт
Чтобы собирать данные от Arduino (а она просто 500 раз в секунду шлет их по USB), мы написали простенькую читалку. На Python возникли проблемы с повторным открытием устройства на чтение — во второй раз данные уже не читались. Мы не стали разбираться и просто переписали то же самое на Golang — после этого все заработало.
Тут нас ждали еще небольшие грабли: в буфере устройства с предыдущего запуска остаются старые данные. Поэтому сейчас мы просто отбрасываем первые 500 измерений (1 секунда). Затем собранные в .csv данные обрабатываем скриптом на Python (в котором используются Pandas и Seaborn) и получаем графики, которые вы видели в начале статьи.
Если вам интересны исходники читалки, прошивка и код для обработки данных — могу поделиться, пишите в личку.
Автор: Яндекс