FW15 BMS Carrier

BMS carrier is the board which is responsible for monitoring and managing the main battery pack. It interfaces with the AFE (analog front end) board and the Current Sense board to get readings from the main pack.

Other Resources:
FWXIV BMS Carrier notes

BMS AFE Description

image-20240317-064633.png

Components

  • Current Sense - connected via I2C, and provides current readings and ambient temperature,

  • AFEs - 3 AFE boards, daisy-chained over iso-spi. These provide per-cell-unit voltage readings and cell temperature readings, as well as perform load balancing

  • Relays + killswitch monitoring - Positive and negative relays must both be closed for the battery to be connected to the rest of the car. Killswitch monitor reads state of manual killswitch to batteries

    • HV Neg relay

    • HV Pos Relay

    • HV Solar Relay

  • Fans - Used to provide cooling to batteries. Controlled via PWM

Fault Conditions

These are all fault conditions which will trigger a BPS fault. They are split into Minor, in which the issue is likely to not be dangerous and the driver can take time coming to a stop, and Major in which the driver should exit the car as quickly as possible due to dangerous conditions or the potential for thermal runaway.

Note: Cell refers to individual input AFE measurements, which in reality is several physical cells. Cell group refers to an area managed by a single AFE.

AFE:

  • Undervoltage - One Cell Falls < 2.5V (minor)

  • Overvoltage - One cell > 4.5V (Major)

  • Temperature - if any thermistor reads > 50deg (Major)

    • Note: If thermistors read > 40deg, open solar relay to disable charging, but this is not a fault

Current Sense

  • Overcurrent - reading > 58.2A (Minor)

Communication Errors

  • If we lose communication with AFEs or Current sense, need to warn the driver. Registering a fault here has caused many issues in our system.

KillSwitch

  • Will shutoff batteries by itself, but we will treat it as a BPS fault (minor) to ensure relays don't close after letting go of the button

Fault Enum - Bold are major faults, so they are grouped together:

BMS_FAULT_OVERVOLTAGE
BMS_FAULT_UNBALANCE
BMS_FAULT_OVERTEMP_AMBIENT
BMS_FAULT_COMMS_LOSS_AFE
BMS_FAULT_COMMS_LOSS_CURR_SENSE
BMS_FAULT_OVERTEMP_CELL
BMS_FAULT_OVERCURRENT
BMS_FAULT_UNDERVOLTAGE
BMS_FAULT_KILLSWITCH

Operation

BMS Checks

These are the checks that are done at every cycle in each FSM state, at the highest frequency possible. They should happen as follows. If any error is detected, we should exit our check function and transition to fault immediately. We also set the requisite bit in bms_status_bms_faults signal.

  • Check for CS_FAULT state set to high

  • Trigger Cell Voltage conversions

    • Record start time, need to wait 10ms before reading back values

  • Perform current sense read and check

  • Perform AFE voltage sense and check

We also need to do an AFE Temp check, but this does not need to happen every cycle. We can reduce this to every 5 cycles.

Communication Loss: We will keep a running count of communication errors separately for AFEs and Current sense (CRC invalid, no data returned, etc). If 3 occur, we BPS fault.

Shared Memory

Readings from the AFEs and current sense should be stored into a struct shared between the BMS FSM and master task. This will allow for Fan monitor to access temp data, and any data broadcasting to happen from master task

Fan Monitor

This will be a function called from master task medium cycle which will:

  • Update fan PWM based on temp readings

Relay Sequence

These are the actions needed to achieve a certain relay state:

When the car turns on:

  1. set HV_POS_RELAY_EN

  2. set HV_NEG_RELAY_EN

  3. set HV_SOLAR_RELAY_EN

  4. Check all sense pins to verify relays closed

If we fault, we can open all at once (set *_EN to low). If we want to open the solar relay to prevent overcharging, we can set HV_SOLAR_RELAY_EN to low.

