Power Measure
Power Measure IC (Integrated Circuit) is an integrated circuit used for monitoring and managing power supply. It can monitor various parameters of the power supply in real time, such as voltage, current, and power, and provide this information for system use. Power Measure ICs are crucial in various applications, including computers, power management systems, consumer electronics, industrial control systems, and communication devices.
This example demonstrates how to use the BL0937 and INA236 power measurement chips to detect electrical parameters such as voltage, current, active power, and energy(BL0937 only) consumption.
Features
- Measures voltage, current, active power, and energy. 
- Supports both BL0937 and INA236 power measurement chips. 
- Configurable chip selection via DEMO_BL0937 and DEMO_INA236 macros. 
- Supports overcurrent, overvoltage, and undervoltage protection. 
- Energy detection is enabled for accurate readings (BL0937 only). 
- Real-time measurements for INA236, cached measurements for BL0937. 
- Regularly fetches power readings every second and logs them. 
How It Works
The app_main() function in main/power_measure_example.c demonstrates the handle-based factory API:
- (Optional) Initialize I2C bus (INA236 only): - Use i2c_bus_create() with I2C_MASTER_SCL_IO/I2C_MASTER_SDA_IO to create the I2C bus. 
 
- Create a power measurement device: - Prepare common config power_measure_config_t (overcurrent/overvoltage/undervoltage thresholds, enable energy detection). 
- For BL0937, prepare power_measure_bl0937_config_t (CF/CF1/SEL pins, divider/sampling resistors, KI/KU/KP factors). 
- For INA236, prepare power_measure_ina236_config_t (I2C bus, address, alert config). 
- Call power_measure_new_bl0937_device() or power_measure_new_ina236_device() to get a power_measure_handle_t. 
 
- Fetch measurements periodically: - Use power_measure_get_voltage/current/active_power/power_factor() as needed; 
- power_measure_get_energy() returns valid data only on chips that support energy (e.g., BL0937); 
- The example logs values every 1 second. 
 
- Error handling: - If any API returns a non-ESP_OK value, log the error with ESP_LOGE. 
 
- Resource cleanup: - Release the device with power_measure_delete(handle); 
- For INA236, also release the I2C bus with i2c_bus_delete(&i2c_bus). 
 
Code Snippets
BL0937 (GPIO)
#include "power_measure.h"
#include "power_measure_bl0937.h"
power_measure_config_t common = {
    .overcurrent = 2000,
    .overvoltage = 250,
    .undervoltage = 180,
    .enable_energy_detection = true,
};
power_measure_bl0937_config_t bl = {
    .sel_gpio = GPIO_NUM_4,
    .cf1_gpio = GPIO_NUM_7,
    .cf_gpio = GPIO_NUM_3,
    .pin_mode = 0,
    .sampling_resistor = 0.001f,
    .divider_resistor = 1981.0f,
    .ki = 2.75f, .ku = 0.65f, .kp = 15.0f,
};
power_measure_handle_t h;
ESP_ERROR_CHECK(power_measure_new_bl0937_device(&common, &bl, &h));
float u,i,p,e;
power_measure_get_voltage(h, &u);
power_measure_get_current(h, &i);
power_measure_get_active_power(h, &p);
power_measure_get_energy(h, &e);
power_measure_delete(h);
INA236 (I2C)
#include "power_measure.h"
#include "power_measure_ina236.h"
#include "i2c_bus.h"
i2c_config_t conf = {
    .mode = I2C_MODE_MASTER,
    .sda_io_num = I2C_MASTER_SDA_IO, // GPIO_NUM_20
    .sda_pullup_en = GPIO_PULLUP_ENABLE,
    .scl_io_num = I2C_MASTER_SCL_IO, // GPIO_NUM_13
    .scl_pullup_en = GPIO_PULLUP_ENABLE,
    .master.clk_speed = 100000,
};
i2c_bus_handle_t bus = i2c_bus_create(I2C_NUM_0, &conf);
power_measure_config_t common = {
    .overcurrent = 15,
    .overvoltage = 260,
    .undervoltage = 180,
    .enable_energy_detection = false,
};
power_measure_ina236_config_t ina = {
    .i2c_bus = bus,
    .i2c_addr = 0x41,
    .alert_en = false,
    .alert_pin = -1,
    .alert_cb = NULL,
};
power_measure_handle_t h;
ESP_ERROR_CHECK(power_measure_new_ina236_device(&common, &ina, &h));
float u,i,p;
power_measure_get_voltage(h, &u);
power_measure_get_current(h, &i);
power_measure_get_active_power(h, &p);
power_measure_delete(h);
i2c_bus_delete(&bus);
Troubleshooting
BL0937 Issues:
- Failed Initialization : If the initialization fails, ensure that all GPIO pins are correctly defined and connected to the BL0937 chip. 
- Measurement Failures : If the measurements fail (e.g., voltage, current), verify that the BL0937 chip is properly powered and communicating with your ESP32 series chips. 
INA236 Issues:
- I2C Bus Initialization Failed : Check that the I2C pins (SDA/SCL) are correctly connected and not conflicting with other peripherals. 
- INA236 Not Detected : Verify the I2C address (default 0x41) and ensure the chip is properly powered. 
- Measurement Failures : Check I2C communication and ensure the INA236 chip is functioning correctly. 
- No Real-time Data : INA236 provides real-time measurements, so if you see cached values, check the power_measure component implementation. 
Adapted Products
| Name | Function | Vendor | Datasheet | HAL | 
|---|---|---|---|---|
| BL0937 | detect electrical parameters such as voltage, current, active power, and energy consumption | BELLING | √ | |
| INA236 | precision power monitor with I2C interface for voltage, current, and power measurement | TI | √ | 
API Reference
The following API implements hardware abstraction for power measure. Users can directly call this layer of code to write sensor applications.
Header File
Functions
- 
esp_err_t power_measure_delete(power_measure_handle_t handle)
- Delete a power measurement device. - Parameters
- handle – Power measure device handle 
- Returns
- ESP_OK: Success 
- ESP_ERR_INVALID_ARG: Invalid handle 
 
 
- 
esp_err_t power_measure_get_voltage(power_measure_handle_t handle, float *voltage)
- Get current voltage (V) - Parameters
- handle – Power measure device handle 
- voltage – Pointer to store the voltage value 
 
- Returns
- ESP_OK: Success 
- ESP_ERR_INVALID_ARG: Invalid arguments 
- ESP_ERR_INVALID_STATE: Device not initialized 
 
 
- 
esp_err_t power_measure_get_current(power_measure_handle_t handle, float *current)
- Get current current (A) - Parameters
- handle – Power measure device handle 
- current – Pointer to store the current value 
 
- Returns
- ESP_OK: Success 
- ESP_ERR_INVALID_ARG: Invalid arguments 
- ESP_ERR_INVALID_STATE: Device not initialized 
 
 
- 
esp_err_t power_measure_get_active_power(power_measure_handle_t handle, float *power)
- Get current active power (W) - Parameters
- handle – Power measure device handle 
- power – Pointer to store the power value 
 
- Returns
- ESP_OK: Success 
- ESP_ERR_INVALID_ARG: Invalid arguments 
- ESP_ERR_INVALID_STATE: Device not initialized 
 
 
- 
esp_err_t power_measure_get_power_factor(power_measure_handle_t handle, float *power_factor)
- Get power factor. - Parameters
- handle – Power measure device handle 
- power_factor – Pointer to store the power factor value 
 
- Returns
- ESP_OK: Success 
- ESP_ERR_INVALID_ARG: Invalid arguments 
- ESP_ERR_INVALID_STATE: Device not initialized 
- ESP_ERR_NOT_SUPPORTED: Chip doesn’t support this feature 
 
 
- 
esp_err_t power_measure_get_energy(power_measure_handle_t handle, float *energy)
- Get energy consumption (kWh) - Parameters
- handle – Power measure device handle 
- energy – Pointer to store the energy value 
 
- Returns
- ESP_OK: Success 
- ESP_ERR_INVALID_ARG: Invalid arguments 
- ESP_ERR_INVALID_STATE: Device not initialized 
- ESP_ERR_NOT_SUPPORTED: Chip doesn’t support this feature 
 
 
- 
esp_err_t power_measure_reset_energy_calculation(power_measure_handle_t handle)
- Reset energy calculation. - Parameters
- handle – Power measure device handle 
- Returns
- ESP_OK: Success 
- ESP_ERR_INVALID_ARG: Invalid handle 
- ESP_ERR_INVALID_STATE: Device not initialized 
- ESP_ERR_NOT_SUPPORTED: Chip doesn’t support this feature 
 
 
- 
esp_err_t power_measure_get_apparent_power(power_measure_handle_t handle, float *apparent_power)
- Get apparent power measurement. - Parameters
- handle – Power measure device handle 
- apparent_power – Pointer to store the apparent power value in volt-amperes (VA) 
 
- Returns
- ESP_OK: Success 
- ESP_ERR_INVALID_ARG: Invalid arguments 
- ESP_ERR_INVALID_STATE: Device not initialized 
- ESP_ERR_NOT_SUPPORTED: Chip doesn’t support this feature 
 
 
- 
esp_err_t power_measure_calibrate_voltage(power_measure_handle_t handle, float expected_voltage)
- Dynamic runtime calibration for voltage (BL0937 only) - Parameters
- handle – Power measure device handle 
- expected_voltage – The known reference voltage value in volts 
 
- Returns
- ESP_OK: Success 
- ESP_ERR_INVALID_ARG: Invalid arguments 
- ESP_ERR_INVALID_STATE: Device not initialized 
- ESP_ERR_NOT_SUPPORTED: Chip doesn’t support this feature 
 
 
- 
esp_err_t power_measure_calibrate_current(power_measure_handle_t handle, float expected_current)
- Dynamic runtime calibration for current (BL0937 only) - Parameters
- handle – Power measure device handle 
- expected_current – The known reference current value in amperes 
 
- Returns
- ESP_OK: Success 
- ESP_ERR_INVALID_ARG: Invalid arguments 
- ESP_ERR_INVALID_STATE: Device not initialized 
- ESP_ERR_NOT_SUPPORTED: Chip doesn’t support this feature 
 
 
- 
esp_err_t power_measure_calibrate_power(power_measure_handle_t handle, float expected_power)
- Dynamic runtime calibration for power (BL0937 only) - Parameters
- handle – Power measure device handle 
- expected_power – The known reference power value in watts 
 
- Returns
- ESP_OK: Success 
- ESP_ERR_INVALID_ARG: Invalid arguments 
- ESP_ERR_INVALID_STATE: Device not initialized 
- ESP_ERR_NOT_SUPPORTED: Chip doesn’t support this feature 
 
 
- 
esp_err_t power_measure_get_voltage_multiplier(power_measure_handle_t handle, float *multiplier)
- Get voltage multiplier (BL0937 only, advanced users) - Parameters
- handle – Power measure device handle 
- multiplier – Pointer to store the voltage multiplier value 
 
- Returns
- ESP_OK: Success 
- ESP_ERR_INVALID_ARG: Invalid arguments 
- ESP_ERR_INVALID_STATE: Device not initialized 
- ESP_ERR_NOT_SUPPORTED: Chip doesn’t support this feature 
 
 
- 
esp_err_t power_measure_get_current_multiplier(power_measure_handle_t handle, float *multiplier)
- Get current multiplier (BL0937 only, advanced users) - Parameters
- handle – Power measure device handle 
- multiplier – Pointer to store the current multiplier value 
 
- Returns
- ESP_OK: Success 
- ESP_ERR_INVALID_ARG: Invalid arguments 
- ESP_ERR_INVALID_STATE: Device not initialized 
- ESP_ERR_NOT_SUPPORTED: Chip doesn’t support this feature 
 
 
- 
esp_err_t power_measure_get_power_multiplier(power_measure_handle_t handle, float *multiplier)
- Get power multiplier (BL0937 only, advanced users) - Parameters
- handle – Power measure device handle 
- multiplier – Pointer to store the power multiplier value 
 
- Returns
- ESP_OK: Success 
- ESP_ERR_INVALID_ARG: Invalid arguments 
- ESP_ERR_INVALID_STATE: Device not initialized 
- ESP_ERR_NOT_SUPPORTED: Chip doesn’t support this feature POWER_MEASURE 
 
 
Structures
- 
struct power_measure_config_t
- Common power measure configuration. 
Type Definitions
- 
typedef struct power_measure_dev_t *power_measure_handle_t
- Power measure device handle.