Когда вы создаете проект промышленной установки, робота, дистанционно управляемой модели ровера или аналогичный проект с микрокомпьютером, встает задача контроля состояния систем электропитания. Вам нужно проверять напряжение на аккумуляторах, потребляемый ток и мощность. Не исключено, что в проекте есть не одна, а несколько цепей, где нужно обеспечить подобный контроль.
Результаты контроля можно передавать, например, на пульт управления или использовать как‑то еще. Когда заряд аккумуляторов подходит к концу, можно отключить какие‑нибудь устройства с целью экономии энергии или инициировать зарядку аккумуляторов вашего устройства. Если в устройстве есть сервоприводы, можно контролировать потребляемую ими мощность, а при перегрузке отключать все сервоприводы или некоторые из них.
В этой статье мы расскажем об использовании для контроля напряжения, тока и мощности недорогого модуля GY-219 с интерфейсом I2C и чипом INA219. Вы сможете подключить его практически к любому микрокомпьютеру, где есть такой интерфейс.
В статье будет описано подключение GY-219 к отечественному микрокомпьютеру Repka Pi (все так же будет работать и с Raspberry Pi).
Оглавление
Возможности и устройство чипа INA219
Модуль INA219 может измерять напряжение питания и напряжение на нагрузке до 26 В, а ток, проходящий через нагрузку, до 3.2 А. Также он измеряет мощность как произведение тока, проходящего через нагрузку, на напряжение, подведенное к нагрузке.
Для измерения тока на плате модуля GY-219 установлен шунтирующий резистор с сопротивлением 0.1 Ом и допустимой мощностью рассеивания 2 Вт. В состав чипа INA219 входит 12-разрядный аналого‑цифровой преобразователь АЦП (ADC). Для питания модуля GY-219 можно использовать напряжение в диапазоне 3–5 В. При этом потребляемый модулем ток не превышает 1 mA.
Что касается точности измерений, то модуль на базе чипа INA219A измеряет ток и напряжение с точностью 0.5–1%, а модуль на базе INA219B — с точностью 0.2–0.5%. Подробную информацию о чипе INA219 вы найдете в даташите.
В INA219 имеется возможность усреднения результатов измерений путем выполнения серии измерений (до 128) с последующим нахождением среднего значения. Такой режим может быть полезен при наличии шумов в измеряемом напряжении. При усреднении измерения будут отнимать больше времени, однако точность результата возрастет за счет усреднения.
Схема чипа INA219 представлена на рис.1.
Для измерения тока и напряжения в чипе используются входы VIN+ и VIN‑.
Входы программируемого усилителя (Programmable Gain Amplifier, PGA) с помощью коммутатора могут подключаться двумя разными способами:
оба входа подключаются к VIN+ и VIN‑;
один вход подключается к VIN‑, а другой — к земле GND
Первый способ нужен для измерения тока. Предполагается, что между VIN+ и VIN‑ включен шунт и через него идет измеряемый ток. Второй способ применяется для измерения напряжения.
Выход PGA подключен ко входу аналого‑цифрового преобразователя ADC. Результаты измерений из ADC записываются в регистры тока Current Register и напряжения Voltage Register. Что касается регистра мощности Power Register, то чип INA219 автоматически записывает в него произведение измеренного тока и напряжения.
Для чтения регистров используется интерфейс I2C. При этом с помощью входов A0 и A1 можно изменять адрес устройства на шине I2C. По умолчанию этот адрес равен 0×40 (шестнадцатеричное значение).
На рис.2 показан модуль GY-219, созданный на базе чипа INA219A и снабженный шунтом на 0.1 Ом мощностью 2 Вт.
Контакты VIN‑ и VIN+, показанные на этом рисунке, предназначены для измерения силы тока. В комплекте с модулем идет разъем с клеммами, а также гребенка. Контакты VIN‑ и VIN+ выведены как на разъем, так и на одноименные контакты гребенки.
Контакт VCC предназначен для подачи питающего напряжения, которое, как мы уже говорили, должно находиться в пределах от 3 В до 5 В.
Контакт GND должен быть соединен с землей микроконтроллера, а также с землей контура, в котором происходит измерение тока, напряжения и мощности. При подключении нужно следить за тем, чтобы через землю микроконтроллера не шел ток контура, который может быть довольно большим.
Что касается контактов SCL и SDA, то они предназначены для подключения к шине I2C.
Перемычки A0 и A1 позволяют изменить адрес чипа INA219 на шине I2C, который по умолчанию равен 0×40. Устанавливая перемычки, можно задать следующие адреса:
0×40 (перемычки не установлены);
0×41 (перемычка A0);
0×44 (перемычка A1);
0×45 (перемычки A0 и A1)
Таким образом вы можете подключить к шине I2C до четырех устройств GY-219.
В тех случаях, когда к шине I2C подключены другие устройства с адресом 0×40 (например, Robointellect Controller 001), нужно либо изменить адреса этих устройств, либо изменить адрес чипа INA219, установив соответствующие перемычки.
На рис.3 мы показали схему измерения напряжения, тока и потребляемой мощности.
Контакт VIN+ подключается к положительному полюсу источника питания, а контакт VIN‑ — к положительному входу нагрузки (на рис. 3 — это электродвигатель). При этом общий провод питания необходимо подключить к земле GND микроконтроллера так, чтобы большой ток нагрузки не проходил через контакты микроконтроллера.
Для измерения тока нагрузки чип INA219 измеряет падение напряжения на шунте. Кроме этого, измеряется напряжение на нагрузке. Зная напряжение на нагрузке и ток нагрузки, чип INA219 вычисляет потребляемую мощность и сохраняет ее во внутреннем регистре, доступном для чтения через шину I2C.
Собираем макет для экспериментов
Для первых экспериментов с модулем GY-219 соберите макет, показанный на рис.4.
С помощью этого макета мы будем измерять ток, напряжение и мощность, потребляемые светодиодом, подключенным к напряжению 5 В микрокомпьютера через резистор 1 кОм.
Выводы GND и VCC 5V модуля GY-219 подсоедините, соответственно, к земле и контакту +5 В микрокомпьютера Repka Pi.
Выводы SDA и SCL модуля GY-219 нужно подключить к физическим контактам 3 и 5 микрокомпьютера Repka Pi.
Контакт VIN+ модуля GY-219 подключите к контакту 4 микрокомпьютера Repka Pi — там есть напряжение 5 В.
Контакт «+» светодиода с последовательно включенным резистором 1 кОм нужно подключить к контакту VIN‑ модуля GY-219 и к земле Repka Pi.
На рис.5 приведено назначение контактов (распиновки), при этом в Repka Pi нужно установить пятую распиновку. Как видно из этого рисунка, напряжение +5 В выведено на физические контакты 2 и 4, а земля — на физические контакты 9, 14, 20, 25, 30, 34 и 39. При этом на контакты 1 и 17 выведено напряжение 3.3 В, что тоже можно использовать для наших экспериментов с измерением напряжения, тока и мощности.
Для установки пятой распиновки запустите команду:
# repka-config
Далее нажмите клавишу Enter и выберите пункт меню Настройка производительности и распиновки (3 Frequency / Pinout Options). Далее выберите вариант 5 (рис.6).
После перезагрузки можно приступить к подготовке программного обеспечения (ПО).
Устанавливаем необходимое ПО
Для INA219 есть несколько пакетов Python, позволяющих получить данные из регистров этого чипа. Мы расскажем о библиотеке pi‑ina219, которую можно использовать на микрокомпьютерах Raspberry Pi и BeagleBone Black, а также после небольшой доработки, которую мы и рассмотрим — на отечественном микрокомпьютере Repka Pi.
С помощью этой библиотеки можно измерять напряжение на нагрузке и протекающий через нее ток, напряжение на шунте, а также мощность, потребляемую нагрузкой. Библиотека получает данные от чипа и конфигурирует его через шину I2C.
Для увеличения точности измерений в библиотеке pi‑ina219 предусмотрена ручная и автоматическая настройка режима программируемого усилителя PGA, а также автоматическая установка регистра калибровки.
Просматриваем шины и адреса I2C
Перед началом испытаний нужно убедиться, что на шине I2C виден адрес чипа INA219, установленного в модуле GY-219. Для этого обновите ОС и установите пакет i2c‑tools:
# apt update
# apt upgrade
# apt install i2c-tools
Затем с помощью программы i2cdetect просмотрите список шин I2C:
# i2cdetect -l
i2c-1 i2c mv64xxx_i2c adapter I2C adapter
i2c-2 i2c mv64xxx_i2c adapter I2C adapter
i2c-0 i2c DesignWare HDMI I2C adapter
Здесь обнаружены шины с номерами 0, 1 и 2. В Repka OS для подключения через контакты GPIO используется шина с номером 1. Выведите на консоль адреса устройств, подключенных к этой шине:
# i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Если все подключения выполнены правильно, вы должны увидеть устройство с адресом 0×40 — это и есть адрес чипа INA219 по умолчанию на шине I2C. Здесь предполагается, что вы не устанавливали перемычки на модуле GY-219 для изменения адреса.
Устанавливаем Python и pip3
Убедитесь, что у вас установлен Python версии 3, а также программа pip3:
# python3 --version
# pip3 –version
При необходимости установите Python версии 3 и pip3:
# apt install python3
# apt install python3-pip
Устанавливаем библиотеки pi-ina219
Как мы уже говорили, для получения данных от модуля GY-219 с чипом INA219 мы будем использовать библиотеку pi‑ina219. Эта библиотека, работоспособная на микрокомпьютерах Raspberry Pi и BeagleBone Black, устанавливается очень просто:
# pip3 install pi-ina219
Если вы устанавливаете библиотеку на отечественном микрокомпьютере Repka Pi, то после установки библиотеки нужно внести в ее код некоторые изменения.
Посмотрите исходный код функции platform_detect, определённой в файле /usr/local/lib/python3.8/dist‑packages/Adafruit_GPIO /Platform.py. Вы увидите, что при запуске на неизвестной для библиотеки платформе эта функция возвращает значение UNKNOWN.
Для обмена с модулем GY-219 по шине I2C библиотека pi‑ina219 использует библиотеку I2C, определенную в файле /usr/local/lib/python3.8/dist‑packages/Adafruit_GPIO/I2C.py.
Функция get_default_bus библиотеки I2C возвращает номер шины по умолчанию, который зависит от типа микрокомпьютера. Для Raspberry Pi в зависимости от версии платформы это значение равно 0 или 1, а для BeagleBone Black — равно 1.
Чтобы использовать библиотеку pi‑ina219 на Repka Pi, отредактируйте функцию get_default_bus таким образом, чтобы при неизвестном типе микрокомпьютера она возвращала значение 1:
def get_default_bus():
"""Return the default bus number based on the device platform. For a
Raspberry Pi either bus 0 or 1 (based on the Pi revision) will be returned.
For a Beaglebone Black the first user accessible bus, 1, will be returned.
"""
plat = Platform.platform_detect()
if plat == Platform.RASPBERRY_PI:
if Platform.pi_revision() == 1:
# Revision 1 Pi uses I2C bus 0.
return 0
else:
# Revision 2 Pi uses I2C bus 1.
return 1
elif plat == Platform.BEAGLEBONE_BLACK:
# Beaglebone Black has multiple I2C buses, default to 1 (P9_19 and P9_20).
return 1
else:
return 1
# raise RuntimeError('Could not determine default I2C bus for platform.')
Другой, более правильный, но и более сложный вариант — изменить упомянутую функцию platform_detect таким образом, чтобы она могла распознавать микрокомпьютер Repka Pi. Нужно также будет внести изменения в функцию get_default_bus, чтобы для Repka Pi она возвращала значение, равное единице.
Запускаем программу example.py
В состав репозитория библиотеки pi-ina219 входит программа example.py (листинг 1).
Листинг 1. Программа https://raw.githubusercontent.com/chrisb2/pi_ina219/master/example.py
#!/usr/bin/env python
import logging
from ina219 import INA219
SHUNT_OHMS = 0.1
MAX_EXPECTED_AMPS = 0.2
def read():
ina = INA219(SHUNT_OHMS, MAX_EXPECTED_AMPS, log_level=logging.INFO)
ina.configure(ina.RANGE_16V, ina.GAIN_AUTO)
print("Bus Voltage : %.3f V" % ina.voltage())
print("Bus Current : %.3f mA" % ina.current())
print("Supply Voltage : %.3f V" % ina.supply_voltage())
print("Shunt voltage : %.3f mV" % ina.shunt_voltage())
print("Power : %.3f mW" % ina.power())
if name == "main":
read()
Программа создает объект ina класса INA219, передавая конструктору значение сопротивления шунта (0.1 Ом), величину максимально ожидаемого тока (в данном случае 200 mA), а также уровень отладки log_level.
Далее программа с помощью функции configure устанавливает максимально возможное измеряемое напряжение, равное 16 В, а также режим автоматического выбора усиления ina.GAIN_AUTO для программируемого усилителя PGA. Данный режим исключит переполнение регистров и обеспечит точность измерений в автоматическом режиме.
После выполнения конфигурирования программа вызывает пять функций:
voltage — напряжение на нагрузке Bus Voltage;
current — ток в нагрузке Bus Current;
supply_voltage — напряжение источника питания Supply Voltage;
shunt_voltage — напряжение на шунте Shunt voltage;
power — потребляемая мощность Power
Полученные этими функциями данные, а также отладочная информация выводятся на консоль:
# python3 example.py
2023-09-11 13:58:45,812 - INFO - INA219 gain set to 0.04V
2023-09-11 13:58:45,812 - INFO - INA219 calibrate called with: bus max volts: 16V, max shunt volts: 0.04V, max expected amps: 0.200A
2023-09-11 13:58:45,813 - INFO - INA219 max possible current: 0.400A
2023-09-11 13:58:45,813 - INFO - INA219 max expected current: 0.200A
2023-09-11 13:58:45,813 - INFO - INA219 current LSB: 6.250e-06 A/bit
2023-09-11 13:58:45,814 - INFO - INA219 power LSB: 1.250e-04 W/bit
2023-09-11 13:58:45,814 - INFO - INA219 max current before overflow: 0.2048A
2023-09-11 13:58:45,814 - INFO - INA219 max shunt voltage before overflow: 20.4800mV
2023-09-11 13:58:45,814 - INFO - INA219 calibration: 0xfffe (65534)
Bus Voltage : 3.284 V
Bus Current : 1.900 mA
Supply Voltage : 3.284 V
Shunt voltage : 0.180 mV
Power : 6.125 mW
Здесь приведены результаты измерений на макете, собранном согласно рис. 4 и рис.7.
В этой схеме на светодиод через резистор подается напряжение 3.284 В от соответствующего контакта микрокомпьютера. При этом через светодиод и резистор проходит ток 1.0 мА, а потребляемая мощность составляет 6.125 мВт.
Потери напряжения на шунте очень малы — 0.18 мВ, и в данном случае ими можно пренебречь.
Заметим, что представленная в листинге 1 программа использует параметры по умолчанию. При этом она учитывает, что сопротивление шунта равно 0.1 Ом, что позволяет измерять токи до 3.2 А. При этом что чип INA219 позволяет измерять напряжение до 26 В.
Настраиваем конфигурацию INA219
Чип INA219 содержит регистры для конфигурирования, которыми удобно управлять с помощью библиотеки pi‑ina219.
Прежде всего, конфигурация задается в параметрах конструктора класса INA219. В листинге 1 указаны такие параметры:
SHUNT_OHMS = 0.1
MAX_EXPECTED_AMPS = 0.2
…
ina = INA219(SHUNT_OHMS, MAX_EXPECTED_AMPS, log_level=logging.INFO)
Кроме этого, конфигурацию можно измерять с помощью специально предназначенной для этого функции:
ina.configure(ina.RANGE_16V, ina.GAIN_AUTO)
Параметры конструктора
Значение параметров конструктора понятно из их названий. Параметр SHUNT_OHMS
указывает конструктору сопротивление шунта, которое для модуля GY-219 равно 0.1 Ом.
Если вам нужно измерять токи, превышающие 3.2 А, придется заменить шунт или припаять параллельно к имеющемуся шунту на плату модуля еще один резистор.
Необязательный параметр MAX_EXPECTED_AMPS задает максимальный ожидаемый ток. Правильное указание этого параметра позволит исключить переполнение регистров и увеличить точность измерений.
Другие необязательные параметры конструктора:
busnum — номер шины I2C;
address — адрес на шине I2C;
log_level — степень детализации вывода отладочной информации
Если указан параметр log_level, то его значение может быть равно logging.INFO или logging.DEBUG. В первом случае на консоль выводятся основные параметра работы чипа, в том числе значение для записи в регистр калибровки, а во втором еще и результаты операций со всеми регистрами.
Чтоб отключить вывод отладочной информации, просто не указывайте параметр log_level.
Параметры функции configure
Прежде всего, рассмотрим параметр voltage_range функции configure. Он может иметь два значения:
RANGE_16V — измерение напряжения от 0 до 16 В;
RANGE_32V — измерение напряжения от 0 до 32 В
Обратите внимание — даже при указании параметра RANGE_32V чип INA219 допускает максимальную величину напряжения 26 В.
Чтобы проверить работу параметра voltage_range, соберите схему с внешним регулируемым источником питания, показанную на рис.8.
Здесь к источнику питания подключен все тот же светодиод, однако на этот раз его сопротивление равно 10 КОм. Вместо контактов микрокомпьютера для питания светодиода используется положительный вывод регулируемого источника питания.
Отрицательный вывод источника питания (земля) подключен к контакту 6 микрокомпьютера Repka Pi, то есть к его земле. В нашей схеме измеряемый ток не идет через контакты микрокомпьютера.
Если установить напряжение питания меньше 16 В, например, 15.6 В, то программа example.py (листинг 1) выведет следующую информацию (отладка отключена):
Bus Voltage : 15.548 V
Bus Current : 2.000 mA
Supply Voltage : 15.544 V
Shunt voltage : 0.200 mV
Power : 31.126 mW
Теперь установите напряжение питания, равное 17.2 В, как это показано на рис. 8, и запустите программу снова.
Bus Voltage : 16.000 V
Bus Current : 2.300 mA
Supply Voltage : 16.000 V
Shunt voltage : 0.230 mV
Power : 36.876 mW
Как видите, потребляемый ток и мощность увеличились, однако напряжение выводится как 16 В, а не 17.2 В. Чтобы напряжение 17.2 В показывалось правильно, передайте функции configure параметр ina.RANGE_32V вместо указанного там ранее значения ina.RANGE_16V:
ina.configure(ina.RANGE_32V, ina.GAIN_AUTO)
Теперь мы получим ожидаемые результаты измерений:
Bus Voltage : 17.172 V
Bus Current : 2.200 mA
Supply Voltage : 17.184 V
Shunt voltage : 0.230 mV
Power : 37.876 mW
Как видите, если параметр voltage_range функции configure указать неверно, выходное напряжение может быть измерено неправильно. При этом, к сожалению, библиотека
pi‑ina219 не создает исключение. Как результат программа не сможет обнаружить ошибку при измерении напряжения из‑за неправильно заданного значения параметра voltage_range.
Изучаем чип INA219 в деталях
В простейших случаях достаточно создать свою программу на базе кода example.py, приведенного в листинге 1. При этом необходимо правильно указать значение максимального ожидаемого тока в параметре конструктора и параметра voltage_range функции configure, а также задать автоматический выбор усиления ina.GAIN_AUTO.
Однако для реализации всех богатых возможностей и понимания принципов работы чипа INA219 необходимо изучить его регистры, а также алгоритмы вычислений и калибровки при проведении измерений.
Это необходимо, например, если вы собираетесь получить от него максимально возможную точность измерений или максимальную скорость выполнения измерений, или создать собственную библиотеку для работы с чипом INA219.
Основой для получения детальной информации вам послужит даташит, который можно загрузить здесь, а также статья INA219 Current and Power Sensor. Очень много информации можно извлечь, изучая исходные коды класса INA219 библиотеки pi‑ina219.
Итак, если вам интересны детали работы и настройки чипа INA219, читайте нашу статью дальше.
Регистры чипа INA219
Прежде всего, познакомимся с регистрами INA219 (таблица 1).
В регистр конфигурации с адресом 0×00 программа должна записать 16-разрядное значение конфигурации, которое задается отдельными битами. Этот регистр доступен как на запись, так и на чтение. При выключении питания его содержимое не сохраняется, поэтому программа при запуске должна каждый раз его инициализировать.
Регистры с шестнадцатеричными адресами от 0×01 до 0×04 доступны только на чтение и
содержат данные для получения напряжения на шунте и нагрузке, мощности и величины тока. Заметим, что для получения верных данных необходима определенная обработка значений, полученных из этих регистров.
И, наконец, регистр 0×05 хранит так называемый фактор калибровки, который используется для исключения переполнения и повышения точности измерений.
Регистр конфигурации
В таблице 2 вы найдете описание назначения отдельных разрядов регистра конфигурации.
Обратите внимание на разряд 13. Если в него записать нулевое значение, то будет
установлен диапазон измерения напряжения от 0 до 16 В, а если значение единицы — от 0 до 32 В (реально до 26 В). Этим битом управляет только что рассмотренный параметр voltage_range функции configure библиотеки pi‑ina219.
Младшие биты регистра конфигурации MODE1-MODE3 определяют режим работы чипа INA219 (таблица 3).
По умолчанию установлен режим непрерывного измерения напряжения на шунте и нагрузке (выделен в табл. 3 рамкой красного цвета).
В библиотеке pi‑ina219 определены функции sleep и wake, первая из которых
переводит чип в спящий режим с отключением питания для экономии энергии, а вторая — восстанавливает его рабочее состояние.
Функция sleep получает текущую конфигурацию, сбрасывает три младших бита, и записывает новое значение в регистр конфигурации:
def sleep(self):
configuration = self._read_configuration()
self._configuration_register(configuration & 0xFFF8)
Аналогично, функция wake восстанавливает режим непрерывного измерения напряжения на
шунте и нагрузке, устанавливая в 1 три младших бита в регистре конфигурации:
def wake(self):
configuration = self._read_configuration()
self._configuration_register(configuration | 0x0007)
time.sleep(0.00004)
После сохранения новой конфигурации функция wake ожидает 40 мкс для завершения операции.
В таблице 4 приведены разрядность и количество замеров напряжения на шунте и
нагрузке. Таблица общая для полей SADC1-SADC4 и BADC1-BADC4. Набор полей SADC1-SADC4 задает разрядность аналого-цифрового преобразователя ADC и количество измерений в одном цикле при измерении напряжения на шунте, а набор полей BADC1-BADC4 задает те же параметры при измерении напряжения на нагрузке.
По умолчанию используется 12 разрядов при времени измерения 532 мкс (выделено в табл. 4 рамкой красного цвета).
Увеличивая количество замеров в одном цикле при установленном бите ADC4, можно
увеличивать точность за счет усреднения заданного количества замеров. Чем больше это количество, тем выше точность и время, потраченное на измерения.
Регистр конфигурации позволяет вам управлять разрядностью и количеством замеров отдельно для измерения напряжения на шунте и на нагрузке.
Регистр напряжения на нагрузке
Регистр напряжения на нагрузке доступен для чтения по адресу 0×02. Однако для
получения из записанных в нем данных правильного значения напряжения, необходимы некоторые преобразования.
Прежде всего, данные АЦП записываются в 13 старших бит регистра — D15-D3. Поэтому для получения результатов измерения требуется сдвинуть содержимое регистра вправо на
три бита.
В нулевой бит D0 после проведения измерений записывается флаг переполнения. Если этот флаг установлен, результаты измерений выходят за допустимые пределы и полученные значения напряжения, тока и мощности могут быть неверными.
Если установлен бит D1, то преобразования завершены и выходные регистры содержат искомые результаты измерений. Этот бит сбрасывается после изменения режима работы чипа в регистре конфигурации, а также при чтении содержимого регистра мощности с адресом 0×03.
Надо сказать, что в библиотеке pi‑ina219 функция voltage и вызываемые ей функции не проверяют бит D0 флага переполнения и бит завершения измерений D1:
__BUS_MILLIVOLTS_LSB = 4 # 4mV … def voltage(self):
value = self._voltage_register()
return float(value) * self.__BUS_MILLIVOLTS_LSB / 1000
…
def _voltage_register(self):
register_value = self._read_voltage_register()
return register_value >> 3
def _read_voltage_register(self):
return self.__read_register(self.__REG_BUSVOLTAGE)
def __read_register(self, register, negative_value_supported=False):
if negative_value_supported:
register_value = self._i2c.readS16BE(register)
else:
register_value = self._i2c.readU16BE(register)
self.logger.debug(
"read register 0x%02x: 0x%04x 0b%s" %
(register, register_value,
self.__binary_as_string(register_value)))
return register_value
Функция voltage вызывает _voltage_register, умножая полученное от нее значение
на константу __BUS_MILLIVOLTS_LSB. В этой константе хранится количество милливольт на младший разряд данных АЦП, а именно 4 мВ. Далее, чтобы получить напряжение в вольтах, результат умножения делится на 1000.
Функция _voltage_register читает содержимое регистра напряжения на нагрузке и сдвигает результат вправо на три бита. Она получает данные с помощью функции __read_register.
И, наконец, функция __read_register читает содержимое регистра, адрес которого передается ей в качестве параметра, и при использовании отладки выводит прочитанные данные на консоль.
Регистр тока
Другой важный регистр с адресом 0×04 — это регистр тока в нагрузке. Для его измерения в библиотеке pi‑ina219 определена функция current:
def current(self):
self._handle_current_overflow()
return self._current_register() * self._current_lsb * 1000
Измерение тока — более сложный процесс по сравнению с измерением напряжения. Функция current, возвращающая значение тока в миллиамперах, фиксирует переполнение и создает в этом случае исключение DeviceRangeError.
Для обработки переполнения вызывается функция _handle_current_overflow:
def _handle_current_overflow(self):
if self._auto_gain_enabled:
while self._has_current_overflow():
self._increase_gain()
else:
if self._has_current_overflow():
raise DeviceRangeError(self.__GAIN_VOLTS[self._gain])
Прежде всего, функция _handle_current_overflow проверяет, было ли указано значение параметра усиления как ina.GAIN_AUTO при вызове функции configure:
ina.configure(ina.RANGE_32V, ina.GAIN_AUTO)
Если задано автоматическое определение необходимого усиления, при обнаружении переполнения функцией _has_current_overflow будет вызвана функция _handle_current_overflow. Она автоматически подбирает режим усиления PGA из числа предусмотренных в чипе INA219 (рис. 1).
Функция _has_current_overflow проверяет бит переполнения при чтении регистра напряжения:
def _has_current_overflow(self):
ovf = self._read_voltage_register() & self.__OVF
return (ovf == 1)
Что касается функции _increase_gain, то она читает текущее усиление из регистра конфигурации (биты PG0, PG1). Далее она пытается увеличить индекс в массиве возможных параметров усиления __GAIN_VOLTS, после чего записывает новое значение усиления и новое значение для регистра калибровки:
__GAIN_VOLTS = [0.04, 0.08, 0.16, 0.32]
…
def _increase_gain(self):
self.logger.info(self.__LOG_MSG_3)
gain = self._read_gain()
if gain < len(self.__GAIN_VOLTS) - 1:
gain = gain + 1
self._calibrate(self.__BUS_RANGE[self._voltage_range],
self.__GAIN_VOLTS[gain])
self._configure_gain(gain)
time.sleep(0.001)
else:
self.logger.info('Device limit reach, gain cannot be increased')
raise DeviceRangeError(self.__GAIN_VOLTS[gain], True)
Функция _calibrate вычисляет новый фактор калибровки для записи в регистр калибровки 0x05. Этот процесс будет описан ниже в нашей статье.
При невозможности подобрать усиление, необходимое для того, чтобы избавиться от переполнения, вырабатывается исключение DeviceRangeError.
Регистр калибровки
Здесь мы подошли к такому моменту, когда нужно рассказать про регистр калибровки тока и мощности с адресом 0x05. Биты D1-D15 этого регистра хранят так называемый фактор калибровки, а бит D0 не используется.
Согласно описанию чипа INA219, регистр калибровки устанавливает ток, соответствующий полному падению напряжения на шунте. От содержимого этого регистра зависит полный диапазон шкалы и младший разряд измерения тока и мощности.
В статье INA219 Current and Power Sensor описаны вычисления, выполняемые чипом INA219 при выполнении измерений.
Для определения значения фактора калибровки нужно знать максимальное ожидаемое значение тока в нагрузке MaxExpectedCurrent. Это значение должно полностью поместиться в регистр тока (с адресом 0x04). При этом количество ампер на один младший бит CurrentLSB вычисляется следующим образом:
CurrentLSB = MaxExpectedCurrent / 2**15
Здесь учтено, что регистр тока с адресом 0x04 содержит 15 разрядов значения плюс один разряд знака.
Для вычисления фактора калибровки Cal используется такая формула:
Cal = round(0.04096 / CurrentLSB * RShunt)
В этой формуле RShunt представляет собой сопротивление шунта (равно 0.1 Ом в модуле GY-219), а число 0.04096 рекомендуется в описании чипа INA219 как подходящее значение для эффективного использования разрядов регистра при масштабировании.
В процессе измерений в регистр тока CurrentRegister с адресом 0x04 записывается значение, определенное с учетом содержимого регистра напряжения на шунте ShuntVoltageRegister (адрес 0x01) и вычисленного фактора калибровки Cal:
CurrentRegister = (ShuntVoltageRegister * Cal) / 4096
Младший разряд регистра напряжения на шунте соответствует 10 мкВ. Этот регистр содержит значение со знаком, поэтому в нем может храниться максимальное число, равное 215-1. Простой расчет показывает, что при сопротивлении шунта 0.1 Ом и максимальном напряжении на шунте 0.32767 В максимальный ток через шунт составит 3.2 А. При этом учитывается, что:
((215-1) * 10 мкВ) / 106 = 0.32767 В
Для определения мощности в ваттах на один бит PowerLSB согласно документации на INA219 используется такая формула:
PowerLSB = 20 * CurrentLSB
При этом содержимое регистра мощности 0x03 вычисляется так:
PowerRegister = (CurrentRegisterBus * VoltageRegister) / 5000
Настройка усиления PGA
Вы уже знаете, что биты PG0 и PG1 задают усиление для PGA, встроенного в чип INA219. Усиление можно задавать как параметр функции configure. Ниже мы показали, как задать автоматический выбор усиления:
ina.configure(ina.RANGE_32V, ina.GAIN_AUTO)
Вы также можете задать режим усиления вручную с помощью следующих констант, определенных в файле ina219.py библиотеки pi-ina219. В комментариях указано максимальное напряжение на шунте в мВ:
GAIN_1_40MV = 0 # 40 мВ
GAIN_2_80MV = 1 # 80 мВ
GAIN_4_160MV = 2 # 160 мВ
GAIN_8_320MV = 3 # 320 мВ
Также в этом файле определен массив максимальных напряжений __GAIN_VOLTS в вольтах для перечисленных выше режимов усиления:
__GAIN_VOLTS = [0.04, 0.08, 0.16, 0.32]
Исследуем автоматическую регулировку усиления и калибровку
Чтобы разобраться на практике как INA219 выполняет автоматическую регулировку усиления и калибровку при измерении тока, соберите макет, показанный на рис.9.
В отличие от макета, использованного нами ранее (рис. 4), здесь мы подаем напряжение с лабораторного источника питания на мощный резистор сопротивлением 15 Ом.
При включении питающего напряжения 5 В, амперметр лабораторного источника фиксирует ток, равный 314 мА, и мощность 1.5 Вт.
Посмотрим, что покажут измерения, выполненные с помощью INA219.
Запустим программу example.py, указав параметры конструктора и функции configure следующим образом:
SHUNT_OHMS = 0.1
MAX_EXPECTED_AMPS = 0.2
def read():
ina = INA219(SHUNT_OHMS, MAX_EXPECTED_AMPS, log_level=logging.DEBUG)
ina.configure(ina.RANGE_32V, ina.GAIN_AUTO)
Здесь в конструкторе мы намеренно указали максимально ожидаемый ток 0.2 А, зная, что в нашем макете ток достигнет значения 0.314 А. Для подробной выдачи действий по выбору усиления мы включили параметр отладки, равный logging.DEBUG.
Так же мы выбрали режим автоматического подбора усиления ina.GAIN_AUTO, и максимальное напряжение ina.RANGE_32V.
Запустим программу и посмотрим внимательно на отладочную информацию, которая появится на консоли.
Измерение напряжения на нагрузке
Сразу после запуска устанавливается усиление GAIN_1_40MV и максимальный ожидаемый ток 0.200 A. Из вывода отладочной информации видно, что максимальный ток перед переполнением составит 0.2048 A, а максимальное напряжение на шунте перед переполнением — 20.4800 мВ:
# python3 example.py
2023-09-14 06:11:03,505 - INFO - INA219 gain set to 0.04V
2023-09-14
06:11:03,506 - DEBUG - INA219 shunt ohms: 0.100, bus max volts: 32,
shunt volts max: 0.04, max expected amps: 0.200A, bus ADC: 3, shunt ADC:
3
2023-09-14 06:11:03,506 - INFO - INA219 calibrate called with:
bus max volts: 32V, max shunt volts: 0.04V, max expected amps: 0.200A
2023-09-14 06:11:03,506 - INFO - INA219 max possible current: 0.400A
2023-09-14 06:11:03,507 - INFO - INA219 max expected current: 0.200A
2023-09-14 06:11:03,507 - INFO - INA219 current LSB: 6.250e-06 A/bit
2023-09-14 06:11:03,507 - INFO - INA219 power LSB: 1.250e-04 W/bit
2023-09-14 06:11:03,507 - INFO - INA219 max current before overflow: 0.2048A
2023-09-14 06:11:03,508 - INFO - INA219 max shunt voltage before overflow: 20.4800mV
Далее видим, что в регистр калибровки записывается значение 0xfffe:
2023-09-14 06:11:03,508 - INFO - INA219 calibration: 0xfffe (65534)
2023-09-14 06:11:03,508 - DEBUG - INA219 calibration: 0xfffe
2023-09-14 06:11:03,508 - DEBUG - INA219 write register 0x05: 0xfffe 0b1111111111111110
2023-09-14 06:11:03,509 - DEBUG - INA219 Wrote to register 0x05: [255, 254]
После этого следует запись нового значения в регистр конфигурации 0x00 значения 0010 0001 1001 1111:
2023-09-14 06:11:03,510 - DEBUG - INA219 configuration: 0x219f
2023-09-14 06:11:03,510 - DEBUG - INA219 write register 0x00: 0x219f 0b0010000110011111
2023-09-14 06:11:03,511 - DEBUG - INA219 Wrote to register 0x00: [33, 159]
Биты усиления D12 и D11 содержат нулевые значения, что соответствует усилению GAIN_1_40MV.
На следующем этапе вызывается функция voltage, возвращающая напряжение на нагрузке. Она читает содержимое регистра напряжения на нагрузке 0x02 и регистра мощности 0x03. После этого на консоль выводится значение измеренного напряжения:
2023-09-14 06:11:03,513 - DEBUG - INA219 Read 0x8325 from register pair 0x02, 0x03
2023-09-14 06:11:03,514 - DEBUG - INA219 read register 0x02: 0x2583 0b0010010110000011
Bus Voltage : 4.800 V
Итак, INA219 показал, что напряжение на нагрузке равно 4.8 В.
Дополнительный контроль с помощью мультиметра обнаружил, что напряжение на выходе лабораторного источника питания равно 4.96 В, а на нагрузке — 4.73 В. При этом вольтметр лабораторного источника питания показал выходное напряжение, равное 5 В.
Чему больше верить?
В этой ситуации для получения точного значения напряжения лучше использовать для контроля сертифицированный вольтметр, который прошел процедуру испытания и калибровки. Однако в реальных применениях точность измерений INA219 может оказаться вполне достаточной.
При использовании калиброванного вольтметра можно скорректировать измеренное значение напряжения уже в вашей программе. Также полученные показания могут изменяться в зависимости от температуры окружающей среды.
Также напомним, что модуль на базе чипа INA219A измеряет ток и напряжение с точностью 0.5–1%. При напряжении 5 В отклонение может составить до 0.05 В.
Измерение тока
На следующем шаге программа вызывает функцию current для измерения тока, проходящего через нагрузку. И вот тут возникает переполнение:
2023-09-14 06:11:03,515 - DEBUG - INA219 Read 0x9325 from register pair 0x02, 0x03
2023-09-14 06:11:03,515 - DEBUG - INA219 read register 0x02: 0x2593 0b0010010110010011
2023-09-14 06:11:03,516 - INFO - INA219 Current overflow detected - attempting to increase gain
Обратите внимание на содержимое регистра напряжения на нагрузке 0x02:
0b0010010110010011
Младший бит этого регистра, сигнализирующий переполнение, установлен в единицу.
Подбор усиления и вычисление фактора калибровки при переполнении
После обнаружения переполнения функция current запускает процедуру подбора режима усиления.
Вначале выбирается режим усиления, допускающий напряжение на шунте без переполнения, равного 0.08 В. Это соответствует току 0.8 A:
2023-09-14 06:11:03,517 - DEBUG - INA219 Read 0x9F21 from register pair 0x00, 0x01
2023-09-14 06:11:03,517 - DEBUG - INA219 read register 0x00: 0x219f 0b0010000110011111
2023-09-14 06:11:03,517 - INFO - INA219 gain is currently: 0.04V
2023-09-14 06:11:03,518 - INFO - INA219 calibrate called with: bus max volts: 32V, max shunt volts: 0.08V
2023-09-14 06:11:03,518 - INFO - INA219 max possible current: 0.800A
2023-09-14 06:11:03,518 - INFO - INA219 current LSB: 2.439e-05 A/bit
2023-09-14 06:11:03,518 - INFO - INA219 power LSB: 4.878e-04 W/bit
2023-09-14 06:11:03,519 - INFO - INA219 max current before overflow: 0.7992A
2023-09-14 06:11:03,519 - INFO - INA219 max shunt voltage before overflow: 79.9195mV
Далее новое значение фактора калибровки устанавливается в регистре 0x05, равным 0x4199:
2023-09-14 06:11:03,519 - INFO - INA219 calibration: 0x4199 (16793)
2023-09-14 06:11:03,519 - DEBUG - INA219 calibration: 0x4199
2023-09-14 06:11:03,520 - DEBUG - INA219 write register 0x05: 0x4199 0b0100000110011001
2023-09-14 06:11:03,521 - DEBUG - INA219 Wrote to register 0x05: [65, 153]
В регистр конфигурации 0x01 записывается новое значение режима усиления, равный GAIN_2_80MV:
2023-09-14 06:11:03,522 - DEBUG - INA219 Read 0x9F21 from register pair 0x00, 0x01
2023-09-14 06:11:03,522 - DEBUG - INA219 read register 0x00: 0x219f 0b0010000110011111
2023-09-14 06:11:03,523 - DEBUG - INA219 configuration: 0x299f
2023-09-14 06:11:03,523 - DEBUG - INA219 write register 0x00: 0x299f 0b0010100110011111
2023-09-14 06:11:03,524 - DEBUG - INA219 Wrote to register 0x00: [41, 159]
2023-09-14 06:11:03,524 - INFO - INA219 gain set to: 0.08V
Теперь, с новым режимом усиления и новым фактором калибровки, функция current возвращает правильное значение тока в нагрузке:
2023-09-14 06:11:03,527 - DEBUG - INA219 Read 0x7A25 from register pair 0x02, 0x03
2023-09-14 06:11:03,527 - DEBUG - INA219 read register 0x02: 0x257a 0b0010010101111010
2023-09-14 06:11:03,528 - DEBUG - INA219 Read 0x493D from register pair 0x04, 0x05
2023-09-14 06:11:03,529 - DEBUG - INA219 read register 0x04: 0x3d49 0b0011110101001001
Bus Current : 382.659 mA
Измерение напряжения питания
На следующем шаге программа вызывает функцию supply_voltage, возвращающую напряжение питания:
2023-09-14 06:11:03,530 - DEBUG - INA219 Read 0x8225 from register pair 0x02, 0x03
2023-09-14 06:11:03,530 - DEBUG - INA219 read register 0x02: 0x2582 0b0010010110000010
2023-09-14 06:11:03,532 - DEBUG - INA219 Read 0x8225 from register pair 0x02, 0x03
2023-09-14 06:11:03,532 - DEBUG - INA219 read register 0x02: 0x2582 0b0010010110000010
2023-09-14 06:11:03,533 - DEBUG - INA219 Read 0xF70E from register pair 0x01, 0x02
2023-09-14 06:11:03,534 - DEBUG - INA219 read register 0x01: 0x0ef7 0b0000111011110111
Supply Voltage : 4.838 V
Как мы говорили раньше, показания INA219 отличаются от показаний вольтметра лабораторного источника питания (5 В), а также показаний контрольного мультиметра (4.96 В).
Измерение напряжения на шунте
Функция shunt_voltage возвращает напряжение на шунте, равное 38.3 мВ:
2023-09-14 06:11:03,535 - DEBUG - INA219 Read 0x8225 from register pair 0x02, 0x03
2023-09-14 06:11:03,535 - DEBUG - INA219 read register 0x02: 0x2582 0b0010010110000010
2023-09-14 06:11:03,537 - DEBUG - INA219 Read 0xF60E from register pair 0x01, 0x02
2023-09-14 06:11:03,537 - DEBUG - INA219 read register 0x01: 0x0ef6 0b0000111011110110
Shunt voltage : 38.300 mV
Если разделить это напряжение на сопротивление шунта, равное 0.1 Ом, получится ток 0.383 А, который мы получили выше от функции current.
Измерение мощности
Перед завершением работы программа example.py вызывает функцию power, возвращающую мощность в нагрузке:
2023-09-14 06:11:03,538 - DEBUG - INA219 Read 0x7A25 from register pair 0x02, 0x03
2023-09-14 06:11:03,539 - DEBUG - INA219 read register 0x02: 0x257a 0b0010010101111010
2023-09-14 06:11:03,540 - DEBUG - INA219 Read 0xB70E from register pair 0x03, 0x04
2023-09-14 06:11:03,540 - DEBUG - INA219 read register 0x03: 0x0eb7 0b0000111010110111
Power : 1837.561 mW
Если умножить ток на напряжение в нагрузке, измеренные INA219, получится значение 1,8336 Вт, что вполне согласуется с результатом, прочитанным из регистра мощности чипа INA219.
Переполнение при отключении автоматического выбора усиления
Теперь мы попробуем вместо автоматического подбора режима усиления указать его явным образом как ina.GAIN_1_40MV:
SHUNT_OHMS = 0.1
MAX_EXPECTED_AMPS = 0.2
…
ina = INA219(SHUNT_OHMS, MAX_EXPECTED_AMPS)
ina.configure(ina.RANGE_32V, ina.GAIN_1_40MV)
Теперь, как и ожидается, в процессе измерения тока произойдет переполнение. Соответствующее сообщение программа выведет на консоль:
# python3 example.py
Bus Voltage : 4.792 V
Ошибка: Current out of range (overflow), for gain 0.04V
Ручной выбор режима усиления
Если по какой-то причине вы решили выбрать усиление самостоятельно, не полагаясь на режим автоматического выбора усиления ina.GAIN_AUTO, то можно придерживаться следующего плана.
Прежде всего нужно определить максимальное значение измеряемого тока. При использовании библиотеки pi-ina219 это значение нужно передать в конструктор класса INA219.
В конструктор класса INA219 нужно передать сопротивление шунта. Для модуля GY-219 оно равно 0.1 Ом, но вы можете заменить резистор на плате модуля или припаять параллельно еще один резистор, чтобы измерять токи, большие чем 3.2 А.
Рассчитайте значение усиления исходя из диапазона измеряемого тока. Для шунта сопротивлением 0.1 Ом получаются следующие максимальные значения напряжения на шунте и соответствующие этому напряжению токи:
GAIN_1_40MV — 40 мВ, 0.4 A
GAIN_2_80MV — 80 мВ, 0.8 А
GAIN_4_160MV — 160 мВ, 1.6 А
GAIN_8_320MV — 320 мВ, 3.2 А
Выберите ближайшее усиление, соответствующее измеряемому току с учетом сопротивления шунта.
После расчета усиления сформируйте данные для регистра конфигурации и запишите их в этот регистр.
Полезные ссылки
INA219 26-V 12-bit I2C output digital power monitor
INA219 Current and Power Sensor
Репозиторий py_ina219_smbus
Как подключить датчик тока к Arduino
Итоги
Прочитав эту статью, вы узнали, как использовать модуль GY-219 с интерфейсом I2C
и чипом INA219 для измерения напряжения на нагрузке, потребляемый нагрузкой ток и мощность.
Вы подключили модуль GY-219 к одноплатному компьютеру Repka Pi и установили библиотеку pi-ina219, позволяющую легко получать данные от INA219 в программах Python3.
В завершение на рис.10 приведём пример Web приложения на Python для управления включением реле, поворотом сервоприводов, управлением сигналами RGB-светодиода и с выводом показаний датчика тока в отдельный набор виджетов (стрелочный индикатор, цифровой индикатор и график показаний с настраиваемой глубиной отображения показаний датчика на графике), при этом датчик тока именно INA219 - как и рассматриваемый в данной статье, в измерительную цепь которого включена нагрузка управляемых сервоприводов и включаемых с помощью реле устройств. Данное приложение является учебным и предназначено для подготовки специалистов по автоматике и встраиваемым системам и может быть легко переделано в проект панели управления автоматикой или в приложение для управления каким то объектом, например теплицей или системой подачи питания и т.п.
В рабочих проектах у нас этот датчик применяется в продвинутых моделях роботов Робоинтеллект — там обратная связь по току питания силовых установок применяется, чтобы обеспечить программную защиту и отключение в случае, если манипулятор упрётся в препятствие или механически заклинит и тогда есть опасность выхода двигателей из строя и тогда такая простая обратная связь позволяет избежать кучи нежелательных проблем.
Те, кому нужно разобраться в теме до самых глубин, нашли в статье детальное описание архитектуры чипа INA219, а также алгоритмов, положенных в его основу. С помощью этой информации вы сможете использовать все возможности чипа INA219, а при необходимости создать свою библиотеку для получения от него данных измерений.
Изображения, использованные в статье: