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.

BQ27441EVM-G1A: Battery percent showing higher after discharging.

Part Number: BQ27441EVM-G1A
Other Parts Discussed in Thread: BQ27411-G1, GPCCHEM

I have been working with fuel gauge IC BQ27411-G1.

We configured and found the battery percent. But after some time when we recheck with the battery percent.

It shown higher value than previous even after having long duration discharging.

Can someone share some technical notes or a sample code which repeatedly checks after specific time.

Also possible reason for getting such issue.

Attached is the schematic and procedure of reading code.

BQ27441-G1A.c
/*******************************************************************************
 * Macro defines
 ******************************************************************************/
/* TWI instance ID for BQ27441A */
#define TWI_INSTANCE_ID_BQ2774A 1

#define BQ27441_DEVICE_ADDR  (0xAAU >> 1)

//#define BQ27441_SCL_PIN          15     // SCL signal pin
//#define BQ27441_SDA_PIN          16    // SDA signal pin
//#define BQ27441_GPOUT            17    // BQ27441 GPOUT Pin


#define BQ27441_COMMAND_CONTROL         0x00       //Control
#define BQ27441_COMMAND_TEMP            0x02       //Temp
#define BQ27441_COMMAND_VOLTAGE         0x04       //Voltage mV
#define BQ27441_COMMAND_FLAGS           0x06       //Flags
#define BQ27441_COMMAND_NOM_CAPACITY    0x08       //NominalAvailableCapacity mAh
#define BQ27441_COMMAND_AVAIL_CAPACITY  0x0A       //FullAvailableCapacity mAh
#define BQ27441_COMMAND_REM_CAPACITY    0x0C       //RemainingCapacity mAh
#define BQ27441_COMMAND_FULL_CAPACITY   0x0E       //FullChargeCapacity mAh
#define BQ27441_COMMAND_AVG_CURRENT     0x10       //AverageCurrent mA
#define BQ27441_COMMAND_STDBY_CURRENT   0x12       //StandbyCurrent mA
#define BQ27441_COMMAND_MAX_CURRENT     0x14       //MaxLoadCurrent mA
#define BQ27441_COMMAND_AVG_POWER       0x18       //AveragePower mW
#define BQ27441_COMMAND_SOC             0x1C       //StateofCharge %
#define BQ27441_COMMAND_INT_TEMP        0x1E       //Internal Temp 0.1 degree K
#define BQ27441_COMMAND_SOH             0x20       //State of Health num/%
#define BQ27441_COMMAND_REM_CAP_UNFL    0x28       //RemainingCapacityUnfiltered mAh
#define BQ27441_COMMAND_REM_CAP_FIL     0x2A       //RemainingCapacityFiltered mAh
#define BQ27441_COMMAND_FULL_CAP_UNFL   0x2C       //FullChargeCapacityUnfiltered mAh
#define BQ27441_COMMAND_FULL_CAP_FIL    0x2E       //FullChargeCapacityFiltered mAh
#define BQ27441_COMMAND_SOC_UNFL        0x30       //StateOfChargeUnfiltered mAh 

#define BQ27441_REG_BlockDataControl   0x61       //BlockDataMemoryControl
#define BQ27441_REG_DataBlockClass     0x3E       //Design capacity Parameter
#define BQ27441_REG_DataBlock          0x3F       //BLock offset location
#define BQ27441_REG_BlockDataChecksum  0x60       //Block Data Cheksum
#define BQ27441_REG_DesignCapacity     0x4A       //DesignCapacity MSB Address
#define BQ27441_REG_DesignEnergy       0x4C       //DesignEnergy MSB Address
#define BQ27441_REG_TerminateVoltage   0x50       //Terminate Voltage Address
#define BQ27441_REG_TaperRate          0x5B       //Taper Rate Address

#define BQ27441_EXTENDED_BLOCKDATA     0x40
   
#define CFGUPMODE_BIT     0x10

#define CFGUPMODE_READ_FLAG_TIMEOUT 80


/*******************************************************************************
 * Variables
 ******************************************************************************/


unsigned char I2C_BQ27441_Read_Buffer[4];

