Skip to content
Test Types & Methods

Track Battery Cycling Test Data

Learn how to log charge/discharge cycling data, track capacity fade, and monitor cell performance across production using TofuPilot.

JJulien Buteau
intermediate11 min readMarch 14, 2026

How to Track Battery Cycling Test Data with TofuPilot

Battery cycling tests generate thousands of data points per cell: voltage curves, current profiles, temperature readings, capacity measurements across hundreds of cycles. TofuPilot stores all of it in a structured, queryable format so you can track capacity fade, compare cells, and catch quality issues before they reach the pack.

What Battery Cycling Data Looks Like

A single cell cycling test produces:

Data pointPer cycleOver 500 cycles
Voltage vs. time~1000 samples500,000 samples
Current vs. time~1000 samples500,000 samples
Temperature~100 samples50,000 samples
Charge capacity (Ah)1 value500 values
Discharge capacity (Ah)1 value500 values
Coulombic efficiency1 value500 values

Multiply that by hundreds or thousands of cells in production, and you're looking at a data management problem that spreadsheets can't handle.

Logging Cycling Data to TofuPilot

Per-Cycle Upload

Upload results after each charge/discharge cycle completes. This gives you real-time visibility into cell performance.

battery_cycle_test.py
from tofupilot import TofuPilotClient

client = TofuPilotClient()

def log_cycle(cell_serial, cycle_number, charge_ah, discharge_ah, temp_max, voltage_curve):
    coulombic_eff = discharge_ah / charge_ah * 100 if charge_ah > 0 else 0
    capacity_retention = discharge_ah / nominal_capacity * 100

    client.create_run(
        procedure_id=f"CELL-CYCLING-C{cycle_number}",
        unit_under_test={"serial_number": cell_serial},
        run_passed=capacity_retention > 80 and temp_max < 45,
        steps=[{
            "name": f"Cycle {cycle_number}",
            "step_type": "measurement",
            "status": capacity_retention > 80,
            "measurements": [
                {"name": "charge_capacity_ah", "value": charge_ah, "unit": "Ah", "limit_low": 2.8},
                {"name": "discharge_capacity_ah", "value": discharge_ah, "unit": "Ah", "limit_low": 2.8},
                {"name": "coulombic_efficiency_pct", "value": coulombic_eff, "unit": "%", "limit_low": 99.0},
                {"name": "capacity_retention_pct", "value": capacity_retention, "unit": "%", "limit_low": 80.0},
                {"name": "max_temperature_c", "value": temp_max, "unit": "°C", "limit_high": 45.0},
                {"name": "voltage_curve_v", "value": voltage_curve, "unit": "V"},
            ],
        }],
    )

End-of-Life Summary Upload

After cycling completes, upload a summary with key aging metrics.

battery_eol_summary.py
client.create_run(
    procedure_id="CELL-CYCLING-SUMMARY",
    unit_under_test={"serial_number": cell_serial},
    run_passed=final_capacity_retention > 80,
    steps=[{
        "name": "Cycling Summary",
        "step_type": "measurement",
        "status": final_capacity_retention > 80,
        "measurements": [
            {"name": "total_cycles", "value": 500, "unit": "cycles"},
            {"name": "initial_capacity_ah", "value": 3.2, "unit": "Ah"},
            {"name": "final_capacity_ah", "value": 2.72, "unit": "Ah"},
            {"name": "capacity_retention_pct", "value": 85.0, "unit": "%", "limit_low": 80.0},
            {"name": "avg_coulombic_efficiency", "value": 99.7, "unit": "%", "limit_low": 99.0},
            {"name": "max_temperature_observed", "value": 42.3, "unit": "°C", "limit_high": 45.0},
        ],
    }],
)

Tracking Capacity Fade Across Production

The real value of centralized cycling data is comparing cells across production batches. TofuPilot's measurement trending shows:

  • Capacity retention distribution: Are all cells aging at the same rate?
  • Batch-to-batch variation: Does the new electrolyte formulation change the fade curve?
  • Outlier detection: Which cells are degrading faster than expected?

If batch 47 cells show 90% retention at 300 cycles while batch 46 showed 94%, something changed in the manufacturing process. The data in TofuPilot tells you immediately.

Cell Grading from Cycling Data

Not all cells are created equal. Cycling data helps grade cells into bins for different applications.

GradeCriteriaApplication
ACapacity > 3.1 Ah, retention > 95% at 200 cyclesEV packs
BCapacity > 2.9 Ah, retention > 90% at 200 cyclesEnergy storage
CBelow Grade BSecond-life applications

TofuPilot's measurement filters let you query cells by any combination of cycling metrics to assign grades automatically.

Integration with Battery Cyclers

Most battery cyclers (Arbin, Maccor, Neware, BioLogic) export data in CSV or proprietary formats. Parse the cycler output and upload to TofuPilot.

arbin_import.py
import csv
from tofupilot import TofuPilotClient

client = TofuPilotClient()

def import_arbin_data(csv_path, cell_serial):
    with open(csv_path) as f:
        reader = csv.DictReader(f)
        for row in reader:
            if row["Step_Type"] == "Discharge":
                client.create_run(
                    procedure_id="CELL-CYCLING",
                    unit_under_test={"serial_number": cell_serial},
                    run_passed=float(row["Discharge_Capacity(Ah)"]) > 2.8,
                    steps=[{
                        "name": f"Cycle {row['Cycle_Index']}",
                        "step_type": "measurement",
                        "status": True,
                        "measurements": [
                            {"name": "discharge_capacity_ah", "value": float(row["Discharge_Capacity(Ah)"]), "unit": "Ah"},
                            {"name": "charge_capacity_ah", "value": float(row["Charge_Capacity(Ah)"]), "unit": "Ah"},
                            {"name": "max_voltage_v", "value": float(row["Voltage(V)"]), "unit": "V"},
                        ],
                    }],
                )

Safety Monitoring

Battery testing has unique safety requirements. TofuPilot helps track safety-critical measurements:

  • Maximum temperature: Cells approaching thermal runaway thresholds
  • Voltage anomalies: Cells that don't reach full charge voltage or drop too fast
  • Capacity jumps: Sudden capacity changes that indicate internal shorts
  • Impedance growth: Rising internal resistance indicating degradation

Set tight limits on these safety measurements. A cell that passes capacity specs but shows abnormal temperature behavior needs investigation before it goes into a pack.

More Guides

Put this guide into practice