Skip to main content

NI Battery Cell Quality library

Project description

NI Battery Cell Quality (nibcq) Python API

Overall Status

Project Info
Package NI Battery Cell Quality Toolkit Python API
Author NI

About

Use the nibcq Python package to perform battery cell characterization measurement testing on NI hardware. The package provides high-level APIs for the following tests:

  • Electrochemical Impedance Spectroscopy (EIS)
  • AC Internal Resistance (ACIR)
  • DC Internal Resistance (DCIR)
  • Open Circuit Voltage (OCV)

API Status

Status Details
PyPI Version PyPI Version
Supported Python Versions Python Version
Documentation Documentation
Downloads PyPI Downloads
Driver Version Tested Against 2026 Q1

Note: NI created and supports nibcq.

Contributing

At this time, NI is not accepting external contributions.

The nibcq library is under development. While we appreciate interest from our community, we are not set up to handle external pull requests, issues, or contributions. This policy may change in the future.


Features

The nibcq package includes support for the following features.

  • Electrochemical Impedance Spectroscopy (EIS) - Conduct a multi-frequency impedance characterization
  • AC Internal Resistance (ACIR) - Conduct a single-frequency impedance measurement
  • DC Internal Resistance (DCIR) - Conduct a two-point DC resistance measurement
  • Open Circuit Voltage (OCV) - Conduct a precision voltage measurement at rest
  • Advanced Compensation Logic - Support multiple methods for your complex compensation system:
    • Short Compensation: Remove cable and contact resistance using short-circuit measurements
    • Golden DUT Compensation: Calibrate your DUT using known reference devices
    • Short with Known Impedance Table (KIT): Isolate test fixture impedance by subtracting known reference resistor values for a precise jig-only compensation
  • Parallel Measurements - Run ACIR, DCIR, and EIS measurements in parallel across multiple devices for higher throughput
  • Custom Error Handling - Unified exception hierarchy with BCQError base class and specific subclasses for clear, actionable error messages
  • Temperature Monitoring - Track temperature during measurements
  • Switch Control - Automate multi-DUT testing with NI switch modules
  • Self-Calibration Diary Logging - Manage NI hardware self-calibration with persistent logging, tracking calibration history, temperature conditions, and time-based validity

System Requirements

Software Requirements

The nibcq package requires the following software:

  • Python: 3.12 or later (required)
  • NI Driver Runtimes (required):
    • NI-DCPower
    • NI-DMM
    • NI-Switch
    • NI-DAQmx

Note: Installing the Battery Cell Quality Toolkit through NI Package Manager automatically installs all required NI drivers.

Note: The nibcq package uses NumPy for impedance calculations and signal processing. NumPy installs automatically as a dependency with nibcq.

Supported Devices

Source Measure Units (SMUs)

EIS and ACIR testing requires the following NI hardware:

  • NI PXIe-4139
  • NI PXIe-4139 40W

Electronic Loads

DCIR testing requires the following NI hardware:

  • NI PXIe-4051

Digital Multimeters (DMMs)

OCV testing requires the following NI hardware:

  • NI PXI-4071 (Note: Not available for purchase)
  • NI PXIe-4081

Switch Modules

Multi-DUT tests use the following optional NI hardware:

  • NI PXI-2525
  • NI PXIe-2530B

Thermocouple Input Modules

Temperature sensing tests use the following optional NI hardware:

  • NI PXIe-4353

Installation

Use pip to install the nibcq package through the following command:

pip install nibcq

Note: To visualize EIS measurement results, install matplotlib through the following command:

pip install matplotlib

Quick Start

Basic Measurement Workflow

All nibcq package measurements use the following Python pattern:

from nibcq import Device, ACIR, ACIRTestParameters
from nibcq.enums import DeviceFamily

# 1. Connect the device
with Device.create(DeviceFamily.SMU, resource_name="PXI1Slot3") as device:

    # 2. Configures the test parameters from a file or programmatically
    test_params = ACIRTestParameters.from_file("ACIRConfigFile.json")

    # 3. Creates a measurement instance
    acir = ACIR(device, test_params, test_frequency=1000.0)

    # 4. Loads a compensation (Also needed if set to NO_COMPENSATION)
    compensation = acir.load_compensation_file()

    # 5. Runs a measurement
    result = acir.run(compensation)

    # 6. Accesses the results
    print(f"Impedance: {result.impedance} Ω")

Available Measurement Types

# OCV - DMM based
from nibcq import OCV, OCVTestParameters
from nibcq.enums import DMMRange
ocv = OCV(device, OCVTestParameters(
    range=DMMRange.DC_10V,
    aperture_time=1.0,
    number_of_averages=10,
    adc_calibration=True
))
start, end, voltage = ocv.run()

# ACIR - Single frequency
from nibcq import ACIR, ACIRTestParameters
from nibcq.enums import CompensationMethod
acir = ACIR(device, ACIRTestParameters(
    voltage_limit_hi=5.0,
    nominal_voltage=3.7,
    current_amplitude=0.1,
    number_of_periods=20,
    compensation_method=CompensationMethod.SHORT
), test_frequency=1000.0)
result = acir.run(compensation)

# EIS - Multi-frequency
from nibcq import EIS, EISTestParameters, FrequencySet
eis = EIS(device, EISTestParameters(
    voltage_limit_hi=5.0,
    nominal_voltage=3.7,
    compensation_method=CompensationMethod.SHORT,
    frequency_sweep_characteristics={
        10000.0: FrequencySet(current_amplitude=0.1, number_of_periods=1000),
        1000.0: FrequencySet(current_amplitude=0.1, number_of_periods=100),
        100.0: FrequencySet(current_amplitude=0.1, number_of_periods=10)
    }
))
results = eis.run(compensation)
nyquist, magnitude, phase = eis.get_plots()  # Get plot data

# DCIR - Electronic load-based
from nibcq import DCIR, DCIRTestParameters
from nibcq.enums import PowerlineFrequency
dcir = DCIR(device, DCIRTestParameters(
    max_load_current=2.0,
    powerline_frequency=PowerlineFrequency.FREQ_60_HZ
))
resistance = dcir.run()

Advanced Features

The nibcq package includes support for the following advanced features.

  • Parallel Measurements - Run measurements on multiple devices simultaneously for higher throughput
  • Multi-DUT Testing with Switching - Test DUTs sequentially in multiple test jigs using a SMU or a DMM
  • Temperature Monitoring - Perform tests with temperature monitoring
  • Device Self-Calibration - Set Devices to perform a self-calibration under specific circumstances
  • Compensation File Creation - Create compensation values to account for the impedance of cables, connectors, and other components in the measurement path

Parallel Measurements

from nibcq import ParallelACIR, ACIRTestParameters, Device
from nibcq.enums import DeviceFamily

# Initialize a leader device and one or more follower devices
with Device.create(
    DeviceFamily.SMU, resource_name="PXI1Slot3"
) as leader, Device.create(
    DeviceFamily.SMU, resource_name="PXI1Slot4"
) as follower:
    # Configure the test parameters
    test_params = ACIRTestParameters.from_file("ACIRConfigFile.json")

    # Set up a Parallel ACIR Measurement
    parallel_acir = ParallelACIR(
        leader=leader,
        followers=[follower],
        test_parameters=test_params,
        test_frequency=1000.0,
    )

    # Load compensation and run
    compensation = parallel_acir.load_compensation_file()
    result = parallel_acir.run(compensation)

    print(f"Impedance: {result.impedance}")

Note: Parallel measurement classes (ParallelACIR, ParallelDCIR, ParallelEIS) follow the same leader/follower pattern. Refer to the examples page for more detailed usage.

Multi-DUT Testing with Switching

from nibcq import Device, ACIR, ACIRTestParameters
from nibcq.enums import DeviceFamily, SwitchDeviceType, SwitchTopology
from nibcq.switch import SwitchConfiguration

# Connect to the SMU
with Device.create(DeviceFamily.SMU, resource_name="PXI1Slot3") as device:
    # Configure switching
    switch_config = SwitchConfiguration(
        topology=SwitchTopology.SWITCH_2_WIRE_QUAD_16X1_MUX,
        channels=["ch0", "ch1", "ch2", "ch3"]
    )

    # Add switching capability to the device
    device.with_switching(
        config=switch_config,
        sense_switch_resource_name="PXI1Slot5",
        source_switch_resource_name="PXI1Slot6",
        dmm_switch_type=SwitchDeviceType.PXIe_2530B
    )

    # Configure the measurement
    test_params = ACIRTestParameters.from_file("ACIRConfigFile.json")
    acir = ACIR(device, test_params, test_frequency=1000.0)
    compensation = acir.load_compensation_file()

    # Run the measurement on all channels
    results = acir.run_with_switching(compensation)

    # Display the results per channel
    for cell_data, result in results:
        print(f"Channel {cell_data.channel_name}: {result.impedance} Ω")

Temperature Monitoring

from nibcq import Device, ACIR, ACIRTestParameters
from nibcq.enums import DeviceFamily
from nibcq.temperature import ThermocoupleSettings

# Connect to the SMU
with Device.create(DeviceFamily.SMU, resource_name="PXI1Slot3") as device:
    # Add the temperature monitoring
    tc_settings = ThermocoupleSettings("PXI1Slot7/ai0")
    device.with_temperature(tc_settings)

    # Configure and run the measurement
    test_params = ACIRTestParameters.from_file("ACIRConfigFile.json")
    acir = ACIR(device, test_params, test_frequency=1000.0)
    compensation = acir.load_compensation_file()
    # Optional - Set acceptable temperature delta for validation
    acir.acceptable_temperature_delta = 5.0  # degrees Celsius

    result = acir.run(compensation)

    # Measure and display temperature
    acir.measure_temperature()
    print(f"Impedance: {result.impedance} Ω at {acir.temperature:.2f} °C")

Device Self-Calibration

from nibcq import Device, Calibrator
from nibcq.calibration import Settings
from nibcq.enums import DeviceFamily

# Connect to the device
with Device.create(DeviceFamily.SMU, resource_name="PXI1Slot3") as device:
    # Configure the calibration settings
    cal_settings = Settings(
        temperature_delta=2.0,  # °C tolerance
        days_to_calibration=1,  # Recalibration interval in days
    )

    # Create the calibrator
    calibrator = Calibrator(device, cal_settings)

    # Validate the calibration
    if not calibrator.last_calibration_is_valid:
        print("Calibration required - running self-calibration...")
        calibrator.self_calibrate()
        print("Calibration complete!")
    else:
        print("Calibration is valid.")

Compensation File Creation

from nibcq import Device, ACIR, ACIRTestParameters
from nibcq.enums import DeviceFamily

with Device.create(DeviceFamily.SMU, "PXI1Slot3") as device:
    # Create the compensation file with a connected short circuit
    acir = ACIR(device, ACIRTestParameters.from_file("ACIRConfigFile.json"), 1000.0)
    comp_file_path = acir.write_compensation_file(
        comment="Short compensation at 1 kHz"
    )
    print(f"Compensation file created: {comp_file_path}")

Documentation

Note: The nibcq Python repository, and all related examples, are for internal use only. Access is granted only to authorized personnel upon request and approval by NI.


Support and Feedback


License

This project is licensed under the MIT License. See the LICENSE file for details.

For third-party software notices and license information, see the NOTICE file.


Related Projects

  • nidcpower - NI-DCPower Python API
  • nidmm - NI-DMM Python API
  • niswitch - NI-Switch Python API
  • nidaqmx - NI-DAQmx Python API
  • NumPy - Fundamental package for scientific computing with Python (BSD License)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nibcq-1.4.0.tar.gz (113.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nibcq-1.4.0-py3-none-any.whl (129.4 kB view details)

Uploaded Python 3

File details

Details for the file nibcq-1.4.0.tar.gz.

File metadata

  • Download URL: nibcq-1.4.0.tar.gz
  • Upload date:
  • Size: 113.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for nibcq-1.4.0.tar.gz
Algorithm Hash digest
SHA256 bd15ebdac8891598de229818626d9214212525655904b1756db82f9035aa23d0
MD5 154f90fa2f900366ed14e4ad351679fe
BLAKE2b-256 9ab69f7e7e317fb31558aefaccb87afc241e632fd3470c789ea3b3fee935a282

See more details on using hashes here.

Provenance

The following attestation bundles were made for nibcq-1.4.0.tar.gz:

Publisher: publish.yml on ni/nibcq-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nibcq-1.4.0-py3-none-any.whl.

File metadata

  • Download URL: nibcq-1.4.0-py3-none-any.whl
  • Upload date:
  • Size: 129.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for nibcq-1.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 eb2356573ef636dc2142013172b819e968461b151751739c5e4d519662369e38
MD5 1ec151925937baf92f5fbdd01d8f310e
BLAKE2b-256 831b3b9bd9e2fe43ffcb3cf1a29fe0151270be31945f62f8350717ccd1a5cbce

See more details on using hashes here.

Provenance

The following attestation bundles were made for nibcq-1.4.0-py3-none-any.whl:

Publisher: publish.yml on ni/nibcq-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page