/*******************************************************************************
 * Function Prototype Declarations
 ******************************************************************************/


void config_Guage_Parameters();
void read_battery_parameters();
void Check_gauge_memory(void);
uint8_t Read_Battery_SOC();



uint8_t Read_Battery_SOC()
{
#ifndef I2C_FUEL_GAUGE_BIT_BANG
    Enable_TWI_BQ27441();
#endif
    uint8_t Data_LSB;
    uint8_t SOC;
    uint8_t ret = false;
    
    //Read State of charge capacity %
    if(!I2C_BQ27441_Read(BQ27441_COMMAND_SOC, I2C_BQ27441_Read_Buffer, 0x02))
    {
        Fuel_Gauge_I2C_Init();
        config_Guage_Parameters();
    }
    Data_LSB = I2C_BQ27441_Read_Buffer[0];
    SOC =  Data_LSB;
#ifndef I2C_FUEL_GAUGE_BIT_BANG
    Disable_TWI_BQ27441();
#endif
    return SOC;
}

void config_Guage_Parameters()
{
  //  Enable_TWI_BQ27441();
    uint8_t ret_code = false;
    uint8_t Wr_Buffer[2];
    uint8_t Old_DesCap_MSB, Old_DesCap_LSB, Old_DesEner_MSB, Old_DesEner_LSB, Old_TermVolt_MSB, Old_TermVolt_LSB, Old_TaperRate_MSB, Old_TaperRate_LSB;
    uint8_t New_DesCap_MSB, New_DesCap_LSB, New_DesEner_MSB, New_DesEner_LSB, New_TermVolt_MSB, New_TermVolt_LSB, New_TaperRate_MSB, New_TaperRate_LSB;
    uint8_t Tmp_Chksum = 0;
    uint8_t Set_Chksum = 0;
    uint8_t New_Chksum = 0; 
    uint8_t Old_Chksum;
    uint8_t COMMAND_FLAG;

   //Steps to unseal the fuel guage
     Wr_Buffer[0] = 0x00;
     Wr_Buffer[1] = 0x80;
     ret_code = I2C_BQ27441_Write(BQ27441_COMMAND_CONTROL, Wr_Buffer, 0x02);
     ret_code = I2C_BQ27441_Write(BQ27441_COMMAND_CONTROL, Wr_Buffer, 0x02);
     

    //Steps to place guage into config update mode - Send SET_CFGUPDATE subcommand,
     Wr_Buffer[0] = 0x13;
     Wr_Buffer[1] = 0x00;
     ret_code = I2C_BQ27441_Write(BQ27441_COMMAND_CONTROL, Wr_Buffer, 0x02);

   //  nrf_delay_ms(1000);

    //Confirm configuration update by Reading flag register 4th bit is set
      COMMAND_FLAG = 0;      
        for(unsigned char i = CFGUPMODE_READ_FLAG_TIMEOUT; ((COMMAND_FLAG & 0x10) == 0x00) && (i>0); i--)
        {
            nrf_delay_ms(20);
            ret_code = I2C_BQ27441_Read(BQ27441_COMMAND_FLAGS, &COMMAND_FLAG, 0x01);
        }
        if((COMMAND_FLAG & 0x10) == 0)
        {
           //Error_code = Congiguration update error;
        }
      

    //steps to set up block RAM update
     Wr_Buffer[0] = 0x00;
     ret_code = I2C_BQ27441_Write(BQ27441_REG_BlockDataControl, Wr_Buffer, 0x01);
     Wr_Buffer[0] = 0x52;
     ret_code = I2C_BQ27441_Write(BQ27441_REG_DataBlockClass, Wr_Buffer, 0x01);
     Wr_Buffer[0] = 0x00;
     ret_code = I2C_BQ27441_Write(BQ27441_REG_DataBlock, Wr_Buffer, 0x01);


     //Read old Checksum
     ret_code = I2C_BQ27441_Read(BQ27441_REG_BlockDataChecksum, I2C_BQ27441_Read_Buffer, 0x01);
     Old_Chksum = I2C_BQ27441_Read_Buffer[0];
     Tmp_Chksum = 255 - Old_Chksum;

     //Read old Design Capacity bytes 
     ret_code = I2C_BQ27441_Read(BQ27441_REG_DesignCapacity, I2C_BQ27441_Read_Buffer, 0x02);
     Old_DesCap_MSB = I2C_BQ27441_Read_Buffer[0];
     Old_DesCap_LSB = I2C_BQ27441_Read_Buffer[1];

      //Read old Design Energy bytes
      ret_code = I2C_BQ27441_Read(BQ27441_REG_DesignEnergy, I2C_BQ27441_Read_Buffer, 0x02);
      Old_DesEner_MSB = I2C_BQ27441_Read_Buffer[0];
      Old_DesEner_LSB = I2C_BQ27441_Read_Buffer[1];

      //Read old Terminate voltage 
      ret_code = I2C_BQ27441_Read(BQ27441_REG_TerminateVoltage, I2C_BQ27441_Read_Buffer, 0x02);
      Old_TermVolt_MSB = I2C_BQ27441_Read_Buffer[0];
      Old_TermVolt_LSB = I2C_BQ27441_Read_Buffer[1];

      //Read old Taper rate
      ret_code = I2C_BQ27441_Read(BQ27441_REG_TaperRate, I2C_BQ27441_Read_Buffer, 0x02);
      Old_TaperRate_MSB = I2C_BQ27441_Read_Buffer[0];
      Old_TaperRate_LSB = I2C_BQ27441_Read_Buffer[1];

      //Calculate Tmp_Chksum
     Tmp_Chksum = Tmp_Chksum - Old_DesCap_MSB - Old_DesCap_LSB - Old_DesEner_MSB - Old_DesEner_LSB - Old_TermVolt_MSB - Old_TermVolt_LSB - Old_TaperRate_MSB - Old_TaperRate_LSB;
    
                                
     //Write new Design Capacity bytes - for 2600mAh (0x0A28)
     Wr_Buffer[0] = 0x0A;
     Wr_Buffer[1] = 0x28;
     ret_code = I2C_BQ27441_Write(BQ27441_REG_DesignCapacity, Wr_Buffer, 0x02);


     //Write Design Energy bytes -  for (2600mAh * 3.7) = 9620 (0x2594) 
     Wr_Buffer[0] = 0x25;
     Wr_Buffer[1] = 0x94;
     ret_code = I2C_BQ27441_Write(BQ27441_REG_DesignEnergy, Wr_Buffer, 0x02);

     //Write Terminate voltage (For 2800 mAh)
     Wr_Buffer[0] = 0x0A;
     Wr_Buffer[1] = 0xF0;
     ret_code = I2C_BQ27441_Write(BQ27441_REG_TerminateVoltage, Wr_Buffer, 0x02);

     //Write Taper rate (200) (Taper current - 130mA)
     Wr_Buffer[0] = 0x00;
     Wr_Buffer[1] = 0xC8;
     ret_code = I2C_BQ27441_Write(BQ27441_REG_TaperRate, Wr_Buffer, 0x02);


     //Read old Design Capacity bytes 
     ret_code = I2C_BQ27441_Read(BQ27441_REG_DesignCapacity, I2C_BQ27441_Read_Buffer, 0x02);
     New_DesCap_MSB = I2C_BQ27441_Read_Buffer[0];
     New_DesCap_LSB = I2C_BQ27441_Read_Buffer[1];

      //Read old Design Energy bytes
      ret_code = I2C_BQ27441_Read(BQ27441_REG_DesignEnergy, I2C_BQ27441_Read_Buffer, 0x02);
      New_DesEner_MSB = I2C_BQ27441_Read_Buffer[0];
      New_DesEner_LSB = I2C_BQ27441_Read_Buffer[1];

      //Read old Terminate voltage 
      ret_code = I2C_BQ27441_Read(BQ27441_REG_TerminateVoltage, I2C_BQ27441_Read_Buffer, 0x02);
      New_TermVolt_MSB = I2C_BQ27441_Read_Buffer[0];
      New_TermVolt_LSB = I2C_BQ27441_Read_Buffer[1];

      //Read old Taper rate
      ret_code = I2C_BQ27441_Read(BQ27441_REG_TaperRate, I2C_BQ27441_Read_Buffer, 0x02);
      New_TaperRate_MSB = I2C_BQ27441_Read_Buffer[0];
      New_TaperRate_LSB = I2C_BQ27441_Read_Buffer[1];


     //CalculateTmp_Chksum
     Tmp_Chksum = Tmp_Chksum + New_DesCap_MSB + New_DesCap_LSB + New_DesEner_MSB + New_DesEner_LSB + New_TermVolt_MSB + New_TermVolt_LSB + New_TaperRate_MSB + New_TaperRate_LSB; 
     New_Chksum = 0xFF - Tmp_Chksum;


     //Write new checksum 
     Wr_Buffer[0] = New_Chksum;
     ret_code = I2C_BQ27441_Write(BQ27441_REG_BlockDataChecksum, Wr_Buffer, 0x01);

     //Write BQ27441_REG_DataBlockClass
     Wr_Buffer[0] = 0x52;
     ret_code = I2C_BQ27441_Write(BQ27441_REG_DataBlockClass, Wr_Buffer, 0x01);
     Wr_Buffer[0] = 0x00;
     ret_code = I2C_BQ27441_Write(BQ27441_REG_DataBlock, Wr_Buffer, 0x01);
 

     //Read Checksum and checked matched or not with New_Chksum
     ret_code = I2C_BQ27441_Read(BQ27441_REG_BlockDataChecksum, I2C_BQ27441_Read_Buffer, 0x01);
     nrf_delay_ms(5);
     Set_Chksum = I2C_BQ27441_Read_Buffer[0];

     if(Set_Chksum == New_Chksum)
     {
        printf("\r\nChksum matched: RAM Update completed correctly");
     }
     else
     {
         printf("\r\nChksum not matched: RAM Update completed not correctly");
     }

  
    //Configuration Update by sending Soft Command to control register
     Wr_Buffer[0] = 0x42;
     Wr_Buffer[1] = 0x00;
     ret_code = I2C_BQ27441_Write(BQ27441_COMMAND_CONTROL, Wr_Buffer, 0x02);
   //  nrf_delay_ms(1000);

    // Confirm CONFIG UPDATE mode Exit by polling Flags register until bit 4 is clear.
     COMMAND_FLAG = 0xFF;
//     while((COMMAND_FLAG & 0x10) == 0x10)
//     {
//	 I2C_BQ27441_Read(BQ27441_COMMAND_FLAGS, &COMMAND_FLAG, 0x01);
//     }
      for(unsigned char i = CFGUPMODE_READ_FLAG_TIMEOUT; ((COMMAND_FLAG & 0x10) == 0x10) && (i>0); i--)
        {
            nrf_delay_ms(20);
            ret_code = I2C_BQ27441_Read(BQ27441_COMMAND_FLAGS, &COMMAND_FLAG, 0x01);
        }
        if((COMMAND_FLAG & 0x10) == 0x10)
        {
           //Error_code = Congiguration update error;
        }

     //Steps to seal the fuel guage
     Wr_Buffer[0] = 0x20;
     Wr_Buffer[1] = 0x00;
     ret_code = I2C_BQ27441_Write(BQ27441_COMMAND_CONTROL, Wr_Buffer, 0x02);
     nrf_delay_ms(5);
     nrf_delay_ms(100);
#ifndef I2C_FUEL_GAUGE_BIT_BANG
     Disable_TWI_BQ27441();
#endif
}


//In main Loop
void main()
{
    
    config_Guage_Parameters();    //Initilize the guage IC parameters
	battery_percent = Read_Battery_SOC();
	
	while()
	{
	    if(RTC_Alarm_Flag == 1)    //RTC alarm interrupt generated per hour 
		{
		    config_Guage_Parameters();                   
			battery_percent = Read_Battery_SOC();
			RTC_Interrupt_Flag = 0;
		}	   
	}
}


Scematic ofBQ27441_G1A.doc

Sudhir Foujadar