Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BMS / individual cell data for batteries #603

Open
tkurki opened this issue Dec 25, 2020 · 6 comments
Open

BMS / individual cell data for batteries #603

tkurki opened this issue Dec 25, 2020 · 6 comments

Comments

@tkurki
Copy link
Member

tkurki commented Dec 25, 2020

LiFePO4 batteries are getting more common. They require more detailed management that is typically handled by a Battery Management System. BMSs can produce data on a cell as opposed to battery level and this data is relevant if you want to monitor the performance and health of a LiFePO4 battery.

@tkurki
Copy link
Member Author

tkurki commented Dec 25, 2020

Per cell data:

  • voltage
  • temperature

BMS data:

  • balancing - what data is there about balancing?
  • overcurrent/overvoltage/undervoltage/undertemperature protection states and settings

@GHBLoos
Copy link

GHBLoos commented Mar 29, 2021

My initial thoughts:

All LPF battery-cell have these charasteristics (please check those):
Voltage

  • charge voltage 3.6v
  • nominal voltage: 3.2v
  • minimum discharge voltage: 2.5v
  • maximum charge voltage: 3.65v
  • cut-off charge voltage 3.9v

Current

  • Overcurrent

Environment

  • Charge Temperature 0-45C @ 35%-85% humidity
  • Discharge Temperature -20-60C @ 35%-85% humidity
  • Discharge Cut-off Voltage 0-45C @ 35%-85% humidity
    Cell temperature
    (I can't find any numbers for that yet)

A LPF battery used for 12v is a package of 4 cells.
A LPF battery used for 24v is a package of 8 cells.
That means that you have to multiply the battery-cell voltage 4 or 8 times.

Keys

I am thinking of the following keys (starting with /vessels/<RegExp>/electrical/batteries/<RegExp>)

static numbers (constants):

chemistry = LiFePO4
cell.voltage.nominal = 3.2
cell.voltage.dischargeLimit =2.5
cell.voltage.chargeLimit = 3.6
cell.voltage.dischargeCutOff
cell.voltage.chargeCutOff= 3.9
cell.current.overCurrentProtection =
cell.environment.ChargeMinTemperature = 0C
cell.environment.ChargeMaxTemperature = 45C
cell.environment.DischargeMinTemperature = -20C
cell.environment.DischargeMaxTemperature = 60C
cell.environment.MinRelativeHumidity = 35%
cell.environment.MaxRelativeHumidity = 85%

battery specific numbers

numberOfCells (4=12v, 8=24v)
cell.capacity [amp * hour]

calculated static numbers

voltage.nominal (numberOfCells * cell.voltage.nominal)
voltage.dischargeLimit (numberOfCells * cell.voltagedischargeLimit)
voltage.chargeLimit (numberOfCells * cell.voltage.chargeLimit)
voltage.dischargeCutOff (numberOfCells * cell.voltage.dischargeCutOff)
voltage.chargeCutOff (numberOfCells * cell.voltage.chargeCutOff)
current.overCurrentProtection ( = cell.current.overCurrentProtection)
environment.*

measured numbers

cell.<#>.voltage
cell.<#>.temperature
environment.temperature
environment.relativeHumidity

calculated numbers

capacity.nominal (=cell.capacity.nominal)
capacity.actual (=depends on environmental temperature and/or cell temperature)
capacity.stateOfCharge
capacity.depthOfDischarge
cell.<#>.capacity.stateOfCharge
cell.<#>.capacity.depthOfDischarge

status

online (is the battery available for switching on or off)
switch (is the battery switched on (relay switch))
protected (is the battery protected from being used/from being switched on)
unbalanced (cells are unbalanced)

@natecostello
Copy link

A scattering of initial thoughts/comments:

This is a really good start. I've tried to provide examples of where at least one BMS, (the REC Q) overlaps/aligns with what you've proposed.

My initial thoughts:

All LPF battery-cell have these charasteristics (please check those):
Voltage

  • charge voltage 3.6v
  • nominal voltage: 3.2v
  • minimum discharge voltage: 2.5v
  • maximum charge voltage: 3.65v
  • cut-off charge voltage 3.9v

REC Q BMS has similar parameters and a few extras:

  • balance end voltage (BVOL) (e.g., 3.58V)
  • balance start voltage (BMIN) (e.g., 3.45V)
  • cell end of charge voltage (CHAR) (e.g., 3.58V)
  • cell over voltage switch off (CMAX) (e.g., 3.85V)
  • cell under voltage protection switch off (CMIN) (e.g., 2.8V)
  • cell under voltage discharge protection (CLOW) (e.g., 2.9V)

I'm not sure of the value of reporting a static nominal voltage, but am open to it.

Current

  • Overcurrent

REC Q BMS doesn't have any explicit over current protection as far as I can tell. This function is provided by fusing/breakers outside of the BMS control. BMS's that don't rely on external contactors (ie, have internal FETs) probably do enforce current limits. The REC Q does report limits that CAN connected sources and sinks are ideally supposed to observe.

Environment

  • Charge Temperature 0-45C @ 35%-85% humidity
  • Discharge Temperature -20-60C @ 35%-85% humidity
  • Discharge Cut-off Voltage 0-45C @ 35%-85% humidity
    Cell temperature
    (I can't find any numbers for that yet)

REC Q BMS parameters:

  • cell over temperature switch-off (TMAX) (e.g, 55C)
  • Under temperature charging disable (TMIN) (e.g, -10C)

A LPF battery used for 12v is a package of 4 cells.
A LPF battery used for 24v is a package of 8 cells.
That means that you have to multiply the battery-cell voltage 4 or 8 times.

Not necessarily. My battery design is 2P8S, so 16 cells, but 24V. The topology is needed to get from cell number to voltage or capacity. That said, I'm not advocating for including a topology field. As reflected in comments below, I'm not convinced we should be calculating pack level parameters from cell level parameters.

Keys

I am thinking of the following keys (starting with /vessels/<RegExp>/electrical/batteries/<RegExp>)

static numbers (constants):

chemistry = LiFePO4
cell.voltage.nominal = 3.2
cell.voltage.dischargeLimit =2.5
cell.voltage.chargeLimit = 3.6
cell.voltage.dischargeCutOff
cell.voltage.chargeCutOff= 3.9
cell.current.overCurrentProtection =
cell.environment.ChargeMinTemperature = 0C
cell.environment.ChargeMaxTemperature = 45C
cell.environment.DischargeMinTemperature = -20C
cell.environment.DischargeMaxTemperature = 60C
cell.environment.MinRelativeHumidity = 35%
cell.environment.MaxRelativeHumidity = 85%

battery specific numbers

numberOfCells (4=12v, 8=24v)
This doesn't account for parallel cells (e.g., a 2P8S topology).

cell.capacity [amp * hour]

Cell capacity is not meaningful without specifying a topology (e.g. I have 280AH cells, but my pack is 2P8S, so pack capacity != cell capacity). I can't off hand think of a situation where you would care about cell capacity individually, but happy to be convinced.

calculated static numbers

voltage.nominal (numberOfCells * cell.voltage.nominal)
voltage.dischargeLimit (numberOfCells * cell.voltagedischargeLimit)
voltage.chargeLimit (numberOfCells * cell.voltage.chargeLimit)
voltage.dischargeCutOff (numberOfCells * cell.voltage.dischargeCutOff)
voltage.chargeCutOff (numberOfCells * cell.voltage.chargeCutOff)
current.overCurrentProtection ( = cell.current.overCurrentProtection)
environment.*

A few of these numbers, depending on the BMS, are not static, and also would not reflect the above calculation. The REC BMS reports/commands semi-dynamic dynamic values for the above or similar values (acted on by systems like Victron in DVCC modes):
voltage.chargeLimit
voltage.dischargeLimit
current.dischargeLimit

Additionally, since the cell based protections are cell based, reporting/calculating pack level limits from the cell based limits are not meaningful unless all cells were perfectly balanced and identical. Meaning, I will always get a low voltage protection cutoff at some voltage above voltage.dischargeCutoff because it actuates on the lowest cell, while other cells are still higher.

measured numbers

cell.<#>.voltage
cell.<#>.temperature
environment.temperature
environment.relativeHumidity

I'm not sure of any guidance on operation with respect to relative humidity. I'm also not aware of any BMS's that monitor or report it.

Regarding cell temperatures, the REC Q supports up to three temperature sensors, which aren't necessarily related to specific cells (but could). I do know that at least one other BMS (the EPS) does report a temperature for each cell. I think however this ends up, there it must account somehow for these two different cases.

calculated numbers

capacity.nominal (=cell.capacity.nominal)
capacity.actual (=depends on environmental temperature and/or cell temperature)
capacity.stateOfCharge
capacity.depthOfDischarge
cell.<#>.capacity.stateOfCharge
cell.<#>.capacity.depthOfDischarge

I'm not sure state of charge is relevant from a cell perspective.
Is depthOfDischarge simply 1-SOC?
To this list, though not necessarily on a cell basis, I would add stateOfHealth which is reported by some BMS's.

status

online (is the battery available for switching on or off)
switch (is the battery switched on (relay switch))
protected (is the battery protected from being used/from being switched on)
unbalanced (cells are unbalanced)

I think more relevant than unbalanced is whether the BMS is balancing. That said, the BMS I am most familiar with doesn't not explicitly report when it is balancing.

@GHBLoos
Copy link

GHBLoos commented Apr 5, 2021

That's good feedback!

  • I read in some articles that unbalanced cells are determined by comparing the individual state of charge (SOC) of a cell. That would mean that every cell has a SOC.
  • Some batteries don't have a balancing function build in. In fact, if you stay between certain voltage charge and discharge limits, it is very rare that your cells will get unbalanced (so a way to prevent disbalancing, is to keep yout batteries between those limits). Balancing a battery 'manually' is very easy.
  • yes, DOD = 1 - SOC
  • Several battery specs have humidity and temperature ranges. As I understand, if you are out of these limits, parameters as discharge voltage and charge voltage limits are going to change too. Then of course it might be interesting to know if your battery compartment is very moist or extremely cold or so.

A few of these numbers, depending on the BMS, are not static, and also would not reflect the above calculation. The REC BMS >reports/commands semi-dynamic dynamic values for the above or similar values (acted on by systems like Victron in DVCC >modes):
voltage.chargeLimit
voltage.dischargeLimit
current.dischargeLimit

Additionally, since the cell based protections are cell based, reporting/calculating pack level limits from the cell based limits are >not meaningful unless all cells were perfectly balanced and identical. Meaning, I will always get a low voltage protection cutoff >at some voltage above voltage.dischargeCutoff because it actuates on the lowest cell, while other cells are still higher.

  • You are right about that. I guess protection will always be cell based. So these numbers are more informational (you might want to show values for a battery in stead of values for a cell). But even then they should be calculated using individual cell data.
  • Configuration of the battery (2P8S) should be implemented too. Fully agree on that. So cell capacity is important, but from a battery point of view, you need to know the configuration. batterypackConfiguration = { 1P4S, 2P8S}

I think a github page must be created to organize this data structure, so we can discuss the individual keys and relations between them. I am not that good in github, so I have to figure out first how to do that.

@MikeP-NZ
Copy link

Great discussion. If I can contribute some suggestions...
electical.batteries.<RegExp>

A BMS will usually report the max and min cell voltage and temperature for a battery. These stats are important for monitoring the balance state and the performance of the BMS and the cells.
Not all BMSs will have a temperature sensor for every cell and some will have additional temperature sensors for the cell balancing circuitry, contactors and MOSFETs.
.cells.voltage.minimum ; maximum of measured cell voltages
.cells.voltage.maximum ; minimum of measured cell voltages
.cells.temperature.maximum ; maximum of measured cell temperatures
.cells.temperature.minimum ; minimum of measured cell temperatures
.cells.<RegExp>.voltage
.cells.<RegExp>.temperature
.<RegExp>.temperature ; temperature of named component, eg. BMS, contactor, pre-charge resistors

.dateLastBalance ; Date and time that the battery was last fully charged and allowed to achieve fully balanced cells.
.cumulativeChargeLastBalance ; The cumulative charge (cumulative Ah) value at the last balance, or a value for accumulated Ah since last balance charge.
These are useful for triggering reminders for periodic balance charging. Maximum lithium battery lifespan is achieved by avoiding deep discharge and also by not unnecessarily charging the battery to 100%.
Not all BMS will track charging amp-hours and discharging amp-hours separately. Some will only track accumulated amp-hours. My experience is that they increment this value at half the rate during both charging and discharging.
.cumulativeCharge or .lifetimeCharge ;
The BMS may report "cycles" This is not how many times the battery has been charged. It is derived by cumulativeCharge/NominalCapacity
.cycles

I hope that input is helpful.

@lphooge
Copy link

lphooge commented May 14, 2024

Note: numberOfCells can be different values than 4 or 8.
For example for electric motors 48V batteries are common, those have 16 LiFePo4 cells in series.

And in the future other cell chemistries might have even different requirements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants