Battery Pack Optimizer Project Report

A practical Python GUI for grouping 18650 cells into balanced series/parallel packs using capacity, DCIR, and voltage safety checks.

Python PySide6 GUI Excel input/output Simulated annealing Voltage safety guardrails

Executive Summary

The application helps build safer and better balanced battery packs by assigning cells into series groups with parallel slots. It validates spreadsheet data, selects the best cells when extras are available, optimizes group balance, checks parallel voltage spread, visualizes the final layout, and exports a formatted workbook.

Primary Goal
Balanced groups
  • Similar group capacity
  • Similar parallel DCIR
  • Safe voltage spread inside each parallel group
Core Safety Addition
Voltage matching
  • Good: ≤ 0.02 V
  • Acceptable: ≤ 0.05 V
  • Warning: > 0.05 V
  • Unsafe: > 0.10 V
Final Output
Builder ready report
  • Pack summary
  • Visual layout
  • Grouped cells table
  • Excel export with safety colors

Inputs

The app expects an Excel sheet with measured cell data. Voltage is now part of the expected input because it matters before cells are physically connected in parallel.

Required columns
  • Cell ID
  • Model
  • Capacity (mAh)
  • DCIR (mΩ)
  • Voltage (V)
User settings
  • Pack configuration, such as 10S4P
  • Nominal and full cell voltage
  • Capacity, DCIR, and voltage weights
  • Max allowed parallel voltage spread
  • Unsafe voltage spread threshold

How the Optimizer Works

The optimizer starts from a reasonable first layout, then repeatedly swaps cells between groups to reduce the pack score.

Capacity

Parallel cell capacities are summed within each series group. The optimizer tries to make those group totals similar.

group_capacity = sum(cell capacities) capacity_score = std(group_capacities) / mean(group_capacities)
DCIR

Cells in parallel behave like resistors in parallel, so group DCIR is calculated using reciprocal resistance.

group_DCIR = 1 / sum(1 / cell_DCIR) dcir_score = std(group_DCIRs) / mean(group_DCIRs)
Voltage safety guardrail

Voltage is treated differently from capacity and DCIR. Capacity/DCIR are balanced between series groups. Voltage spread is checked inside each parallel group, because cells connected in parallel must be close in voltage before connection.

group_voltage_spread = max(group voltages) minus min(group voltages)

How the Score Is Calculated

The score is a single number that tells the optimizer how good a proposed pack layout is. A lower score is better. Each possible layout is judged by how evenly it distributes capacity, how evenly it distributes internal resistance, and whether any parallel group has a risky voltage spread.

Capacity balance

First, the app adds the cell capacities inside each series group. It then compares those group totals. If one group has much less capacity than the others, that group will limit the whole pack, so the score goes up.

capacity_score = standard deviation of group capacities divided by average group capacity
DCIR balance

DCIR is calculated as parallel resistance inside each group. Groups with higher resistance sag more under load and heat more, so the optimizer tries to keep group resistance values close together.

dcir_score = standard deviation of group DCIR values divided by average group DCIR
Voltage penalty

Voltage is handled as a safety check inside each parallel group. Small spreads are allowed, but larger spreads add a penalty because cells at different voltages can drive equalization current into each other when connected.

  • Up to 0.02 V adds no penalty
  • 0.02 to 0.05 V adds a small penalty
  • Above 0.05 V adds a strong penalty
  • Above 0.10 V is treated as unsafe and flagged clearly
Weighted total

The final score combines the three parts using user selected weights. This lets the builder decide what matters most for a given pack, while still keeping voltage safety visible.

total_score = capacity_weight times capacity_score plus dcir_weight times dcir_score plus voltage_weight times voltage_penalty
How to read the score

The score is mainly useful for comparing layouts from the same cell set and same settings. It is not a universal battery quality number. If the optimizer finds a lower score, it has found a layout with better balance or fewer voltage concerns under the chosen weights.

Voltage Safety Logic

The most important safety rule is not average voltage. It is the spread inside each parallel group. A high voltage cell connected directly in parallel with a lower voltage cell can push equalization current between cells, causing heat, sparks, cell stress, or damage.

Good
≤ 0.02 V
Acceptable
≤ 0.05 V
Warning
> 0.05 V
Unsafe
> 0.10 V
Current scoring behavior

The voltage logic was refined so safe voltage matching does not overpower the whole optimizer.

  • ≤ 0.02 V: no voltage penalty
  • 0.02 to 0.05 V: small nudge penalty
  • > 0.05 V: strong penalty or rejection
  • > 0.10 V: unsafe warning
Recommendation

Before physical assembly, cells should be balanced to approximately the same voltage, ideally within 0.02 to 0.05 V.

Outputs

In the GUI
  • Pack summary with voltage safety recommendation
  • Visual pack layout by series group and parallel slot
  • Grouped cells table
  • Group summary table
  • Capacity, DCIR, and voltage spread charts
Excel export
  • Grouped Cells
  • Group Summary
  • Pack Summary
  • Unused Cells
  • Conditional formatting for voltage safety status

Challenges Faced During Development

Initial UI density

The first version was functional but looked like a default desktop tool. The layout was redesigned with a clearer sidebar, better summary cards, stronger buttons, and cleaner charts.

Screen fit

The first visual pass was too tall for smaller screens. The sidebar was changed so settings scroll independently, while the Optimize button, status log, and progress bar remain pinned at the bottom.

Voltage safety

The app originally optimized capacity and DCIR only. Voltage was added because cells connected in parallel need close voltages before assembly to reduce equalization current risk.

Too strict voltage scoring

The first voltage scoring method penalized every tiny voltage spread. This caused the optimizer to lock onto the voltage sorted starting layout. The scoring was changed so ideal spreads have no penalty and voltage acts mainly as a safety guardrail.

Diagnostics noise

Detailed optimizer diagnostics helped debug the algorithm, but they were too noisy for the status panel. The status panel now focuses on progress and final score, while detailed information remains in the summary/export path.