There are standard instructions on the internet about how to perform a learning cycle, but in this article, I will explain how to practically perform a learning cycle in a real case for the used Device and why it may fail.
The data I have collected during this journey is attached via the link at the end of the article.
Disclaimer: The author of this article has no affiliation with Texas Instruments. This article is written for the purpose of personal and independent research by the author. It may contain mistakes and subjective judgments made by the author. The author disclaims any responsibility for the consequences of using the information provided in the article. The materials of the article are distributed as-is. Each person who uses the materials in practice assumes full responsibility for the consequences thereof.
Let's take the used Gas Gauging Device BQ28Z610 and connect some new batteries to it.
Learning Cycle
0. Unseal the Device
1. Configure the Device
First of all, we need to configure the device with the battery parameters, write them into Data Flash:
- Design Capacity mAh (pack Capacity) to address 0x462A;
- Design Energy cWh (pack Voltage * pack Capacity / 10) to 0x462C;
- expected Qmax Cell 0 word to 0x4206;
- expected Qmax Cell 1 word to 0x4208;
- expected Qmax Pack word to 0x420A;
- Gas Gauging Update Status: byte = 0x04 to 0x420E.
- Gas Gauging: Cycle Count word = 0 - for new battery, or some approx. value of recharging cycles - for used one to 0x4240;
Reset "R_a flags" in the Data Flash to the Default values:
- Cell0 R_a flag: addr = 0x4100, data = 0xFF55 - Cell impedance never updated; Table being used;
- Cell1 R_a flag: addr = 0x4140, data = 0xFF55 - Cell impedance never updated; Table being used;
- xCell0 R_a flag: addr = 0x4180, data = 0xFFFF - Cell impedance never updated; Table never used;
- xCell0 R_a flag: addr = 0x41C0, data = 0xFFFF - Cell impedance never updated; Table never used;
Ra Table |
⚠️ Don't forget about Little-endian. For example, 0xFF55 to 0x4100 means:
- 0x55 to 0x4100
- 0xFF to 0x4101
ℹ️ The documentation contains a warning about updating R_a flags:
Firmware updates these values: It is not recommended to change them manually.
But, since the firmware in this particular case does not reset the flags, when the Update Status is set to less than 06, I assume this is a possible bug, and we have to update the flags manually.
💡 Notice: If the R_a flags are not reset, the Update Status will be set to 06 instead of 05 in the future, as the device will consider the resistance table already updated.
For example, here is how the Ra Table looks before the Learning Cycle for a used Device:
Ra Table before start the Learning Cycle |
Qmax is the theoretical maximum charge capacity calculated based on real data of the passed charge during discharge and the depth of discharge (DOD). At the very beginning, it takes the value of Design Capacity in mAh.
Qmax Cell 0 = Qmax Cell 1 = Qmax Pack = Design Capacity
Manually setting the Gas Gauging Update Status to the value below 06 means that the Device should automatically update Qmax and Averaged cell resistance.
For example, there are four batteries, and we connect them in pairs in parallel, and then connect these two pairs in series:
Pack and Cells Capacity example |
2. Reset the Device
3. Unseal the Device
The Device automatically becomes sealed after reset.
4. Update Status = 04
Gas Gauging Update Status should be 04 (00000100), it means:
- Bit 2: Impedance Track gauging and lifetime: Enabled;
- Other bits = 0: The device is learning.
5. GaugingStatus()[RDIS] = 1
Usually, the resistance table is updated during discharging, so we need to disable resistance table updating during the initial discharge.
The flag GaugingStatus()[RDIS] should become high after reset, which means that the device will not update the resistance table until the battery is fully discharged. This flag clears when a rest in a fully discharged state is detected.
6. Discharge the battery to empty with any current
At this stage, the current does not influence anything, but a lower current is better because we need to discharge the battery as much as possible. For example, you may set the current to C/10, which should take approximately 10 hours.
The deeper the charge, the more accurate the calculation of Qmax will be.
7. Wait until relax
When the battery is fully discharged, wait until it enters a state of relaxation - when the flag GaugingStatus()[REST] becomes high: either after 5 hours or when each cell voltage change is less than 4 microvolts per second and Current > (-) "Quit Current" for "Dsg Relax Time" period.
💡 Notice: There is a typo in the official manual documentation, so the index of the REST flag in the result of the GaugingStatus() is 8, not 9.
Due to we can only observe millivolts readings, let's convert this value to that which can be used:
dV/dt = 4 uV/s = 0.004 mV/s
To determine how much time is needed to change the voltage by at least one volt:
dt = dV / [dV/dt]; dV = 1; dt = 1 / [dV/dt] = 1 / 0.004 mV/s = 250 s = 4m 10s
So, to reach a relaxed state, the voltage of each battery should not change by more than 1mV for at least 5 minutes.
How it happens in a real case:
Flags: RDIS (bit 10) = 0, REST (bit 8) = 1, BAL_EN (bit 4) = 1 |
8. Charge the Battery with C/2
This phase is necessary to determine the approximate value of the real Qmax, which is calculated using the amount of charge poured into the battery and the DOD0s before and after charging. For a new battery, this value will be more accurate than for an old one.
Charging is considered complete when the flags are set:
- ChargingStatus()[VCT] = 1;
- BatteryStatus()[FC] = 1.
9. Wait until relax
When the battery is fully charged, wait until GaugingStatus()[REST] becomes high, either after 2 hours or when the voltage of each cell does not change for 5 minutes and Current < "Quit Current" for "Chg Relax Time" period.
10. Update Status = 05
At this point Gas Gauging Update Status should become 05 (00000101), which means:
- Bit 2: Impedance Track gauging and lifetime updating is enabled;
- Bit 0: QMax updated.
Updated Qmax values in the Data Flash:
- Qmax Cell 0 (0x4206) = some value;
- Qmax Cell 1 (0x4208) = some value;
- Qmax Pack (0x420A) = min(Qmax Cell 0, Qmax Cell 1).
Qmax updated. Flags: QMax (bit 17) = 1, VOK (bit 11) =0, REST (bit 8) = 1 |
The Device is ready to learn Resistances of the Battery.
👉 Other possible values for the Update Status:
- If the value of Update Status is 06, it means that the R_a flags were not reset at the beginning, so the Device assumes the resistance table has been updated.
- If the value of Update Status remains 04, then something went wrong, and the device could not learn the correct value of Qmax. Let's clarify when this could occur.
Why the Update Status remains 04
According to the documentation, to update theQmax for the first time, the difference between the DOD0 after discharge and the DOD0 after charge should be greater than 90%.
You should already know what DOD (Depth Of Discharge) is and what it means, so I will not elaborate on this point. DOD0 just means DOD that corresponds to the OCV.
OCV - the voltage of the battery, may be called Open Circuit Voltage when it has remained without charging or discharging for 5 hours after the last discharging or 2 hours after charging, or when the voltage change becomes less than 4 microvolts per second.
Increasing battery voltage during relaxation after discharging |
You might have encountered the definition that the difference in DOD0s should be no less than 14745; otherwise, you should start the whole process over. But you may ask how 14745 corresponds to 90% of the DOD0 difference. The answer is that this value, 14745, is 90% of 16384, which is 2^14, so I assume that DOD0 is stored in the device as a 14-bit value.
14745 is a 90% of raw DOD0 difference |
Check the DOD0 difference using the DOD0 readings themselves
According to the "Technical Reference Manual", DOD0 of the battery can be obtained from the ITStatus3 (see "12.2.41 AltManufacturerAccess() 0x0075"). ITStatus3 returns 20 bytes in the following format: aaAAbbBBccCCddDDeeEEffFFggGGhhHHiiIIjjJJ, where:
- IIii (upper byte at index 17, lower byte at index 16): RawDOD0_1. Cell 1 raw DOD0 measurement;
- JJjj (index 19, index 18): RawDOD0_2. Cell 2 raw DOD0 measurement.
These values indicate the depth of discharge during the most recent OCV reading. The reported values are scaled to an integer value per DOD0 = DOD(OCV, Temperature) × 2^14 and has a range of 0 to 16383 (= 2^14 - 1).
To convert DOD0 raw value to percentage:
DOD0 percent = DOD0 raw / 16384 * 100;
For example, we got two DOD readings - one at rest after full discharge and another at rest after full charge:
- RawDOD0_1. Cell 1 raw DOD0 measurement: 12608
- RawDOD0_1. Cell 1 raw DOD0 measurement: 2144
Then the difference become:
12608 / 16384 * 100 ~ 77 % 2144 / 16384 * 100 ~ 13% 77 % - 13 % = 64 %; (12608 - 2144) / 16384 * 100 ~ 64 %.
64 % is less than 90 % that's why Qmax update was failed.
Thus, to ensure that the Learning Cycle will not fail, the DOD0 of the battery after the initial discharge should be greater than 15700 (96%) and should be below 1000 (6%) after the first charging.
Voltage Path for Determining the DOD0s
DOD0 corresponds to the OCV at a certain temperature. Let's consider that we have normal room temperature, then the dependence of DOD0 on OCV is as follows (there are many options, but I'll stick with this one):
DOD0, OCV, % mV 0 4180 10 4092 20 4013 30 3940 40 3877 50 3828 60 3792 70 3761 80 3717 90 3659 100 3052
Values in between may be calculated just by linear interpolation:
OCV interpolation |
Example:
DOD0 = 12%; OCV (10%) = 4092 mV; OCV (20%) = 4013 mV; OCV (12%) = OCV (10%) - - ( OCV (10%) - OCV (20%) ) * * ( 12 - 10 ) / ( 20 - 10 ) = = 4092 - (4092 - 4013) * 2 / 10 = = 4092 - 79 * 0.2 = 4076.2 mV.
To find the DOD0 from the OCV:
DOD0 interpolation |
Example:
OCV = 4076 mV; DOD0 (4092) = 10%; DOD0 (4013) = 20%; DOD0 (4076) = 10 + + (20 - 10) * (4092 - 4076) / (4092 - 4013) = = 10 + 10 * 16 / 79 = 12%.
Thus, we need the OCV after the initial discharge and after the first charge to determine the DOD0s.
In order for the value of Qmax to be successfully updated, the voltage in the relaxation state should remain as follows:
- after full discharge - below 3295 mV (DOD0 > 96%)
- after full charge - above 4127 mV (DOD0 < 6%)
So, if your battery cannot be charged lower the proper DOD0 due to quick self-discharge or cannot be discharged upper the proper DOD0 due to too high internal resistance, and as a result, the difference between these two DOD0 values cannot be greater than 90%, then the gas gauging device cannot be learned on this battery. Use another one.
Continue Learning Cycle with the Update Status = 05
Ra table when Update Status = 05 during rest |
11. Discharge the Battery with current between C/5 and C/10
Obviously, the discharge process should take between 5 and 10 hours. If it does not, then either the incorrect capacity was determined, or the battery is too old and its internal resistance is too high. I just warn you here, but will explain this moment later.
How resistances are stored in the Ra Table
The Ra Table is updated after some time during discharging:
The Ra Table during discharging |
A little bit later:
The Ra Table is being updated |
A large number of values at the right end of the first two rows change long before the discharging phase is finished. According to the document "Theory and Implementation of Impedance Track", the tables are compressed, which is why many values are updated. The decompression formula is:
R[0] = Base R; for i in [1..14]: R[i] = Base R + sum(R_compressed[k], k = 1 .. i) × 2^Gain;
I'm not completely sure, but I assume there is a small mistake in this formula, so I will try to explain it:
- Gain is equal to '-10' as specified in the 'Units' column of "Table 14-1. Data Flash Table" (see "Technical Reference Manual"). From the result of "12.2.39 AltManufacturerAccess() 0x0073 ITStatus1" at the 'Ra table scaling factor', we obtain the value '1000'. Both simply mean that resistances are stored in milliohms. I'm just not really sure if we should use 1/1024 ( = 2^-10) or 1/1000 to get Ohms.
- The base value of resistance should also be in the same scale.
- So, I assume that the decompression formula should be like this:
R_compressed[0] = Base R; // either milliohms or 1/1024 fraction of Ohm R[0] = R_compressed[0] * 2^-10 = = R_compressed[0] / 1024; // Ohms for i in [1..14]: R[i] = R[i - 1] + R_compressed[i] / 1024; // Ohms
- R0 - resistance when the battery is full;
- Each following resistance is based on the previous resistance plus the corresponding gained compressed resistance value.
After some amount of time (within 1 minute) after discharging stops, the Ra Table is updated to the end:
Ra Table just after discharging stops. The last two words are going to be updated |
Ra Table updated. High byte of the flag = 05 - RELAX mode and Qmax update in progress |
❗From the documentation:
Note that values of resistance normalized to 0°C are somewhat larger than values at room temperature and so cannot be directly compared with R=dV/I values.
The last two values (R[13] and R[14]) were not taken from real measurements but were fully calculated:
- Value [13] should be calculated from the real data at DOD0 = (100% - 3.3%) = 96.7%, but in my case, the battery could only be discharged to DOD0 = 94.5%.
- Value [14], which corresponds to DOD0 = 100%, cannot be calculated from the real data essentially.
12. Wait for relaxation (5 hours max)
13. Update Status = 06
At this point Gas Gauging Update Status should become 06 (00000110), which means:
- Bit 2: Impedance Track gauging and lifetime updating is enabled;
- Bit 1: Qmax and the Resistance table updated.
When the Update Status becomes 06, Qmax is updated, but the Ra Table remains unchanged, except the flag state:
Update Status = 06: QMax (bit 17) = 0, VOK (bit 11) = 0, REST (bit 8) = 1, BAL_EN (bit 4) = 1 |
Ra Table when Update Status becomes 06. The high byte of the Flag = 00 - Cell impedance and QMax updated |
14. Charge the Battery to full with current C/2
15. Wait for relaxation (2 hours max)
16. Update Status = 0E
And finally Gas Gauging Update Status should become 0x0E (00001110):
- Bit 3: QMax update in the field - it means updating the QMax value at the point of use, rather than in a laboratory. This may include updating QMax at the location of installation or battery operation, such as in a device or equipment.
- Bit 2: Impedance Track gauging and lifetime updating is enabled;
- Bit 1: QMax and the Resistance table updated.
I present the changes in the Device states during the Learning Cycle in the following diagram and table:
Learning Cycle states |
States during the Learning Cycle |
References
- Texas Instruments "How to Complete a Successful Learning Cycle for the bq28z610": https://www.ti.com/lit/an/slua777/slua777.pdf
- Texas Instruments "BQ28Z610 Technical Reference Manual" (Literature Number: SLUUA65E, last revised June 2023): https://www.ti.com/lit/ug/sluua65e/sluua65e.pdf
- Drawing equations: https://latex.codecogs.com/eqneditor/editor.php
- Real data collected during the Learning Cycle: https://docs.google.com/spreadsheets/d/1ULkVYpZ8078p32wp1VYqNTcCF_72ELvEJHNX8fBkniA/edit?usp=sharing
No comments:
Post a Comment