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.
/******************************************************************************* * 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; } } }
Sudhir Foujadar