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 | |
| Supported Python Versions | |
| Documentation | |
| User Manual | |
| Downloads | |
| Driver Version Tested Against | 2026 Q3 |
Note: NI created and supports nibcq.
Contributing
At this time, NI is not accepting external contributions.
The nibcq library is not currently under active development. NI continues to provide security updates, and the project may return to active development in the future.
Because the library is not under active development, NI is not accepting external contributions, pull requests, or issues at this time. While we appreciate the interest from our community, we are not set up to handle them. 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
- LCR Meter Measurements - Run ACIR and EIS impedance measurements and compensation using an NI PXIe-4190 LCR Meter for hardware-based impedance analysis
- 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
BCQErrorbase 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
- Safe Output Disconnection - Reliably disconnect the SMU and electronic load output relays at the end of every ACIR, EIS, and DCIR test (including parallel variants) for a proper workflow and power safety
Note: The nibcq Python API supports the core Battery Cell Quality Toolkit measurement workflows, but some LabVIEW API features are not available in Python. For the full list of supported features and hardware differences between the LabVIEW and Python APIs, see the Python API Capabilities page in the Battery Cell Quality Toolkit Manual.
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
LCR Meters
LCR meter-based EIS and ACIR testing uses the following NI hardware:
- NI PXIe-4190
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()
LCR Meter Measurements
Run ACIR and EIS measurements on an NI PXIe-4190 LCR Meter. Create the device with
DeviceFamily.LCR_METER. LCR measurements use onboard compensation (enabled via
parameter flags), not external compensation files.
from nibcq import Device, LCRACIR, LCRTestParameters, LCREIS, LCREISTestParameters
from nibcq.enums import DeviceFamily
# Connect the LCR Meter (PXIe-4190)
with Device.create(DeviceFamily.LCR_METER, resource_name="MyLCR") as device:
# LCR ACIR - Fixed 1 kHz impedance measurement
lcr_acir = LCRACIR(device, LCRTestParameters(current_amplitude=0.07))
acir_result = lcr_acir.run()
print(f"|Z|: {acir_result.z_magnitude} Ω, Rs: {acir_result.resistance} Ω")
# LCR EIS - Multi-frequency sweep ({frequency: current_amplitude})
lcr_eis = LCREIS(device, LCREISTestParameters(
frequency_sweep_characteristics={10000.0: 0.07, 1000.0: 0.07, 100.0: 0.07}
))
eis_results = lcr_eis.run()
for result in eis_results:
print(f"{result.measured_frequency} Hz - |Z|: {result.z_magnitude} Ω")
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
- API Reference: nibcq Documentation
- Battery Cell Quality Toolkit Manual: NI Documentation - See the Python API Capabilities page for the feature support table comparing the LabVIEW and Python APIs
- Examples: Refer to the examples directory in the nibcq-python repository
Note: The nibcq Python repository is for internal use only. Access is granted only to authorized personnel upon request and approval by NI.
Note: When upgrading to a newer version, review the CHANGELOG for any breaking changes and their migration guides.
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
Metadata
Release files for nibcq 1.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nibcq-1.5.0.tar.gz | 119.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nibcq-1.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 254.6 kB
Release files / nibcq-1.5.0.tar.gz
| Download URL | nibcq-1.5.0.tar.gz |
|---|---|
| Size | 119.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
678a98a7078b38d067e2c3e7c35c0abf217aa77390e2c66d1968a4199d50ceae
|
|
BLAKE2b-256 checksum How to use checksums |
734a3c1f0e547c0d3829f02bc2441887c0ce784c5eccf12847deb3d41e168101
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logRelease files / nibcq-1.5.0-py3-none-any.whl
| Download URL | nibcq-1.5.0-py3-none-any.whl |
|---|---|
| Size | 135.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6bf183184844b5330b5490feedbb09f9b1dd88ff573afdb9c381b835287ff3ee
|
|
BLAKE2b-256 checksum How to use checksums |
ad393bb7cdf688abddae7579f84b8626f34ec685d53fc51b8a874696e63351d3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency log