Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MAX17048 Fuel Gauge Driver

ESP-IDF driver component for the MAX17048 battery fuel gauge IC with I2C interface and runtime configuration support.

Features

  • Accurate Battery Monitoring: Read State of Charge (SOC), voltage, and charge/discharge rate
  • I2C Master API: Uses latest ESP-IDF I2C master driver (no deprecation warnings)
  • Runtime Configuration: Flexible initialization without Kconfig dependencies
  • Shared Bus Support: Works with multiple I2C devices on the same bus
  • Low Power: Sleep mode support for power-conscious applications
  • Easy Integration: Simple API for quick battery monitoring implementation

Hardware Connection

The MAX17048 communicates via I2C and requires minimal external components:

ESP32           MAX17048
=====           ========
GPIO 0     →    SCL
GPIO 1     →    SDA
3.3V       →    VDD
GND        →    GND/VSS
Battery+   →    CELL+ (via 1kΩ resistor)
Battery-   →    CELL-

Note: External pull-up resistors (10kΩ) recommended for SCL/SDA lines.

Usage Example

Basic Initialization (New I2C Master API)

#include "max17048.h"
#include "driver/i2c_master.h"

void app_main(void)
{
    // Setup I2C master bus
    i2c_master_bus_handle_t i2c_bus;
    i2c_master_bus_config_t i2c_config = {
        .clk_source = I2C_CLK_SRC_DEFAULT,
        .i2c_port = I2C_NUM_0,
        .scl_io_num = GPIO_NUM_0,
        .sda_io_num = GPIO_NUM_1,
        .glitch_ignore_cnt = 7,
        .flags.enable_internal_pullup = false,  // Use external pull-ups
    };
    ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_config, &i2c_bus));
    
    // Configure MAX17048
    max17048_config_t max_config;
    max17048_get_default_config(&max_config);
    max_config.i2c_bus_handle = i2c_bus;
    max_config.device_address = 0x36;  // MAX17048 I2C address
    max_config.i2c_freq_hz = 100000;   // 100kHz I2C frequency
    
    // Initialize fuel gauge
    ESP_ERROR_CHECK(max17048_init_on_bus_with_config(&max_config));
    
    // Read battery data
    float soc, voltage, charge_rate;
    if (max17048_get_soc(&soc) == ESP_OK) {
        printf("Battery SOC: %.2f%%\\n", soc);
    }
    
    if (max17048_get_voltage(&voltage) == ESP_OK) {
        printf("Battery Voltage: %.3fV\\n", voltage);
    }
    
    if (max17048_get_crate(&charge_rate) == ESP_OK) {
        printf("Charge Rate: %.2f%%/hr\\n", charge_rate);
    }
}

Shared I2C Bus Example

// Multiple devices on same I2C bus
i2c_master_bus_handle_t shared_i2c_bus;

// Initialize MAX17048
max17048_config_t max_config;
max17048_get_default_config(&max_config);
max_config.i2c_bus_handle = shared_i2c_bus;
max_config.device_address = 0x36;
ESP_ERROR_CHECK(max17048_init_on_bus_with_config(&max_config));

// Initialize other I2C device on same bus
// other_device_init(shared_i2c_bus, other_address);

Battery Monitoring Task

void battery_monitor_task(void *pvParameters)
{
    while (1) {
        float soc, voltage, charge_rate;
        
        if (max17048_get_soc(&soc) == ESP_OK &&
            max17048_get_voltage(&voltage) == ESP_OK &&
            max17048_get_crate(&charge_rate) == ESP_OK) {
            
            printf("Battery Status: SOC=%.1f%%, V=%.2fV, Rate=%.1f%%/hr\\n", 
                   soc, voltage, charge_rate);
                   
            // Check for low battery
            if (soc < 10.0f) {
                printf("WARNING: Low battery!\\n");
            }
            
            // Check charging state
            if (charge_rate > 0.0f) {
                printf("Battery charging at %.1f%%/hr\\n", charge_rate);
            } else if (charge_rate < 0.0f) {
                printf("Battery discharging at %.1f%%/hr\\n", -charge_rate);
            }
        }
        
        vTaskDelay(pdMS_TO_TICKS(5000)); // Update every 5 seconds
    }
}

API Reference

Configuration Functions

  • max17048_get_default_config() - Get default configuration structure
  • max17048_init_on_bus_with_config() - Initialize with runtime configuration
  • max17048_deinit() - Deinitialize and cleanup resources

