Embedded HandbookПриложения
Все разделы › XI. Датчики: подключение, схемы, драйверы
STM32F103, STM32F407 · уровень средний · 7 мин чтения
Открыть в интерактивном справочнике

101. Ток и напряжение: INA219 и ACS712

Ток меряют двумя способами. Можно поставить в цепь шунт — резистор малого сопротивления — и мерить падение на нём: INA219 делает это сам, со своим усилителем и АЦП, и отдаёт по I²C ток, напряжение и мощность. А можно пропустить ток через датчик Холла: ACS712 выдаёт напряжение, пропорциональное току, и его читает АЦП микроконтроллера. Первому нужно одно калибровочное число, второму — измеренный ноль, и у каждого есть место, где показания тихо врут.

АЦП — раздел 14, I²C — раздел 17, делители — раздел 62, подключение модулей — раздел 95.

Как это называется в документации

Оригинал Перевод
shunt resistor шунт — резистор малого сопротивления в цепи тока
high-side, low-side sensing шунт в плюсовом проводе и в минусовом
current sense amplifier усилитель сигнала шунта
calibration register калибровочный регистр
LSB, current LSB вес младшего разряда; шаг измерения тока
bus voltage напряжение шины — на нагрузке относительно земли
Hall effect sensor датчик Холла
sensitivity, mV/A чувствительность: милливольт на ампер
zero-current output выход при нулевом токе
ratiometric output выход, пропорциональный питанию

101.1 Шунт или датчик Холла

INA219 в плюсовом проводе нагрузки и ACS712 через делитель на вход АЦП

INA219 ACS712
принцип шунт, усилитель и АЦП внутри микросхемы датчик Холла с аналоговым выходом
выход числа по I²C: ток, напряжение, мощность напряжение: 185 мВ/А у версии на 5 А
цепь тока через шунт, общая с измерением через саму микросхему, отделена от выхода
что настраивать калибровочный регистр ноль — измерить без нагрузки
слабое место предел ±320 мВ на шунте ноль и чувствительность зависят от питания 5 В

101.2 INA219: шунт и калибровка

INA219 меряет напряжение на шунте (10 мкВ на единицу, до ±320 мВ при усилении по умолчанию) и напряжение шины (4 мВ на единицу), а ток и мощность считает сам — если знает калибровку. Её задают одним числом: CAL = 0,04096 / (I_LSB · R_шунта), где I_LSB — шаг измерения тока.

Шаг выбирают из наибольшего тока: 3,2 А / 32768 = 97,656 мкА — и округляют вверх до удобных 100 мкА. С шунтом 0,1 Ом получается CAL = 4096, а шаг мощности — всегда 20 шагов тока — 2 мВт. Слово настройки после сброса — 0x399F: шкала шины 32 В, шунт ±320 мВ, 12 бит, измерения непрерывно. Шкала шире, чем терпит сам чип: на входах INA219 выдерживает не больше 26 В, и шину выше 26 В к нему не подключают.

#define INA_CONFIG(brng, pg, badc, sadc, mode) \
    ((uint16_t)((brng) << 13 | (pg) << 11 | (badc) << 7 | (sadc) << 3 | (mode)))

uint16_t ina_cal(uint32_t ilsb_ua, uint32_t rshunt_mohm)
{
    return (uint16_t)(40960000u / (ilsb_ua * rshunt_mohm));
}

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


101.3 Чтение и перевод

Регистры INA219 — 16-битные, старшим байтом вперёд; шунт и ток — числа со знаком, у шины значение — в битах 15:3, а младший бит — переполнение расчёта тока или мощности (OVF):

int32_t ina_bus_mv(uint16_t reg)
{
    return (int32_t)(reg >> 3) * 4;
}

int32_t ina_current_ua(uint16_t reg, uint32_t ilsb_ua)
{
    return (int16_t)reg * (int32_t)ilsb_ua;
}

uint32_t ina_power_uw(uint16_t reg, uint32_t ilsb_ua)
{
    return reg * 20u * ilsb_ua;         /* шаг мощности — 20 шагов тока */
}

int ina_read(uint32_t ilsb_ua, int32_t *bus_mv, int32_t *cur_ua, uint32_t *pow_uw)
{
    uint16_t s, b, c, p;
    if (!i2c_read_reg16(INA_ADDR, INA_REG_SHUNT, &s) || !i2c_read_reg16(INA_ADDR, INA_REG_BUS, &b)
        || !i2c_read_reg16(INA_ADDR, INA_REG_CURRENT, &c) || !i2c_read_reg16(INA_ADDR, INA_REG_POWER, &p))
        return 0;
    if ((b & 1u) || (int16_t)s >= 32000 || (int16_t)s <= -32000)
        return 0;                       /* OVF или шунт на пределе ±320 мВ */
    *bus_mv = ina_bus_mv(b);
    *cur_ua = ina_current_ua(c, ilsb_ua);
    *pow_uw = ina_power_uw(p, ilsb_ua);
    return 1;
}

На компьютере вместо шины — модель регистров, которая считает ток и мощность так же, как сам чип: из напряжения шунта и калибровки. Ток 1 А через 0,1 Ом — это 100 мВ на шунте (10 000 единиц) и регистр тока 10 000, то есть 1,000 А; шина 12 В — регистр 0x5DC2, из него 12 000 мВ; мощность — 12 Вт. Ток в обратную сторону, −0,5 А, даёт в регистре шунта 0xEC78 — отрицательное число в дополнительном коде. А 3,3 А — это 330 мВ на шунте, за пределом ±320 мВ — полной шкалы шунта, 32 000 единиц. Бит OVF чип ставит, только когда не помещаются вычисленные ток или мощность, а при CAL = 4096 ток с полной шкалы — 32 000, в регистр он помещается. В модели так и вышло: шунт 0x7D00, ток 32 000, OVF не встал. Поэтому драйвер смотрит и на сам регистр шунта: ±32 000 и дальше — ошибка вместо неверного числа.


101.4 ACS712: датчик Холла и его ноль

ACS712 на 5 А выдаёт половину своего питания при нулевом токе и прибавляет 185 мВ на каждый ампер. При питании 5 В это 1,575…3,425 В на ±5 А — больше, чем выдержит вход АЦП на 3,3 В, поэтому выход идёт через делитель 2/3 (10 кОм и 20 кОм). Коды АЦП для ±5 А — 1303…2833, по 6,53 мА на код:

int32_t acs_ma(int32_t code, int32_t zero_code)
{
    int64_t n = (int64_t)(code - zero_code) * 4950000;
    const int64_t d = 757575;           /* 4095 · 185 */
    return (int32_t)((n + (n < 0 ? -d / 2 : d / 2)) / d);
}

Ток считается от кода нуля, и вот почему его надо мерить, а не брать «половину шкалы». Ноль и чувствительность ACS712 пропорциональны его собственному питанию 5 В, а АЦП меряет относительно своих 3,3 В — эти два напряжения не связаны. При питании ровно 5,0 В код нуля — 2068, при +1 А — 2221, то есть 1000 мА. Просело питание до 4,9 В — ноль ушёл на код 2027, и с нулём, снятым при 5,0 В, датчик показывает −268 мА без всякого тока. Если ноль перемерить, +1 А даёт код 2177 — 980 мА: вместе с питанием на 2 % упала и чувствительность.

ACS712: питание просело на 2 % — ноль уехал, и без тока датчик «видит» −268 мА

Отсюда правила: ноль мерить без нагрузки при каждом запуске, питание датчика держать стабильным, а если нужна точность — мерить само 5 В вторым каналом АЦП через такой же делитель и поправлять чувствительность.


101.5 Где ставить шунт

Шунт в плюсовом проводе оставляет землю нагрузки землёй: у прибора, который делит землю с другими, это обычно единственный правильный вариант, и INA219 сделан именно для него — меряет шину до 26 В при своём питании 3,3 В. Шунт в минусовом проводе проще для усилителя, но «земля» нагрузки тогда плавает на величину падения на шунте, и всё, что подключено к нагрузке, видит этот сдвиг.

Шунт в плюсовом проводе и в минусовом: во втором случае земля нагрузки приподнята на падение на шунте


101.6 Грабли

INA219 показывает ток и мощность ноль. Не записан калибровочный регистр: после включения он пуст, и чип ничего не считает.

Ток INA219 скачет в сотни раз. Регистр прочитан младшим байтом вперёд; у INA219 старший первым.

При большом токе показание «замерло». На шунте больше ±320 мВ: регистр шунта упёрся в ±32 000, а бит OVF может и не встать — он про переполнение расчёта. Проверять регистр шунта; меньше шунт или другое усиление.

ACS712 показывает ток без нагрузки. Ноль взят половиной шкалы, а питание датчика не ровно 5 В: при 4,9 В — −268 мА из ниоткуда. Мерить ноль без нагрузки.

Показания ACS712 плавают вместе с питанием 5 В. Выход пропорционален его питанию, а опора АЦП — своя.

Выход ACS712 — прямо на вход АЦП. До 3,425 В на пяти амперах — больше 3,3 В. Делитель.


101.7 Итоги

Дальше: раздел 101а «Монитор тока и мощности INA226: 16 бит, калибровочный регистр, усреднение, тревога по порогу и счёт энергии» — тот же шунт, но шаг вчетверо мельче, усреднение и тревога внутри микросхемы и счёт миллиампер-часов.

Открыть в интерактивном справочнике