Hi Team,
I have about 10 battery packs with BMS. during my test, I understood that cell balancing for some packs doesn't work as I expected, and for some works correctly. for example, this pack has a problem with balancing.
and here is my config code
#define CELL_MAX_VOLTAGE 0x48 //3644 //mV devide by 50.6 #define CELL_MIN_VOLTAGE 0x2D //2277mv devide by 50.6 0x2d //BALANCING CONFIG #define BALANCE_MINVOLTAGE_RELAX 3370//mv minimmum of cell voltage for balancing in relax mode #define BALANCE_DELTASTART_RELAX 40//mv minimmum differnce between cell voltage for balancing in relax mode #define BALANCE_DELTASTOP_RELAX 20//mv minimmum differnce between cell voltage for ignoring in relax mode #define BALANCE_MINVOLTAGE_CHARGE 3370//mv minimmum of cell voltage for balancing in relax mode #define BALANCE_DELTASTART_CHARGE 40//mv minimmum differnce between cell voltage for balancing in relax mode #define BALANCE_DELTASTOP_CHARGE 20//mv minimmum differnce between cell voltage for ignoring in relax mode #define BALANCE_MAX_CELL 8 //This limits how many cells may be automatically balanced in parallel //PRECHARGE CONFIG #define PRECHARGE_STOP_VOLTAGE 2550//mv pro cell 2.6v * 16 = 41.6v #define PRECHARGE_START_VOLTAGE 2500//mv pro cell 0.5v * 16 = 41.6v ////////////////////////////////////////// Error_flag=CommandSubcommands(SET_CFGUPDATE); if(Error_flag) return Error_flag; //////////////////////////////Power and Reg configs ////////////////////////////// // 'Power Config' - 0x9234 = 0x2D80 // Setting the DSLP_LDO bit allows the LDOs to remain active when the device goes into Deep Sleep mode // Set wake speed bits to 00 for best performance Error_flag=BQ769x2_SetRegister(PowerConfig, 0x2D80, 2); if(Error_flag) return Error_flag; // 'REG0 Config' - set REG0_EN bit to enable pre-regulator Error_flag=BQ769x2_SetRegister(REG0Config, 0x01, 1); if(Error_flag) return Error_flag; //BQ769x2_SetRegister(REG0Config, 0x00, 1); // 'REG12 Config' - Enable REG1 with 5V output (0x0D for 3.3V, 0x0F for 5V) Error_flag=BQ769x2_SetRegister(REG12Config, 0x0F, 1); if(Error_flag) return Error_flag; //BQ769x2_SetRegister(REG12Config, 0x00 , 1); ////////Watch DOG //turn on and off reg for 7 second Error_flag=BQ769x2_SetRegister(HWDRegulatorOptions, 0x27, 1); if(Error_flag) return Error_flag; //10s with now communications will triger Watchdog Error_flag=BQ769x2_SetRegister(HWDDelay, 10, 2); if(Error_flag) return Error_flag; //////////////////////////////pin configs ////////////////////////////// // Set DFETOFF pin to control BOTH CHG and DSG FET - 0x92FB = 0x42 (set to 0x00 to disable) Error_flag=BQ769x2_SetRegister(DFETOFFPinConfig, 0x42, 1); if(Error_flag) return Error_flag; // Set up ALERT Pin - 0x92FC = 0x2A // This configures the ALERT pin to drive high (REG1 voltage) when enabled. // The ALERT pin can be used as an interrupt to the MCU when a protection has triggered or new measurements are available Error_flag=BQ769x2_SetRegister(ALERTPinConfig, 0x2A, 1); if(Error_flag) return Error_flag; // Set TS1 to measure Cell Temperature - 0x92FD = 0x07 Error_flag=BQ769x2_SetRegister(TS1Config, 0x07, 1); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(TS2Config, 0, 1); if(Error_flag) return Error_flag; // Set TS3 to measure Cell Temperature -0x92FF = 0x07 Error_flag=BQ769x2_SetRegister(TS3Config, 0x07, 1); if(Error_flag) return Error_flag; // Set HDQ to measure Cell Temperature - 0x9300 = 0x07 Error_flag=BQ769x2_SetRegister(HDQPinConfig, 0x07, 1); if(Error_flag) return Error_flag; // Set CFETOFF to measure Cell Temperature - 0x92FA = 0x07 Error_flag=BQ769x2_SetRegister(CFETOFFPinConfig, 0x07, 1); if(Error_flag) return Error_flag; // Set DDSG to measure MOSFET Temperature - 0x9302 = 0x0F Error_flag=BQ769x2_SetRegister(DDSGPinConfig, 0x0F, 1); if(Error_flag) return Error_flag; // Set DDSG to measure MOSFET Temperature - 0x9301 = 0x0F Error_flag=BQ769x2_SetRegister(DCHGPinConfig, 0x0F, 1); if(Error_flag) return Error_flag; //////////////////////////////cell und protection configs ////////////////////////////// // 'VCell Mode' - Enable 16 cells - 0x9304 = 0x0000; Writing 0x0000 sets the default of 16 cells Error_flag=BQ769x2_SetRegister(VCellMode, 0x0000, 2); if(Error_flag) return Error_flag; // Enable protections in 'Enabled Protections A' 0x9261 = 0xBC // Enables SCD (short-circuit), OCD2 (over-current in discharge), OCD1 (over-current in discharge), OCC (over-current in charge), // COV (over-voltage), CUV (under-voltage) Error_flag=BQ769x2_SetRegister(EnabledProtectionsA, 0xFC, 1); if(Error_flag) return Error_flag; // Enable all protections in 'Enabled Protections B' 0x9262 = 0xF7 // Enables OTF (over-temperature FET), OTINT (internal over-temperature), OTD (over-temperature in discharge), // OTC (over-temperature in charge), UTINT (internal under-temperature), UTD (under-temperature in discharge), UTC (under-temperature in charge) Error_flag=BQ769x2_SetRegister(EnabledProtectionsB, 0xF7, 1); if(Error_flag) return Error_flag; // Enable Precharge Timeout (PTO) Error_flag=BQ769x2_SetRegister(EnabledProtectionsC, 0x04, 1); if(Error_flag) return Error_flag; // 'Default Alarm Mask' - 0x..82 Enables the FullScan and ADScan bits, default value = 0xF800 Error_flag=BQ769x2_SetRegister(DefaultAlarmMask, 0xF882, 2); if(Error_flag) return Error_flag; //////////////////////////////cell balancing configs ////////////////////////////// // Set up Cell Balancing Configuration - 0x9335 = 0x03 - Automated balancing while in Relax or Charge modes // Also see "Cell Balancing with BQ769x2 Battery Monitors" document on ti.com Error_flag=BQ769x2_SetRegister(BalancingConfiguration, 0x03, 1); if(Error_flag) return Error_flag; //Relax mode Error_flag=BQ769x2_SetRegister(CellBalanceMinCellVRelax, BALANCE_MINVOLTAGE_RELAX, 2); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(CellBalanceMinDeltaRelax, BALANCE_DELTASTART_RELAX, 1); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(CellBalanceStopDeltaRelax, BALANCE_DELTASTOP_RELAX, 1); if(Error_flag) return Error_flag; //Charge mode Error_flag=BQ769x2_SetRegister(CellBalanceMinCellVCharge, BALANCE_MINVOLTAGE_CHARGE, 2); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(CellBalanceMinCellVCharge, BALANCE_DELTASTART_CHARGE, 1); if(Error_flag) return Error_flag; Error_flag= BQ769x2_SetRegister(CellBalanceMinCellVCharge, BALANCE_DELTASTOP_CHARGE, 1); if(Error_flag) return Error_flag; //Number of cell that we want to balancing in same time Error_flag=BQ769x2_SetRegister(CellBalanceMaxCells, BALANCE_MAX_CELL, 1); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(CellBalanceInterval,5, 1); if(Error_flag) return Error_flag; //////////////////////////////precharge configs ////////////////////////////// // start pre charge from 500mv pro cell until PRECHARGE_STOP_VOLTAGE pro cell Error_flag=BQ769x2_SetRegister(PrechargeStartVoltage, PRECHARGE_START_VOLTAGE, 2); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(PrechargeStopVoltage, PRECHARGE_STOP_VOLTAGE, 2); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(PTODelay, 18000, 2); //5 uhr precharge timeout (s) if(Error_flag) return Error_flag; //////////////////////////////predischarge configs ////////////////////////////// //Enable predischarge seq Error_flag=BQ769x2_SetRegister(FETOptions, 0x1D,1); if(Error_flag) return Error_flag; //set pre discharge timeout to 2.50 sec = 250 * 10 ms Error_flag=BQ769x2_SetRegister(PredischargeTimeout, 250,1); if(Error_flag) return Error_flag; //////////////////////////////shutdown protect configs ////////////////////////////// if(fail_status.OTP_FAIL==0) { Error_flag=BQ769x2_SetRegister(ShutdownStackVoltage, (PACK_SHUTDOWN_VOLTAGE/10), 2); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(LowVShutdownDelay, 10, 1); if(Error_flag) return Error_flag; } //////////////////////////////temp protection configs ////////////////////////////// Error_flag=BQ769x2_SetRegister(OTCThreshold, 45, 1);//charge over temp 10-45 according datasheet if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(OTCDelay, 2, 1); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(OTCRecovery, 40, 1); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(OTDThreshold, 55, 1);//discharge over temp -20-55 according datasheet if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(OTDDelay, 2, 1); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(OTDRecovery, 50, 1); if(Error_flag) return Error_flag; //mosfet over temp is defult 80 and bms internal temp is 85 //////////////////////////////voltage and currnet protection configs ////////////////////////////// // Set up CUV (under-voltage) Threshold - 0x9275 = 0x31 (2479 mV) // CUV Threshold is this value multiplied by 50.6mV Error_flag=BQ769x2_SetRegister(CUVThreshold, CELL_MIN_VOLTAGE, 1); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(CUVRecoveryHysteresis, 2 , 1); //that mean 2*50.6 mv more =101.2mv if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(BodyDiodeThreshold, 400 , 2); //set threshold to turn on dsg or cs mosfet after cuv or cov 400ma if(Error_flag) return Error_flag; // Set up COV (over-voltage) Threshold - 0x9278 = 0x48 3643 mV) // COV Threshold is this value multiplied by 50.6mV Error_flag=BQ769x2_SetRegister(COVThreshold, CELL_MAX_VOLTAGE, 1); if(Error_flag) return Error_flag; // Set up OCC (over-current in charge) Threshold - 0x9280 = 0x05 (14 mV = 14A across 1mOhm sense resistor) Units in 2mV Error_flag=BQ769x2_SetRegister(OCCThreshold, (PACK_MAX_CHARGE_CURRENT/2), 1); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(OCCRecoveryThreshold, 300, 2); if(Error_flag) return Error_flag; // Set up OCD1 Threshold - 0x9282 = 0x0A (20 mV = 20A across 1mOhm sense resistor) units of 2mV Error_flag=BQ769x2_SetRegister(OCD1Threshold, (PACK_MAX_DISCHARGE_CURRENT/2), 1); if(Error_flag) return Error_flag; // Set up OCD1 delay 100 *3.3ms = 3.3s Error_flag=BQ769x2_SetRegister(OCD1Delay,120, 1); if(Error_flag) return Error_flag; // Set up OCD2 Threshold - 0x9282 = 0x0A (20 mV = 20A across 1mOhm sense resistor) units of 2mV Error_flag=BQ769x2_SetRegister(OCD2Threshold, ((PACK_MAX_DISCHARGE_CURRENT+80)/2), 1); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(OCD2Delay,20, 1); if(Error_flag) return Error_flag; //set threshold to turn off ocd alert , ma Error_flag=BQ769x2_SetRegister(OCDRecoveryThreshold, 10, 2); if(Error_flag) return Error_flag; //set threshold to turn off ocdl alert , ma Error_flag=BQ769x2_SetRegister(OCDLRecoveryThreshold, 10, 2); if(Error_flag) return Error_flag; // Set up SCD Threshold - 0x9286 = 11 (300 mV = 200A across 1mOhm sense resistor) 0x05=100mV Error_flag=BQ769x2_SetRegister(SCDThreshold, 11 , 1); if(Error_flag) return Error_flag; // Set up SCD Delay - 0x9287 = 0x0B (150 us) Enabled with a delay of (value - 1) * 15 µs; min value of 1 Error_flag=BQ769x2_SetRegister(SCDDelay, 0x0B, 1); if(Error_flag) return Error_flag; // Set up SCDL Latch Limit to 1 to set SCD recovery only with load removal 0x9295 = 0x01 // If this is not set, then SCD will recover based on time (SCD Recovery Time parameter). Error_flag=BQ769x2_SetRegister(SCDLLatchLimit, 0x01, 1); if(Error_flag) return Error_flag; Error_flag=BQ769x2_SetRegister(MfgStatusInit, 0x0080, 2); if(Error_flag) return Error_flag; if((device_profile.calibration_current!=0)&&(device_profile.calibration_current!=-1)) { Error_flag=BQ769x2_SetRegister(BoardOffset, (device_profile.calibration_current*10) , 2); if(Error_flag) return Error_flag; } Error_flag=CommandSubcommands(EXIT_CFGUPDATE); if(Error_flag) return Error_flag;
as you see some cells are more than 3500mv and some less than 3350 mv so delta v is more than 150mv. I have COV protection because of cell 16 voltage. but there is no act in cell balancing to reduce cell16 voltage.
here is the cell balancing time for each cell. all the parameters are 0
and sometimes work cell balancing just for a few seconds at the beginning and will stop.
i have 16s lifepo4 battery
Best Regards,
Alireza