TX:

  • battery_status

    • Fault bitset from ENUM

    • Aux Battery Voltage

    • AFE Status (Comms loss)

  • battery_info

    • Max Cell Voltage

    • Min Cell Voltage

  • battery_vt

    • Pack Voltage

    • Pack Current

    • Pack Temperature

    • Battery Percentage

  • AFE_Status_[1,2,3]

    • ID

    • AFE Temperature reading

    • Cell 1 Voltage

    • Cell 2 Voltage

    • Cell 3 Voltage

AFEs Additional info

The AFEs (analog front end) handle interactions with the main battery pack. There are multiple AFEs (LTC6811 chips) which handle reading cell voltages, reading thermistors to determine cell temperatures, and doing load balancing for the cells. These multiple AFE units are daisy-chained through one SPI interface. This SPI interface through hardware is translated to isoSPI and back to SPI for improved reliability. We do this because of the high potential differences and different grounds on BMS and AFE boards.

AFE Configuration

The AFE operation revolves around two main data structures.

typedef struct LtcAfeSettings { GpioAddress cs; GpioAddress mosi; GpioAddress miso; GpioAddress sclk; const SpiPort spi_port; uint32_t spi_baudrate; LtcAfeAdcMode adc_mode; uint16_t cell_bitset[LTC_AFE_MAX_DEVICES]; uint16_t aux_bitset[LTC_AFE_MAX_DEVICES]; size_t num_devices; size_t num_cells; size_t num_thermistors; } LtcAfeSettings; typedef struct LtcAfeStorage { // Only used for storage in the FSM so we store data for the correct cells uint16_t aux_index; uint16_t retry_count; uint16_t cell_voltages[LTC_AFE_MAX_CELLS]; uint16_t aux_voltages[LTC_AFE_MAX_THERMISTORS]; uint16_t discharge_bitset[LTC_AFE_MAX_DEVICES]; uint16_t cell_result_lookup[LTC_AFE_MAX_CELLS]; uint16_t aux_result_lookup[LTC_AFE_MAX_THERMISTORS]; uint16_t discharge_cell_lookup[LTC_AFE_MAX_CELLS]; LtcAfeSettings settings; } LtcAfeStorage;

The settings struct holds all the configuration for the hardware being used with the AFEs, including the number of AFEs, number of cells, and number of thermistors. The cell_bitset and aux_bitset indicate which of the total set of cells/thermistors we should read as inputs.

The storage struct holds the information from the settings, as well as memory for all of the readings taken.

AFE Readings

AFE readings are taken via the daisy-chain method, meaning that a read of a certain register on one AFE will be replied to with the values of all of the AFEs connected. (For example, the reading of the voltage register A of one of the AFE will be replied to with x 64 bit readings, where x is the number of AFEs connected)

Cell Sense

Essentially, we iterate through the number of voltage registers (4) and for each we read the 3 uint16_t voltages and one 16-bit Packet Error Check from each of the AFEs at this register. These results are then placed at the correct position in the cell_voltages array based on the cell_bitset and cell_result_lookup

Cell Balancing

The goal of cell balancing is to ensure that we fully utilize the capacity of our pack. It is most important while charging, since the pack stops charging when the highest cell voltage reaches the charge limit. Thus, we don’t want to stop charging when once cell reaches the limit but a bunch of other cells are far below the limit. The cells are therefore balanced by discharging cells that have voltages which are too high, allowing all cells to come up to full charge.

Under high current load, differences between the internal resistance of the cells can cause the voltages to read different values when not actually at different states of charge. Based on the above, the proposed behaviour is as follows:

  • Min cell voltage < 4.0V or pack current draw > 10A

    • Balance to within 25mV (discharge everything 25mV above min voltage)

  • Min cell voltage < 4.15V

    • Balance to within 10mV (discharge everything 10mV above min voltage)

  • Min cell voltage > 4.15V

    • Balance to the highest possible accuracy (set to 2mV for now, can tune later)

Aux Voltage Sense

The voltage measurement for the aux battery will be on the carrier to comply with the requirement that “battery protection circuitry” must be in the battery enclosure. Voltage goes through a voltage divider circuit into an ADC pin. Firmware calculates the input voltage of the circuit.