SignalK / specification

Signal K is a JSON-based format for storing and sharing marine data from different sources (e.g. nmea 0183, 2000, seatalk, etc)
Other
91 stars 69 forks source link

BMS / individual cell data for batteries #603

Open tkurki opened 3 years ago

tkurki commented 3 years ago

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 commented 3 years ago

Per cell data:

BMS data:

GHBLoos commented 3 years ago

My initial thoughts:

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

Current

Environment

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 commented 3 years ago

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:

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:

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 commented 3 years ago

That's good feedback!

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 commented 1 year ago

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 commented 4 months ago

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.