pkolt/ina226

1.0.0

Latest
uploaded 1 hour ago
ESP-IDF driver for the Texas Instruments INA226 current, voltage, and power monitor

Readme (ru)

# INA226 for ESP-IDF (ESP32)

- [INA226 for ESP-IDF (ESP32)](#ina226-for-esp-idf-esp32)
  - [Введение](#введение)
    - [Кратко о возможностях](#кратко-о-возможностях)
    - [Карта регистров](#карта-регистров)
    - [Режимы работы (поле `MODE`, биты `2:0` регистра `00h`)](#режимы-работы-поле-mode-биты-20-регистра-00h)
    - [Пин `ALERT`](#пин-alert)
  - [Настройка датчика](#настройка-датчика)
    - [Параметры `ina226_config_t`](#параметры-ina226_config_t)
    - [Допустимые значения](#допустимые-значения)
    - [Можно ли не задавать конфиг вручную?](#можно-ли-не-задавать-конфиг-вручную)
  - [Режим одиночного измерения](#режим-одиночного-измерения)
  - [Режим постоянного измерения](#режим-постоянного-измерения)
  - [Прерывание на пине ALERT при достижении порогового значения](#прерывание-на-пине-alert-при-достижении-порогового-значения)
  - [Прерывания на пине ALERT при готовности данных](#прерывания-на-пине-alert-при-готовности-данных)
  - [Режим работы Power-Down](#режим-работы-power-down)
  - [API](#api)
    - [Создание и жизненный цикл](#создание-и-жизненный-цикл)
    - [Измерения и режимы работы](#измерения-и-режимы-работы)
    - [Чтение измеренных величин](#чтение-измеренных-величин)
    - [ALERT и пороговые события](#alert-и-пороговые-события)
    - [Конфигурация по умолчанию](#конфигурация-по-умолчанию)
  - [Лицензия](#лицензия)


## Введение

`INA226` — цифровой монитор питания с интерфейсом I2C, который измеряет напряжение шины (`VBUS`) и падение напряжения на шунте (`VSHUNT`), а также вычисляет ток и мощность (после калибровки).

### Кратко о возможностях

- Измерение:
  - напряжения шины (`Bus Voltage`, регистр `02h`),
  - напряжения на шунте (`Shunt Voltage`, регистр `01h`),
  - тока (`Current`, регистр `04h`, после записи калибровки),
  - мощности (`Power`, регистр `03h`, после записи калибровки).
- Гибкая настройка АЦП через регистр конфигурации `00h`:
  - усреднение (`AVG`),
  - время преобразования для `VBUS` и `VSHUNT` (`VBUSCT`, `VSHCT`),
  - режим работы (`MODE`).
- Поддержка программного сброса (`RST`, бит 15 регистра `00h`).
- Калибровка под конкретный шунт через регистр `05h` (`Calibration`).
- Работа с аппаратным выходом `ALERT`:
  - пороговые события (over/under limit),
  - сигнал готовности данных (`Conversion Ready`).
- Проверка связи с микросхемой через `Die ID` (`FFh`, значение по умолчанию `2260h`).

### Карта регистров

| Адрес | Доступ | Регистр | По умолчанию | Назначение |
| :---: | :---: | :--- | :---: | :--- |
| `00h` | R/W | Configuration | `4127h` | Настройка АЦП, усреднения, времени преобразования, режима, сброс |
| `01h` | R | Shunt Voltage | `0000h` | Измеренное падение напряжения на шунте |
| `02h` | R | Bus Voltage | `0000h` | Измеренное напряжение шины |
| `03h` | R | Power | `0000h` | Рассчитанная мощность (после калибровки) |
| `04h` | R | Current | `0000h` | Рассчитанный ток (после калибровки) |
| `05h` | R/W | Calibration | `0000h` | Калибровочный коэффициент |
| `06h` | R/W | Mask/Enable | `0000h` | Маски, флаги и полярность/защёлка `ALERT` |
| `07h` | R/W | Alert Limit | `0000h` | Порог для срабатывания `ALERT` |
| `FFh` | R | Die ID | `2260h` | Идентификатор кристалла |

### Режимы работы (поле `MODE`, биты `2:0` регистра `00h`)

| MODE | Режим |
| :--: | :--- |
| `000` | Power-Down (отключен) |
| `001` | Shunt Voltage, trigger (одиночное измерение шунта) |
| `010` | Bus Voltage, trigger (одиночное измерение шины) |
| `011` | Shunt + Bus, trigger (одиночное измерение шунта и шины) |
| `100` | Power-Down (отключен) |
| `101` | Shunt Voltage, continuous (непрерывно) |
| `110` | Bus Voltage, continuous (непрерывно) |
| `111` | Shunt + Bus, continuous (непрерывно, режим по умолчанию) |

### Пин `ALERT`

Вывод `ALERT` настраивается регистрами `Mask/Enable` (`06h`) и `Alert Limit` (`07h`).

- Пороговые события:
  - `SOL`/`SUL` — выход за пределы по напряжению шунта,
  - `BOL`/`BUL` — выход за пределы по напряжению шины,
  - `POL` — превышение порога мощности.
- Событие готовности данных:
  - `CNVR` (маска источника),
  - `CVRF` (флаг готовности преобразования).
- Служебные биты:
  - `AFF` — флаг аварийного события,
  - `OVF` — математическое переполнение,
  - `APOL` — полярность `ALERT` (`0` — active-low, `1` — active-high),
  - `LEN` — режим вывода (`0` — прозрачный, `1` — с защёлкой).

## Настройка датчика

После `ina226_create()` устройство настраивается через `ina226_init(sensor, bus, cfg)`.

- Если `cfg != NULL` — используются ваши значения из `ina226_config_t`.
- Если `cfg == NULL` — библиотека подставляет `INA226_DEFAULT_CONFIG()`.

Важно: после `ina226_init()` драйвер оставляет INA226 в режиме `Power-Down`; запуск измерений делается отдельно (`ina226_measure()`, `ina226_start_single()` или `ina226_start_continuous()`).

### Параметры `ina226_config_t`

```c
typedef struct {
    float r_shunt_ohms;
    float max_expected_amps;
    ina226_avg_t avg;
    ina226_conv_t bus_ct;
    ina226_conv_t shunt_ct;
    uint8_t address;
    uint8_t measurements;
} ina226_config_t;
```

| Поле | Что задаёт | Значение по умолчанию |
| :--- | :--- | :--- |
| `r_shunt_ohms` | Номинал шунта, Ом. Используется при калибровке и пересчёте тока/мощности. | `0.1f` |
| `max_expected_amps` | Ожидаемый максимальный ток, А. Влияет на `Current_LSB` и коэффициент калибровки. | `1.0f` |
| `avg` | Усреднение АЦП (`AVG`, регистр `00h`). | `INA226_AVG_1` |
| `bus_ct` | Время преобразования канала `VBUS` (`VBUSCT`, регистр `00h`). | `INA226_CONV_TIME_1_1MS` |
| `shunt_ct` | Время преобразования канала `VSHUNT` (`VSHCT`, регистр `00h`). | `INA226_CONV_TIME_1_1MS` |
| `address` | 7-битный I2C-адрес INA226. | `INA226_I2C_DEFAULT_ADDR` (`0x40`) |
| `measurements` | Битовая маска измеряемых/читаемых величин (`ina226_measurements_t`). | `INA226_MEAS_ALL` |

### Допустимые значения

- `avg`: `INA226_AVG_1`, `INA226_AVG_4`, `INA226_AVG_16`, `INA226_AVG_64`, `INA226_AVG_128`, `INA226_AVG_256`, `INA226_AVG_512`, `INA226_AVG_1024`.
- `bus_ct` / `shunt_ct`: `INA226_CONV_TIME_140US`, `INA226_CONV_TIME_204US`, `INA226_CONV_TIME_332US`, `INA226_CONV_TIME_588US`, `INA226_CONV_TIME_1_1MS`, `INA226_CONV_TIME_2_116MS`, `INA226_CONV_TIME_4_156MS`, `INA226_CONV_TIME_8_244MS`.
- `address`: от `0x40` до `0x4F` включительно.
- `measurements`: комбинация флагов:
  - `INA226_MEAS_BUS_VOLTAGE`
  - `INA226_MEAS_SHUNT_VOLTAGE`
  - `INA226_MEAS_CURRENT`
  - `INA226_MEAS_POWER`
  - или сразу `INA226_MEAS_ALL`

> Нельзя передавать пустую маску (`0`). Должен быть выбран хотя бы один канал.

### Можно ли не задавать конфиг вручную?

Да. Можно полностью пропустить настройку и передать `NULL`:

```c
ESP_ERROR_CHECK(ina226_init(sensor, bus, NULL));
```

Это рабочий и рекомендуемый вариант для быстрого старта (он же используется в примерах в `examples/*`).

Если нужна точная подстройка под вашу схему (другой шунт, другой адрес, иные времена/усреднение), создайте конфиг от дефолта и поменяйте только нужные поля:

```c
ina226_config_t cfg = INA226_DEFAULT_CONFIG();
cfg.r_shunt_ohms = 0.02f;
cfg.max_expected_amps = 10.0f;
cfg.avg = INA226_AVG_16;
cfg.bus_ct = INA226_CONV_TIME_2_116MS;
cfg.shunt_ct = INA226_CONV_TIME_2_116MS;
cfg.address = 0x41;
cfg.measurements = INA226_MEAS_ALL;

ESP_ERROR_CHECK(ina226_init(sensor, bus, &cfg));
```

## Режим одиночного измерения

Одиночный режим (triggered) удобен, когда измерения нужны по запросу: например, раз в секунду, по событию или по команде от другого модуля.

В этой библиотеке есть два способа работы:

1. `ina226_measure(sensor, &measure)` — самый простой путь:
   - запускает одно преобразование в trigger-режиме,
   - ждёт рассчитанное время преобразования (с учётом `AVG`, `VBUSCT`, `VSHCT`),
   - проверяет готовность,
   - читает выбранные каналы в `ina226_measure_t`.

2. `ina226_start_single(sensor)` + `ina226_read_measure(sensor, &measure)` — ручной путь:
   - запуск преобразования делается отдельно,
   - ожидание/синхронизацию вы контролируете сами (например, через `ALERT`/`CNVR`),
   - чтение выполняется отдельным вызовом.

Режим `MODE` выбирается автоматически из `cfg.measurements`:
- только `INA226_MEAS_BUS_VOLTAGE` → `Bus trigger` (`010`),
- только шунт/ток (без мощности) → `Shunt trigger` (`001`),
- `INA226_MEAS_POWER` (в том числе без остальных флагов), смешанный набор или `INA226_MEAS_ALL` → `Shunt + Bus trigger` (`011`).

Пример (как в `examples/triggered_mode`):

```c
ESP_ERROR_CHECK(ina226_init(sensor, bus, NULL));

while (true) {
    ina226_measure_t measure = {0};
    esp_err_t err = ina226_measure(sensor, &measure);

    if (err == ESP_OK) {
        // Используйте measure.bus_voltage_v, measure.shunt_voltage_mv,
        // measure.current_a, measure.power_w
    }

    vTaskDelay(pdMS_TO_TICKS(1000));
}
```

> В triggered-режиме после каждого завершённого цикла для следующего измерения нужен новый запуск (через `ina226_measure()` или `ina226_start_single()`).

## Режим постоянного измерения

Постоянный режим (continuous) подходит для непрерывного мониторинга: INA226 сам циклически выполняет преобразования, а МК только читает свежие данные.

Базовый сценарий:
1. `ina226_start_continuous(sensor)` — переводит датчик в continuous-режим.
2. Периодически проверяйте готовность данных через `ina226_get_ready(sensor, &ready)`.
3. Когда `ready == true`, читайте значения через `ina226_read_measure(sensor, &measure)`.
4. При необходимости остановите измерения: `ina226_stop_continuous(sensor)` (переход в `Power-Down`).

Режим `MODE` также выбирается автоматически по маске `measurements`:
- только `INA226_MEAS_BUS_VOLTAGE` → `Bus continuous` (`110`),
- только шунт/ток (без мощности) → `Shunt continuous` (`101`),
- `INA226_MEAS_POWER` (в том числе без остальных флагов), смешанный набор или `INA226_MEAS_ALL` → `Shunt + Bus continuous` (`111`).

Пример (как в `examples/continuous_mode`):

```c
ESP_ERROR_CHECK(ina226_init(sensor, bus, NULL));
ESP_ERROR_CHECK(ina226_start_continuous(sensor));

while (true) {
    bool ready = false;

    while (!ready) {
        ESP_ERROR_CHECK(ina226_get_ready(sensor, &ready));
        if (!ready) {
            vTaskDelay(pdMS_TO_TICKS(10));
        }
    }

    ina226_measure_t measure = {0};
    ESP_ERROR_CHECK(ina226_read_measure(sensor, &measure));

    // Используйте measure.*
}
```

> `ina226_read_measure()` не меняет режим INA226: она только читает регистры выбранных каналов.

## Прерывание на пине ALERT при достижении порогового значения

Этот режим нужен, когда важен аппаратный сигнал при выходе измеряемой величины за порог (например, `VBUS` ниже допустимого уровня).

Базовый сценарий:
1. Инициализируйте датчик: `ina226_init(sensor, bus, cfg_or_null)`.
2. Настройте источник/условие/порог: `ina226_set_alert(...)`.
3. Запустите непрерывные измерения: `ina226_start_continuous(sensor)`.
4. В обработчике прерывания/таске прочитайте статус через `ina226_get_alert_status(sensor, &status)`.

Пример (как в `examples/threshold_alert`, срабатывание при `VBUS < 2.6V`):

```c
ESP_ERROR_CHECK(ina226_init(sensor, bus, NULL));

ESP_ERROR_CHECK(ina226_set_alert(sensor,
    INA226_ALERT_BUS_VOLTAGE,
    INA226_ALERT_MODE_LATCHED,
    INA226_ALERT_BELOW,
    2.6f));

ESP_ERROR_CHECK(ina226_start_continuous(sensor));

// ... после IRQ на ALERT
ina226_alert_status_t status = INA226_ALERT_STATUS_NONE;
ESP_ERROR_CHECK(ina226_get_alert_status(sensor, &status));

if (status == INA226_ALERT_STATUS_BUS_UNDER_LIMIT) {
    float vbus = 0.0f;
    ESP_ERROR_CHECK(ina226_read_bus_voltage(sensor, &vbus));
    // обработка аварии
}
```

Важно:
- `INA226_ALERT_MODE_TRANSPARENT` (`LEN=0`) — `ALERT` отпускается автоматически, когда условие ушло.
- `INA226_ALERT_MODE_LATCHED` (`LEN=1`) — `ALERT` защёлкивается до чтения регистра `06h`.
- В этой библиотеке чтение `ina226_get_alert_status()`/`ina226_get_alert_flags()` одновременно является подтверждением события (ACK): снимает защёлку `ALERT` (при `LEN=1`) и очищает соответствующие статус-флаги.

## Прерывания на пине ALERT при готовности данных

Этот режим полезен для синхронизации чтения «свежих» данных без постоянного polling.

Для включения используйте:
- `ina226_set_conversion_ready_alert(sensor, true)` — включает `CNVR`, переводит `ALERT` в прозрачный режим и отключает пороговые источники, чтобы `ALERT` использовался только под событие готовности преобразования.

Типовой поток (как в `examples/conversion_ready`):
1. `ina226_set_conversion_ready_alert(sensor, true)`.
2. Запустите измерение (`ina226_start_single(sensor)` для single-shot или continuous-режим).
3. Ждите IRQ от `ALERT`.
4. В таске прочитайте `ina226_get_alert_status(sensor, &status)` и убедитесь, что `status == INA226_ALERT_STATUS_CONVERSION_READY`.
5. Считайте данные через `ina226_read_measure(sensor, &measure)`.

Пример single-shot:

```c
ESP_ERROR_CHECK(ina226_init(sensor, bus, NULL));
ESP_ERROR_CHECK(ina226_set_conversion_ready_alert(sensor, true));

ESP_ERROR_CHECK(ina226_start_single(sensor));
// wait IRQ ...

ina226_alert_status_t status = INA226_ALERT_STATUS_NONE;
ESP_ERROR_CHECK(ina226_get_alert_status(sensor, &status));

if (status == INA226_ALERT_STATUS_CONVERSION_READY) {
    ina226_measure_t measure = {0};
    ESP_ERROR_CHECK(ina226_read_measure(sensor, &measure));
    // обработка measure.*
}
```

> Замечание: `ina226_get_ready(sensor, &ready)` тоже проверяет готовность по `CVRF` (через чтение `06h`), но это polling-подход. Для IRQ-сценария обычно удобнее `ALERT + ina226_get_alert_status()`.

## Режим работы Power-Down

В `Power-Down` INA226 не выполняет преобразования, но регистры остаются доступны по I2C.

Как используется в библиотеке:
- После `ina226_init()` устройство уже находится в `Power-Down`.
- `ina226_stop_continuous(sensor)` переводит датчик обратно в `Power-Down`.
- Выход из `Power-Down` — запуском измерений:
  - `ina226_start_single(sensor)`,
  - `ina226_start_continuous(sensor)`,
  - или `ina226_measure(sensor, &measure)` (внутри запускает trigger-цикл).

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

```c
ESP_ERROR_CHECK(ina226_init(sensor, bus, NULL)); // уже Power-Down

// ... когда нужно измерять
ESP_ERROR_CHECK(ina226_start_continuous(sensor));

// ... когда измерения больше не нужны
ESP_ERROR_CHECK(ina226_stop_continuous(sensor)); // снова Power-Down
```

Практически это удобно для снижения потребления в паузах между измерениями. При проектировании таймингов учитывайте, что выход из `Power-Down` требует времени (по даташиту INA226 — до десятков миллисекунд, обычно ориентируются на значение до ~40 мс).

## API

### Создание и жизненный цикл

- `esp_err_t ina226_create(ina226_handle_t *out_dev)` - Создание экземпляра драйвера (выделение памяти, без I2C-операций)
- `esp_err_t ina226_init(ina226_handle_t dev, i2c_master_bus_handle_t bus, ina226_config_t *cfg)` - Инициализация датчика на шине I2C, проверка чипа, сброс, калибровка и применение конфигурации (после инициализации устройство в `Power-Down`)
- `esp_err_t ina226_destroy(ina226_handle_t dev)` - Удаление устройства с I2C-шины и освобождение ресурсов

### Измерения и режимы работы

- `esp_err_t ina226_measure(ina226_handle_t dev, ina226_measure_t *measure)` - Выполнение полного одиночного trigger-цикла с ожиданием готовности и чтением каналов
- `esp_err_t ina226_start_single(ina226_handle_t dev)` - Запуск одиночного trigger-измерения без ожидания завершения
- `esp_err_t ina226_start_continuous(ina226_handle_t dev)` - Запуск непрерывных автономных измерений
- `esp_err_t ina226_get_ready(ina226_handle_t dev, bool *ready)` - Проверка флага готовности нового измерения (`CVRF`) для polling в continuous-режиме
- `esp_err_t ina226_stop_continuous(ina226_handle_t dev)` - Остановка непрерывных измерений и перевод в `Power-Down`

### Чтение измеренных величин

- `esp_err_t ina226_read_measure(ina226_handle_t dev, ina226_measure_t *measure)` - Чтение всех активных каналов без изменения текущего режима работы
- `esp_err_t ina226_read_bus_voltage(ina226_handle_t dev, float *voltage_v)` - Чтение напряжения шины (В)
- `esp_err_t ina226_read_shunt_voltage(ina226_handle_t dev, float *voltage_mv)` - Чтение напряжения на шунте (мВ)
- `esp_err_t ina226_read_current(ina226_handle_t dev, float *current_a)` - Чтение тока (А)
- `esp_err_t ina226_read_power(ina226_handle_t dev, float *power_w)` - Чтение мощности (Вт)
- `esp_err_t ina226_set_measurements(ina226_handle_t dev, uint8_t measurements)` - Настройка маски активных измерений (`ina226_measurements_t`) для `ina226_read_measure()` и `ina226_measure()`

### ALERT и пороговые события

- `esp_err_t ina226_set_alert(ina226_handle_t dev, ina226_alert_source_t source, ina226_alert_mode_t mode, ina226_alert_condition_t condition, float threshold)` - Настройка источника ALERT, режима (transparent/latched), условия (выше/ниже порога) и порога
- `esp_err_t ina226_disable_alert(ina226_handle_t dev)` - Отключение всех источников событий ALERT (с сохранением полярности `APOL`)
- `esp_err_t ina226_set_conversion_ready_alert(ina226_handle_t dev, bool enable)` - Включение/выключение сигнализации «данные готовы» (`CNVR`) на пине ALERT
- `esp_err_t ina226_get_alert_flags(ina226_handle_t dev, uint16_t *flags)` - Чтение сырых флагов регистра Mask/Enable (`0x06`)
- `esp_err_t ina226_get_alert_status(ina226_handle_t dev, ina226_alert_status_t *status)` - Чтение и декодирование причины последнего ALERT-события
- `const char *ina226_alert_status_to_str(ina226_alert_status_t status)` - Преобразование статуса ALERT в человекочитаемую строку

### Конфигурация по умолчанию

- `#define INA226_DEFAULT_CONFIG()` - Макрос для построения `ina226_config_t` со значениями по умолчанию (`Rshunt=0.1 Ом`, `Imax=1.0 А`, `AVG=1`, `CT=1.1 мс`, адрес `INA226_I2C_DEFAULT_ADDR`, измерения `INA226_MEAS_ALL`)

> Примечание: функции `ina226_get_alert_flags()` и `ina226_get_alert_status()` читают регистр `0x06` (Mask/Enable), а это подтверждает/сбрасывает часть статусных флагов INA226 (`CVRF`, а также latch ALERT при `LEN=1`).

## Лицензия

[MIT](./LICENSE)

Links

Supports all targets

To add this component to your project, run:

idf.py add-dependency "pkolt/ina226^1.0.0"

download archive

Stats

  • Archive size
    Archive size ~ 45.57 KB
  • Downloaded in total
    Downloaded in total 0 times
  • Downloaded this version
    This version: 0 times

Badge

pkolt/ina226 version: 1.0.0
|