Tool/software:
Hello,
I have been working with the BQ27441 for an embedded project. I have gotten it to work quiet well but I am coming up short with writing the new capacity. I have tested the chip and reading the Voltage, Temperature, and current are all correct and what is expected. I am writing this code in Python but when I read the capacity it still reading as the default value.
When I set the battery capacity I do the following;
unseal
enter extended mode
Write the register for the battery capacity
exit extended mode
seal
This does not produce any errors and the device works and gives me readings, but the capacity has not been updated. I am attaching the full code for this sample incase anyone in the future needs any help with getting started for a Raspberry pi or other Linux distros.
import smbus2 import time # I2C address of BQ27441 BQ27441_I2C_ADDR = 0x55 # Register addresses CONTROL_REG = 0x00 # Control register EXTENDED_DATA_CTRL = 0x3E # Extended Data Control register DESIGN_CAP_REG = 0x4B # Design Capacity register EXIT_CFGUPDATE_REG = 0x44 # Exit Config Mode SOC_REG = 0x1C # State of Charge register VOLTAGE_REG = 0x04 # Battery Voltage register CURRENT_REG = 0x10 # Average Current register TEMP_REG = 0x02 # Battery Temperature register REMAINING_CAP_REG = 0x0A # Remaining Capacity register SOH_Reg = 0x20 #State of health # Control Subcommands UNSEAL_KEY_1 = 0x8000 SEAL_COMMAND = 0x0020 ENTER_CFGUPDATE = 0x0013 # Battery capacity to set (mAh) BATTERY_CAPACITY = 4500 # Initialize I2C bus bus = smbus2.SMBus(1) def write_register(reg, value): """Writes a 16-bit value to the specified BQ27441 register.""" data = [value & 0xFF, (value >> 8) & 0xFF] # Low byte first bus.write_i2c_block_data(BQ27441_I2C_ADDR, reg, data) def read_register(reg): """Reads a 16-bit value from the specified BQ27441 register.""" data = bus.read_i2c_block_data(BQ27441_I2C_ADDR, reg, 2) return data[0] | (data[1] << 8) def unseal_battery(): """Unseals the BQ27441 to allow writing to protected registers.""" write_register(CONTROL_REG, UNSEAL_KEY_1) time.sleep(0.1) def seal_battery(): """Seals the BQ27441 to protect configuration settings.""" write_register(CONTROL_REG, SEAL_COMMAND) time.sleep(0.1) def enter_extended_mode(): """Enables Extended Mode for configuration changes.""" write_register(CONTROL_REG, ENTER_CFGUPDATE) # Enter Config Mode time.sleep(0.1) def exit_extended_mode(): """Exits Extended Mode and applies changes.""" write_register(EXIT_CFGUPDATE_REG, 0x00) # Exit Extended Mode time.sleep(0.1) def set_battery_capacity(capacity): """Sets the battery capacity in Extended Mode.""" unseal_battery() # Unseal before modifying protected settings enter_extended_mode() # Access Design Capacity Block write_register(EXTENDED_DATA_CTRL, 0x13) time.sleep(0.1) # Write new battery capacity write_register(DESIGN_CAP_REG, capacity) time.sleep(0.1) exit_extended_mode() seal_battery() # Reseal after configuration return read_register(DESIGN_CAP_REG) == capacity def get_battery_percentage(): """Reads the battery's state of charge (SOC) in percentage.""" return read_register(SOC_REG) def get_battery_voltage(): """Reads the battery voltage in millivolts (mV).""" return read_register(VOLTAGE_REG) def get_current_draw(): """Reads the battery current draw in mA (negative = discharge, positive = charge).""" raw_current = read_register(CURRENT_REG) if raw_current > 32767: # Convert two's complement for negative values raw_current -= 65536 return raw_current def get_battery_temperature(): """Reads the battery temperature in Celsius.""" raw_temp = read_register(TEMP_REG) # Temperature in 0.1 Kelvin temp_celsius = (raw_temp / 10.0) - 273.15 # Convert to Celsius return round(temp_celsius, 2) def get_remaining_capacity(): """Reads the remaining battery capacity in mAh.""" return read_register(REMAINING_CAP_REG) def get_state_of_health(): """Reads state of battery""" soh_data = read_register(SOH_Reg) return soh_data & 0xFF # Main execution if __name__ == "__main__": print("Initializing BQ27441...") if set_battery_capacity(BATTERY_CAPACITY): print(f"Battery capacity set to {BATTERY_CAPACITY} mAh") else: print("Failed to set battery capacity!") while True: battery_percentage = get_battery_percentage() battery_voltage = get_battery_voltage() current_draw = get_current_draw() battery_temperature = get_battery_temperature() remaining_capacity = get_remaining_capacity() state_of_health = get_state_of_health() print(f"Battery Percentage: {battery_percentage}%") print(f"Battery Voltage: {battery_voltage} mV") print(f"Current Draw: {current_draw} mA") print(f"Battery Temperature: {battery_temperature}°C") print(f"Remaining Capacity: {remaining_capacity} mAh") print(f"State of Health: {state_of_health}") print("-" * 40) time.sleep(2) # Delay before next reading