Battery Reading Functions

  • max17048_get_soc() - Read State of Charge (percentage)
  • max17048_get_voltage() - Read battery voltage (volts)
  • max17048_get_crate() - Read charge/discharge rate (%/hour)

Device Information

  • max17048_get_version() - Read device version
  • max17048_get_config_reg() - Read configuration register

Power Management

  • max17048_sleep() - Enter sleep mode
  • max17048_wake() - Wake from sleep mode
  • max17048_quick_start() - Force quick-start for accurate SOC

Legacy Support (Deprecated)

  • max17048_init() - Legacy initialization (returns ESP_ERR_NOT_SUPPORTED)
  • max17048_init_custom() - Legacy custom init (returns ESP_ERR_NOT_SUPPORTED)

Simple Wrapper Integration

For smartwatch applications, create a simple wrapper that handles initialization, monitoring, and 4.45V battery optimization:

Wrapper Implementation (main/battery_max17048.c)

#include "max17048.h"

static bool battery_initialized = false;
static TaskHandle_t battery_task_handle = NULL;

// Voltage-to-SOC mapping for 4.45V Li-ion battery
static const struct {
    float voltage;
    float soc;
} soc_map_4450mv[] = {
    {4.45, 100.0}, {4.40, 95.0}, {4.35, 90.0}, {4.30, 85.0}, {4.25, 80.0},
    {4.20, 75.0}, {4.15, 70.0}, {4.10, 65.0}, {4.05, 60.0}, {4.00, 55.0},
    {3.95, 50.0}, {3.90, 45.0}, {3.85, 40.0}, {3.80, 35.0}, {3.75, 30.0},
    {3.70, 25.0}, {3.65, 20.0}, {3.60, 15.0}, {3.55, 10.0}, {3.50, 5.0},
    {3.40, 0.0}
};

// Convert voltage to SOC using 4.45V battery profile
static float battery_voltage_to_soc_4450mv(float voltage)
{
    if (voltage >= 4.45) return 100.0;
    if (voltage <= 3.40) return 0.0;
    
    // Linear interpolation between points
    for (size_t i = 0; i < 20; i++) {
        if (voltage <= soc_map_4450mv[i].voltage && 
            voltage >= soc_map_4450mv[i+1].voltage) {
            float v_range = soc_map_4450mv[i].voltage - soc_map_4450mv[i+1].voltage;
            float soc_range = soc_map_4450mv[i].soc - soc_map_4450mv[i+1].soc;
            float v_offset = voltage - soc_map_4450mv[i+1].voltage;
            return soc_map_4450mv[i+1].soc + (v_offset / v_range) * soc_range;
        }
    }
    return 0.0f;
}

// Battery monitoring task
static void battery_task(void *pvParameters)
{
    while (1) {
        if (battery_initialized) {
            float voltage, raw_soc, charge_rate;
            
            if (max17048_get_voltage(&voltage) == ESP_OK &&
                max17048_get_soc(&raw_soc) == ESP_OK &&
                max17048_get_crate(&charge_rate) == ESP_OK) {
                
                // Calculate corrected SOC for 4.45V battery
                float corrected_soc = battery_voltage_to_soc_4450mv(voltage);
                
                ESP_LOGI("BATTERY", "SOC=%.1f%% (Raw: %.1f%%), V=%.2fV, Rate=%.1f%%/hr %s", 
                         corrected_soc, raw_soc, voltage, charge_rate,
                         charge_rate > 0 ? "(Charging)" : 
                         charge_rate < 0 ? "(Discharging)" : "(Standby)");
                
                // Low battery warnings
                if (corrected_soc <= 5.0f) {
                    ESP_LOGW("BATTERY", "CRITICAL: Battery very low!");
                } else if (corrected_soc <= 15.0f) {
                    ESP_LOGW("BATTERY", "WARNING: Low battery");
                }
            }
        }
        vTaskDelay(pdMS_TO_TICKS(5000)); // 5 second intervals
    }
}

// Simple initialization
esp_err_t battery_init_complete(i2c_master_bus_handle_t i2c_bus)
{
    if (battery_initialized) return ESP_OK;
    
    // Initialize MAX17048 (uses menuconfig settings)
    esp_err_t ret = max17048_init();
    if (ret != ESP_OK) return ret;
    
    // Verify communication
    uint16_t version;
    ret = max17048_get_version(&version);
    if (ret != ESP_OK) return ret;
    
    ESP_LOGI("BATTERY", "MAX17048 initialized - Version: 0x%04X", version);
    
    // Create monitoring task
    xTaskCreate(battery_task, "battery_task", 4096, NULL, 5, &battery_task_handle);
    
    battery_initialized = true;
    return ESP_OK;
}

