Hello,
I am working with BQ27441-G1A fuelguage using I2C interface with microcontroller. I successfully communicate with BQ27441-G1A using I2C and successfully read and write. For your reference i attached my code. As you can see in my code in Fualguage_initialize() function i am writting Battery capicity, opconfig, Design Energy, Terminate Voltage, Taper Rate to fuelguage. And all those parameters successfully written to fuelguage which i verified by reading those values. And in Fualguage_Parameter() function i am reading Battery Percentage, Current, Voltage, Design Capacity, Full Capacity, Available Capacity, Battery charging/discharging status. I also attached hardware schematic for your reference. In my code i continuously calling Fualguage_Parameter() after some delay(which is 7 - 8 sec).
I am facing isuue which i mentioned below:
================= First scenario ====================
1) Consider currently i not connected USB charger with my board and my code displays Battery Percentage = 54% it works fine.
2) Now i connect USB charging cable to my board now battery is charging and it works fine.
3) Now i press reset switch in controller(still USB charging cable is attached to board) now in UART display Battery Percentage = 75%.
-- So here Battery Percentage increased abruptly with more difference than last reading. So here i am getting 21% difference which is much more than expected.
================= Second scenario ====================
1) Consider USB charging cable is already connected with my board and my code displays Battery Percentage = 75% it works fine.
2) Now i remove USB charging cable from my board now battery is discharging and it works fine.
3) Now i press reset switch in controller now in UART display Battery Percentage = 55%.
-- So here Battery Percentage decreased abruptly with more difference than last reading. So here i am getting 20% difference which is much more than expected.
These issues i am facing only if i connect/removes USB charging cable and reset the microcontroller else it works fine.
So why i am getting these much difference in Battery Percentage?
Please help me so that i can solve this issue.
Any help in this will be appreciated.
Thank You
Bhavin
===================================== Fuelguage Schematic ================================================
===================================== Battery Charger Schematic ================================================
======================================== main.c ================================================
#ifndef __FUALGUAGE_H
#define __FUALGUAGE_H
#define TIMEOUT 10000
#define BQ72441_I2C_TIMEOUT 2000
//----------------------- Battery parameters macros ---------------------------
#define BATTERY_CAPACITY 5000 // e.g. 800mAh battery
// DesignEnergy = BATTERY_CAPACITY(mAh) * 3.7V
#define DESIGN_ENERGY 18500
#define TERMINATE_VOLTAGE 3300 //TerminateVoltage = 3300mV
#define TAPER_CURRENT 115 //TaperCurrent = 115mA
// TAPER_RATE = (int)(BATTERY_CAPACITY / (0.1 * TAPER_CURRENT))
#define TAPER_RATE 434
#define TAPER_VOLTAGE 4200
#define SOC1_SET_THRESHOLD 10 //low battery threshold percentage interrupt
#define SOC1_CLEAR_THRESHOLD 11 //low battery threshold interrupt clear after reaching this percentage
#define FC_SET 98 //Charging terminates after this percentage
#define FC_CLEAR 95 //Flag's FC bit clear below this percentage
#define OPCONFIG 0x1DFC
typedef struct
{
uint8_t charging : 1;
uint8_t discharge : 1;
uint8_t Bat_Low : 1;
int16_t Percentage;
int16_t Current;
int16_t Design_Capacity;
int16_t Full_Capacity;
int16_t Avail_Capacity;
float Voltage;
}Battery;
typedef enum
{
SET_BATTERY_CAPACITY,
SET_OPCONFIG,
SET_DESIGN_ENERGY,
SET_TERMINATE_VOLTAGE,
SET_TAPER_RATE,
SET_TAPER_VOLTAGE,
SET_SOC1_THRESHOLD,
SET_FC_SET,
SET_FC_CLEAR,
SET_SOC1_CLEAR_THRESHOLD
}Fual_Guage_Init;
typedef enum
{
ENTER_CONFIG,
COMPUTE_BLOCK_CHKSUM,
GET_CHECKSUM,
WRITE_CHECKSUM,
EXIT_CONFIG
}Write_ExtendedData;
#define TIMER_EXPIRE FG_Timer_Flag >= 2
/* This delay is required for I2C read */
#define DELAY for(j = 0;j < 500;j++)
#define SOC1_CLR_THRESHOLD ((offset == 1) && (classID == 49))
#define DEDIGN_CAPACITY ((offset == 10) && (classID == 82))
#define FG_INITIALIZATION_COMPLETE FG_Init > SET_SOC1_CLEAR_THRESHOLD
// Parameters for the current() function, to specify which current to read
typedef enum {
AVG, // Average Current (DEFAULT)
STBY, // Standby Current
MAX // Max Current
} current_measure;
// Parameters for the capacity() function, to specify which capacity to read
typedef enum {
REMAIN, // Remaining Capacity (DEFAULT)
FULL, // Full Capacity
AVAIL, // Available Capacity
AVAIL_FULL, // Full Available Capacity
REMAIN_F, // Remaining Capacity Filtered
REMAIN_UF, // Remaining Capacity Unfiltered
FULL_F, // Full Capacity Filtered
FULL_UF, // Full Capacity Unfiltered
DESIGN // Design Capacity
} capacity_measure;
// Parameters for the soc() function
typedef enum {
FILTERED, // State of Charge Filtered (DEFAULT)
UNFILTERED // State of Charge Unfiltered
} soc_measure;
// Parameters for the soh() function
typedef enum {
PERCENT, // State of Health Percentage (DEFAULT)
SOH_STAT // State of Health Status Bits
} soh_measure;
// Parameters for the temperature() function
typedef enum {
BATTERY, // Battery Temperature (DEFAULT)
INTERNAL_TEMP // Internal IC Temperature
} temp_measure;
// Parameters for the setGPOUTFunction() funciton
typedef enum {
SOC_INT, // Set GPOUT to SOC_INT functionality
// BAT_LOW // Set GPOUT to BAT_LOW functionality <----- This is commented
} gpout_function;
///////////////////////
// General Constants //
///////////////////////
#define BQ27441_UNSEAL_KEY 0x8000 // Secret code to unseal the BQ27441-G1A
#define BQ27441_DEVICE_ID 0x0421 // Default device ID
///////////////////////
// Standard Commands //
///////////////////////
// The fuel gauge uses a series of 2-byte standard commands to enable system
// reading and writing of battery information. Each command has an associated
// sequential command-code pair.
#define BQ27441_COMMAND_CONTROL 0x00 // Control()
#define BQ27441_COMMAND_TEMP 0x02 // Temperature()
#define BQ27441_COMMAND_VOLTAGE 0x04 // Voltage()
#define BQ27441_COMMAND_FLAGS 0x06 // Flags()
#define BQ27441_COMMAND_NOM_CAPACITY 0x08 // NominalAvailableCapacity()
#define BQ27441_COMMAND_AVAIL_CAPACITY 0x0A // FullAvailableCapacity()
#define BQ27441_COMMAND_REM_CAPACITY 0x0C // RemainingCapacity()
#define BQ27441_COMMAND_FULL_CAPACITY 0x0E // FullChargeCapacity()
#define BQ27441_COMMAND_AVG_CURRENT 0x10 // AverageCurrent()
#define BQ27441_COMMAND_STDBY_CURRENT 0x12 // StandbyCurrent()
#define BQ27441_COMMAND_MAX_CURRENT 0x14 // MaxLoadCurrent()
#define BQ27441_COMMAND_AVG_POWER 0x18 // AveragePower()
#define BQ27441_COMMAND_SOC 0x1C // StateOfCharge()
#define BQ27441_COMMAND_INT_TEMP 0x1E // InternalTemperature()
#define BQ27441_COMMAND_SOH 0x20 // StateOfHealth()
#define BQ27441_COMMAND_REM_CAP_UNFL 0x28 // RemainingCapacityUnfiltered()
#define BQ27441_COMMAND_REM_CAP_FIL 0x2A // RemainingCapacityFiltered()
#define BQ27441_COMMAND_FULL_CAP_UNFL 0x2C // FullChargeCapacityUnfiltered()
#define BQ27441_COMMAND_FULL_CAP_FIL 0x2E // FullChargeCapacityFiltered()
#define BQ27441_COMMAND_SOC_UNFL 0x30 // StateOfChargeUnfiltered()
//////////////////////////
// Control Sub-commands //
//////////////////////////
// Issuing a Control() command requires a subsequent 2-byte subcommand. These
// additional bytes specify the particular control function desired. The
// Control() command allows the system to control specific features of the fuel
// gauge during normal operation and additional features when the device is in
// different access modes.
#define BQ27441_CONTROL_STATUS 0x00
#define BQ27441_CONTROL_DEVICE_TYPE 0x01
#define BQ27441_CONTROL_FW_VERSION 0x02
#define BQ27441_CONTROL_DM_CODE 0x04
#define BQ27441_CONTROL_PREV_MACWRITE 0x07
#define BQ27441_CONTROL_CHEM_ID 0x08
#define BQ27441_CONTROL_BAT_INSERT 0x0C
#define BQ27441_CONTROL_BAT_REMOVE 0x0D
#define BQ27441_CONTROL_SET_HIBERNATE 0x11
#define BQ27441_CONTROL_CLEAR_HIBERNATE 0x12
#define BQ27441_CONTROL_SET_CFGUPDATE 0x13
#define BQ27441_CONTROL_SHUTDOWN_ENABLE 0x1B
#define BQ27441_CONTROL_SHUTDOWN 0x1C
#define BQ27441_CONTROL_SEALED 0x20
#define BQ27441_CONTROL_PULSE_SOC_INT 0x23
#define BQ27441_CONTROL_RESET 0x41
#define BQ27441_CONTROL_SOFT_RESET 0x42
#define BQ27441_CONTROL_EXIT_CFGUPDATE 0x43
#define BQ27441_CONTROL_EXIT_RESIM 0x44
///////////////////////////////////////////
// Control Status Word - Bit Definitions //
///////////////////////////////////////////
// Bit positions for the 16-bit data of CONTROL_STATUS.
// CONTROL_STATUS instructs the fuel gauge to return status information to
// Control() addresses 0x00 and 0x01. The read-only status word contains status
// bits that are set or cleared either automatically as conditions warrant or
// through using specified subcommands.
#define BQ27441_STATUS_SHUTDOWNEN (1<<15)
#define BQ27441_STATUS_WDRESET (1<<14)
#define BQ27441_STATUS_SS (1<<13)
#define BQ27441_STATUS_CALMODE (1<<12)
#define BQ27441_STATUS_CCA (1<<11)
#define BQ27441_STATUS_BCA (1<<10)
#define BQ27441_STATUS_QMAX_UP (1<<9)
#define BQ27441_STATUS_RES_UP (1<<8)
#define BQ27441_STATUS_INITCOMP (1<<7)
#define BQ27441_STATUS_HIBERNATE (1<<6)
#define BQ27441_STATUS_SLEEP (1<<4)
#define BQ27441_STATUS_LDMD (1<<3)
#define BQ27441_STATUS_RUP_DIS (1<<2)
#define BQ27441_STATUS_VOK (1<<1)
////////////////////////////////////
// Flag Command - Bit Definitions //
////////////////////////////////////
// Bit positions for the 16-bit data of Flags()
// This read-word function returns the contents of the fuel gauging status
// register, depicting the current operating status.
#define BQ27441_FLAG_OT (1<<15)
#define BQ27441_FLAG_UT (1<<14)
#define BQ27441_FLAG_FC (1<<9)
#define BQ27441_FLAG_CHG (1<<8)
#define BQ27441_FLAG_OCVTAKEN (1<<7)
#define BQ27441_FLAG_ITPOR (1<<5)
#define BQ27441_FLAG_CFGUPMODE (1<<4)
#define BQ27441_FLAG_BAT_DET (1<<3)
#define BQ27441_FLAG_SOC1 (1<<2)
#define BQ27441_FLAG_SOCF (1<<1)
#define BQ27441_FLAG_DSG (1<<0)
////////////////////////////
// Extended Data Commands //
////////////////////////////
// Extended data commands offer additional functionality beyond the standard
// set of commands. They are used in the same manner; however, unlike standard
// commands, extended commands are not limited to 2-byte words.
#define BQ27441_EXTENDED_OPCONFIG 0x3A // OpConfig()
#define BQ27441_EXTENDED_CAPACITY 0x3C // DesignCapacity()
#define BQ27441_EXTENDED_DATACLASS 0x3E // DataClass()
#define BQ27441_EXTENDED_DATABLOCK 0x3F // DataBlock()
#define BQ27441_EXTENDED_BLOCKDATA 0x40 // BlockData()
#define BQ27441_EXTENDED_CHECKSUM 0x60 // BlockDataCheckSum()
#define BQ27441_EXTENDED_CONTROL 0x61 // BlockDataControl()
////////////////////////////////////////
// Configuration Offset //
////////////////////////////////////////
#define CAPACITY_OFFSET 10
#define DESIGN_ENERGY_OFFSET 12
#define TERMINATE_VTG_OFFSET 16
#define TAPERRATE_OFFSET 27
#define TAPER_VTG_OFFSET 29
#define OPCONFIG_OFFSET 0
#define SOC1_OFFSET 0
#define SOC1_CLEAR_OFFSET 1
#define FC_SET_OFFSET 5
#define FC_CLEAR_OFFSET 6
////////////////////////////////////////
// Configuration Class, Subclass ID's //
////////////////////////////////////////
// To access a subclass of the extended data, set the DataClass() function
// with one of these values.
// Configuration Classes
#define BQ27441_ID_SAFETY 2 // Safety
#define BQ27441_ID_CHG_TERMINATION 36 // Charge Termination
#define BQ27441_ID_CONFIG_DATA 48 // Data
#define BQ27441_ID_DISCHARGE 49 // Discharge
#define BQ27441_ID_REGISTERS 64 // Registers
#define BQ27441_ID_POWER 68 // Power
// Gas Gauging Classes
#define BQ27441_ID_IT_CFG 80 // IT Cfg
#define BQ27441_ID_CURRENT_THRESH 81 // Current Thresholds
#define BQ27441_ID_STATE 82 // State
// Ra Tables Classes
#define BQ27441_ID_R_A_RAM 89 // R_a RAM
// Calibration Classes
#define BQ27441_ID_CALIB_DATA 104 // Data
#define BQ27441_ID_CC_CAL 105 // CC Cal
#define BQ27441_ID_CURRENT 107 // Current
// Security Classes
#define BQ27441_ID_CODES 112 // Codes
/////////////////////////////////////////
// OpConfig Register - Bit Definitions //
/////////////////////////////////////////
// Bit positions of the OpConfig Register
#define BQ27441_OPCONFIG_BIE (1<<13)
#define BQ27441_OPCONFIG_BI_PU_EN (1<<12)
#define BQ27441_OPCONFIG_GPIOPOL (1<<11)
#define BQ27441_OPCONFIG_SLEEP (1<<5)
#define BQ27441_OPCONFIG_RMFCC (1<<4)
#define BQ27441_OPCONFIG_BATLOWEN (1<<2)
#define BQ27441_OPCONFIG_TEMPS (1<<0)
// Function Declaration
uint8_t begin(void);
uint8_t setCapacity(uint16_t capacity);
uint16_t voltage(void);
int16_t current(current_measure type);
uint16_t capacity(capacity_measure type);
int16_t power(void);
uint16_t soc(soc_measure type);
uint8_t soh(soh_measure type);
uint16_t temperature(temp_measure type);
uint16_t deviceType(void);
uint8_t enterConfig(uint8_t userControl);
uint8_t exitConfig(uint8_t resim);
uint16_t flags(void);
uint16_t status(void);
uint8_t sealed(void);
uint8_t seal(void);
uint8_t unseal(void);
uint16_t opConfig(void);
uint16_t readWord(uint16_t subAddress);
uint16_t readControlWord(uint16_t function);
uint8_t executeControlWord(uint16_t function);
uint8_t blockDataControl(void);
uint8_t blockDataClass(uint8_t id);
uint8_t blockDataOffset(uint8_t offset);
uint8_t blockDataChecksum(void);
uint8_t readBlockData(uint8_t offset);
uint8_t writeBlockData(uint8_t offset, uint8_t data);
uint8_t computeBlockChecksum(void);
uint8_t writeBlockChecksum(uint8_t csum);
uint16_t readExtendedData(uint8_t classID, uint8_t offset);
uint8_t writeExtendedData(uint8_t classID, uint8_t offset, uint8_t * data, uint8_t len);
uint8_t softReset(void);
uint8_t setDesign_Energy(uint16_t capacity);
uint8_t setTerminate_Voltage(uint16_t capacity);
uint8_t setTaper_Rate(uint16_t capacity);
uint16_t my_readBlockData(uint8_t offset);
void Fualguage_initialize(void);
void Fualguage_Parameter(void);
uint8_t setTaper_Voltage(uint16_t capacity);
uint8_t setGPOUT(uint16_t capacity);
uint8_t Set_SOC1_Threshold(uint16_t capacity);
uint8_t Clear_SOC1_Threshold(uint16_t capacity);
void read_battery_percentage(void);
void Check_Battery_Chg_Dischg(void);
uint8_t Set_FcSet_Threshold(uint16_t capacity);
uint8_t Set_FcClear_Threshold(uint16_t capacity);
void FG_I2C_Read(uint8_t Address,uint8_t read_bytes);
void FG_I2C_Write(uint8_t Address,uint8_t write_bytes,uint8_t *data);
#endif