This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

BQ27441-G1: Setting Capacity and Displaying Correct Values

Part Number: BQ27441-G1
Other Parts Discussed in Thread: BQSTUDIO

Hello,

We are using the bq27441-G1 fuel gauge ic for our battery monitoring system. below are the issue we are facing.

  1. Trouble Setting Battery Capacity:: Sometimes, I can't set the right capacity for our battery. It keeps defaulting to 1340 mAh. Could you explain how to update parameters correctly? And if there's a delay needed, what's the right amount?
  2. Showing Zero Values Despite Battery Voltage: When I start my application, even though the battery voltage is fine (around 4 volts), all the values on the gauge show up as 0 mAh(Remaining capacity,full available capacity). Do you think this is because of how we're gathering data or something about how the fuel gauge learns? If it's a learning issue, could you tell me the right steps to fix it?

 I have attached the log for above 2 problems.

Note : We are using custom PCB board for fuel gauge.

1. DesignCapacityWrite_issue.txt
Inside main
Device ID =1057
device successfully connected
Reading BMS Config
InputVoltageLimit = 6
InputCurrentLimit = 5
SysMinVoltage = 0
BoostModeCurrentLimit= 0
FastChargeCurrentLimit = 16
PreChargeCurrentLimit = 0
TerminationCurrentLimit= 0
ChargeVoltageLimit = 44
BatteryRechargeThr = 0
my getInputVoltageLimit = 6
my getInputCurrentLimit = 5
my getSysMinVoltage = 0
my getBoostModeCurrentLimit= 0
my getFastChargeCurrentLimit = 16
my getPreChargeCurrentLimit = 0
my getTerminationCurrentLimit= 0
my getChargeVoltageLimit = 44
my getBatteryRechargeThr = 0
Now in execute control word
in write extended data
after checksum data
wroteblock data
Now in execute control word
in write extended data
after checksum data
wroteblock data
Now in execute control word
in write extended data
after checksum data
wroteblock data
Now in execute control word
in write extended data
after checksum data
wroteblock data
MY Desired Full Design_capacity: 5000 mAh
MYFull Design_capacity: 1340 mAh
****************************************************************************************
My Voltage: 3781  mV
MY Current: -491  mA
MY Remaining Battery Capacity: 932  mAh
MYFull Full_capacity Capacity: 1207 mAh
MY Available_capacity Capacity: 976  mAh
MYFull AvailableFull_capacity: 1251 mAh
MY RemainingF_capacity: 932  mAh
MYFull RemainingUF_capacity: 932 mAh
MY FullF_capacity: 1207  mAh
MY FullF_capacity: 1207  mAh
MYFull Design_capacity: 1340 mAh
MY State of Charge: 78 p.c.
MY State of Health in percentage: 90 p.c.
MY Temperature: 28.100000 Deg C
MY Current date and time: 2024-03-11 11:50:36
Fuel Gauge flag =0x189
Fuel guage over temperature Flag = 0
Fuel guage under temperature Flag = 0
Fuel guage full charge detection Flag = 0
Fuel guage fast charging allowed Flag = 1
Fuel guage OCVTAKEN Flag = 1
Fuel guage ITPOR Flag = 0
Fuel guage CFGUPMODE Flag = 0
Fuel guage BAT DETECT Flag = 1
Fuel guage SOC1 Flag = 0
Fuel guage SOCF Flag = 0
Fuel guage DSG Flag = 1
Fuel Gauge status =0x8e
Fuel Gauge SHUTDOWNEN status =0
Fuel Gauge WDRESET status =0
Fuel Gauge SS status =0
Fuel Gauge CALMODE status =0
Fuel Gauge CCA status =0
Fuel Gauge BCA status =0
Fuel Gauge QMAX_UP status =0
Fuel Gauge RES_UP status =0
Fuel Gauge INITCOMP status =1
Fuel Gauge HIBERNATE status =0
Fuel Gauge SLEEP status =0
Fuel Gauge LDMD status =1
Fuel Gauge RUP_DIS status =1
Fuel Gauge VOK status =1
****************************************************************************************
system Status value read: 0
VBUS State =0
chrg status is 0
DPM status is 0
Power Good status is 0
VSYSMIN status is 0
Thermal status is 0
Charger Faults value read: 0
Watchdog fault is 0
OTG Fault is 0
Charging fault is 0
Battery fault is 0
NTC FAULT1 is 0
NTC FAULT0  is 0
2. Wrong_capacity_display.txt
My Voltage: 3782  mV
MY Current: -477  mA
MY Remaining Battery Capacity: 0  mAh
MYFull Full_capacity Capacity: 0 mAh
MY Available_capacity Capacity: 0  mAh
MYFull AvailableFull_capacity: 0 mAh
MY RemainingF_capacity: 0  mAh
MYFull RemainingUF_capacity: 0 mAh
MY FullF_capacity: 0  mAh
MY FullF_capacity: 0  mAh
MYFull Design_capacity: 5000 mAh
MY State of Charge: 0 p.c.
MY State of Health in percentage: 91 p.c.
MY Temperature: 29.100000 Deg C
MY Current date and time: 2024-03-11 11:58:44
Fuel Gauge flag =0x18f
Fuel guage over temperature Flag = 0
Fuel guage under temperature Flag = 0
Fuel guage full charge detection Flag = 0
Fuel guage fast charging allowed Flag = 1
Fuel guage OCVTAKEN Flag = 1
Fuel guage ITPOR Flag = 0
Fuel guage CFGUPMODE Flag = 0
Fuel guage BAT DETECT Flag = 1
Fuel guage SOC1 Flag = 1
Fuel guage SOCF Flag = 1
Fuel guage DSG Flag = 1
Fuel Gauge status =0x8c
Fuel Gauge SHUTDOWNEN status =0
Fuel Gauge WDRESET status =0
Fuel Gauge SS status =0
Fuel Gauge CALMODE status =0
Fuel Gauge CCA status =0
Fuel Gauge BCA status =0
Fuel Gauge QMAX_UP status =0
Fuel Gauge RES_UP status =0
Fuel Gauge INITCOMP status =1
Fuel Gauge HIBERNATE status =0
Fuel Gauge SLEEP status =0
Fuel Gauge LDMD status =1
Fuel Gauge RUP_DIS status =1
Fuel Gauge VOK status =0
****************************************************************************************
system Status value read: 0
VBUS State =0
chrg status is 0
DPM status is 0
Power Good status is 0
VSYSMIN status is 0
Thermal status is 0
Charger Faults value read: 0
Watchdog fault is 0
OTG Fault is 0
Charging fault is 0
Battery fault is 0
NTC FAULT1 is 0
NTC FAULT0  is 0

  • Hello Ashish, 

    How are you attempting to write the battery capacity, can you provide me with the steps you have taken? Are you using bqStudio to read and write to the gauge? Can you provide me with the gg file for this? 

    Regards, 

    Jonny. 

  • Hi,

    Currently i am interfacing this IC with our embedded Linux board, i have took reference from the Spark-fun library but changed all the low level interface according to my Linux board. This spark-fun library follows all step which are mention in bq27441-TRM page no 14.

    Note : I am not using bqStudio.

    below is the steps i wrote for fuel gauge setting.

    void config_gauge()
    {
      if (itporFlag())
      {
        setCapacity((uint16_t)bmsconfig.designCapacity);
        delay(2000);
        setDesignEnergy(bmsconfig.designCapacity * 3.7f);
        delay(2000);
        setTerminateVoltage(bmsconfig.terminalVoltage);
        delay(2000);
        setTaperRate(bmsconfig.designCapacity / (.01 * 100));
    
        printf("MY Desired Full Design_capacity: %d mAh\n", bmsconfig.designCapacity);
        printf("MYFull Design_capacity: %d mAh\n", capacity(DESIGN));
      }
    }

    And bellow is the low level code.

    int16_t i2cReadBytes(uint8_t subAddress, uint8_t *dest, uint8_t count)
    {
    	int16_t timeout = BQ72441_I2C_TIMEOUT;
    	I2cSendData(BQ72441_I2C_ADDRESS, &subAddress, 1);
    
    	I2cReadData(BQ72441_I2C_ADDRESS, dest, count);
    
    	return timeout;
    }
    
    void I2cSendData(uint8_t addr, uint8_t *data, uint8_t len)
    {
    	if (ioctl(deviceDescriptor, I2C_SLAVE, addr))
    		syslog(LOG_USER | LOG_INFO, "I2cSendData_device : IOCTL Problem \n");
    
    	write(deviceDescriptor, data, len);
    
    }
    
    /* This function reads data from the I2C device*/
    void I2cReadData(uint8_t addr, uint8_t *data, uint8_t len)
    {
    	if (ioctl(deviceDescriptor, I2C_SLAVE, addr))
    		syslog(LOG_USER | LOG_INFO, "I2cReadData_device : IOCTL Problem \n");
    
    	read(deviceDescriptor, data, len);
    }
    
    // // Write a specified number of bytes over I2C to a given subAddress
    uint16_t i2cWriteBytes(uint8_t subAddress, uint8_t *src, uint8_t count)
    {
    	uint8_t buf[3];
    	buf[0] = subAddress;
    	buf[1] = src[0];
    	buf[2] = src[1];
    
    	I2cSendData1(BQ72441_I2C_ADDRESS, buf, 3);
    	delay(1); //in ms
    
    	return true;
    }

  • Hello Ashish, 

    Please ensure that you are sending the SET_CFGUPDATE subcommand before attempting to change each parameter in the gauge. If you do not do this, then the gauge will not allow you to write new values. 

    Regards, 

    Jonny. 

  • Hi Jonny,

    I've ensured that the SET_CFGUPDATE sub command is properly configured before attempting to modify each parameter.Additionally, I've verified whether it successfully updates the state or not.

    Below is the code for your reference. Please review:

    
    _Bool setCapacity(uint16_t capacity)
    {
    	// Write to STATE subclass (82) of BQ27441 extended memory.
    	// Offset 0x0A (10)
    	// Design capacity is a 2-byte piece of data - MSB first
    	// Unit: mAh
    	uint8_t capMSB = capacity >> 8;
    	uint8_t capLSB = capacity & 0x00FF;
    	uint8_t capacityData[2] = {capMSB, capLSB};
    	return writeExtendedData(BQ27441_ID_STATE, 10, capacityData, 2);
    }
    
    _Bool writeExtendedData(uint8_t classID, uint8_t offset, uint8_t *data, uint8_t len)
    {
    	if (len > 32)
    		return false;
    
    	if (!_userConfigControl)
    		enterConfig(false);
    	printf("in write extended data\n");
    	if (!blockDataControl())	  // // enable block data memory control
    		return false;			  // Return false if enable fails
    	if (!blockDataClass(classID)) // Write class ID using DataBlockClass()
    		return false;
    
    	blockDataOffset(offset / 32); // Write 32-bit block offset (usually 0)
    	computeBlockChecksum();		  // Compute checksum going in
    	uint8_t oldCsum = blockDataChecksum();
    	printf("after checksum data\n");
    	//  Write data bytes:
    	for (int i = 0; i < len; i++)
    	{
    		// Write to offset, mod 32 if offset is greater than 32
    		// The blockDataOffset above sets the 32-bit block
    		writeBlockData((offset % 32) + i, data[i]);
    	}
    	printf("wroteblock data\n");
    	// Write new checksum using BlockDataChecksum (0x60)
    	uint8_t newCsum = computeBlockChecksum(); // Compute the new checksum
    	writeBlockChecksum(newCsum);
    
    	if (!_userConfigControl)
    		exitConfig(true);
    
    	return true;
    }
    _Bool enterConfig(_Bool userControl)
    {
    	if (userControl)
    		_userConfigControl = true;
    
    	if (sealed())
    	{
    		_sealFlag = true;
    		printf("doing unseal\n");
    		unseal(); // Must be unsealed before making changes
    	}
    	printf("Now in execute control word\n");
    	if (executeControlWord(BQ27441_CONTROL_SET_CFGUPDATE))
    	{
    		int16_t timeout = BQ72441_I2C_TIMEOUT;
    		while ((timeout--) && (!(flags() & BQ27441_FLAG_CFGUPMODE)))
    		{
    			printf("in while loop\n");
    			delay1(1);
    		}
    
    		if (timeout > 0)
    			return true;
    	}
    	printf("timeout occured\n");
    	return false;
    }
    
    
    
    

  • Hello Ashish, 

    I recommend following the examples from the Gauge Communication application report. 

    Regards, 

    Jonny.