// Simple status check for power management
bool battery_is_low(void)
{
    if (!battery_initialized) return false;
    
    float voltage;
    if (max17048_get_voltage(&voltage) == ESP_OK) {
        float soc = battery_voltage_to_soc_4450mv(voltage);
        return soc <= 15.0f; // Low battery threshold
    }
    return false;
}

// Get current status (simple interface)
esp_err_t battery_get_status(float *soc, float *voltage, float *charge_rate)
{
    if (!battery_initialized) return ESP_ERR_INVALID_STATE;
    
    float raw_voltage;
    esp_err_t ret = ESP_OK;
    
    if (voltage && max17048_get_voltage(&raw_voltage) == ESP_OK) {
        *voltage = raw_voltage;
        if (soc) *soc = battery_voltage_to_soc_4450mv(raw_voltage);
    } else {
        ret = ESP_FAIL;
    }
    
    if (charge_rate && max17048_get_crate(charge_rate) != ESP_OK) {
        ret = ESP_FAIL;
    }
    
    return ret;
}

Wrapper Usage in main()

void app_main(void)
{
    // Initialize I2C bus
    i2c_master_bus_handle_t i2c_bus;
    // ... I2C bus initialization ...
    
    // Initialize battery monitoring with simple wrapper
    ESP_ERROR_CHECK(battery_init_complete(i2c_bus));
    
    // Main loop with power management
    while (1) {
        // Check battery for power management decisions
        if (battery_is_low()) {
            ESP_LOGW(TAG, "Low battery - entering power save mode");
            // Implement power saving measures
        }
        
        // Get current battery status
        float soc, voltage, charge_rate;
        if (battery_get_status(&soc, &voltage, &charge_rate) == ESP_OK) {
            // Use battery data for UI display or system decisions
        }
        
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

Simple Wrapper Benefits

  1. 4.45V Battery Optimization: Custom voltage-to-SOC mapping for high-voltage batteries
  2. Automatic Monitoring: Background task handles periodic battery updates
  3. Power Management Integration: Simple functions for low battery detection
  4. Reduced Code Complexity: Hide component configuration and error handling
  5. Consistent Logging: Unified battery status reporting format
  6. Easy Maintenance: Component library updates don't affect main application

Configuration Structure

typedef struct {
    i2c_master_bus_handle_t i2c_bus_handle;  // I2C master bus handle
    uint8_t device_address;                  // I2C device address (0x36)
    uint32_t i2c_freq_hz;                    // I2C frequency in Hz
} max17048_config_t;

Technical Specifications

  • Supply Voltage: 2.5V to 5.0V
  • I2C Address: 0x36 (7-bit)
  • I2C Speed: Up to 400kHz
  • SOC Range: 0% to 100% (0.00390625% resolution)
  • Voltage Range: 0V to 5.12V (78.125µV resolution)
  • Rate Range: ±32%/hr (0.208%/hr resolution)
  • Operating Temperature: -40°C to +85°C

Error Codes

  • ESP_OK - Success
  • ESP_ERR_INVALID_ARG - Invalid argument
  • ESP_ERR_NOT_FOUND - Device not found on I2C bus
  • ESP_FAIL - I2C communication error
  • ESP_ERR_NOT_SUPPORTED - Legacy function not supported

Dependencies

  • driver - ESP-IDF driver framework
  • esp_common - ESP common utilities
  • freertos - FreeRTOS kernel
  • log - ESP logging framework

Migration from Legacy Driver

The component now uses the new I2C master API. Update your code:

// Old (deprecated)
max17048_init_custom(I2C_NUM_0, SDA_PIN, SCL_PIN);

// New (recommended)
max17048_config_t config;
max17048_get_default_config(&config);
config.i2c_bus_handle = your_i2c_bus_handle;
config.device_address = 0x36;
max17048_init_on_bus_with_config(&config);

Troubleshooting

  • Device not found: Check I2C wiring and pull-up resistors
  • Inaccurate readings: Perform quick-start calibration
  • Communication errors: Verify I2C frequency and bus configuration
  • Power issues: Ensure proper supply voltage (2.5V-5.0V)

License

This component is provided under the MIT license.

Datasheet

For detailed specifications, refer to the MAX17048 Datasheet.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages