Posted on

Battery Cycle Testing with Python, and E-Load, and Power Supply

Update May 16, 2023 – see here for a newer post with a better overview and details.


A  lot of electronic loads (my Rigol DL3021A included) have a built-in ‘Battery Test’ function, either on the front panel or able to set up through the load’s accompanying software (See here for an overview of my lab hardware). This works fairly well if you’re just trying to run one cycle, but when trying to run multiple cycles you need to control the charging cycle as well. Keysight has the BenchVue software which allows coordination of multiple instruments together in drag-and-drop scratch-like scripts, but to get the full control over the cycles and parameters, you’ll want to control your instruments over SCPI with Python.

I’ve been wanting to test out some LG MJ1 cells for upgrading an old NiCD drill battery, and figured I’d take the opportunity to write a basic battery cell cycling program that I’ll be able to expand on in the future.

Before we dive into specifics though, I will preface with mentioning that I am not a firmware of software programmer by trade or by schooling, only out of necessity and interest – I can write code that works, but is not optimal. I know there’s a lot that could be done better and/or cleaned up in the code. If you want to contribute, send me a message and have a look at what I’ve got on Github!

Program Features

Basic GUI

While I am fairly familiar with command line tools, its always nice to have a GUI. Python makes that super simple with TKinter and EasyGui. A simple, linear flow of operations through popup windows is easy to implement, but in the future, having a full-featured program would be nice. A few images of the GUI screens are shown at the bottom of this post, but are not all that impressive – just the basic options provided.

Storing Test Settings to JSON Files

The settings for each charge and discharge cycle can be stored to a JSON file for easy recall for future tests.

Choosing Test Equipment

When setting up a test, it is good to be able to choose whatever equipment is available to you. The program has been set up to select whichever instrument series and visa resource is available to you.

While SCPI commands are supposed to be standard between equipment, there are a fair number of differences across different models for the more obscure features such as remote sense, front panel lock, and other such features. They often use different SCPI commands to activate these features, so I created a python class for each instrument will all the command specific to that instrument.

Multiple Test Choices

There have often been times where running different cycle types have been useful. There are multiple options for different types of cycles built in:

  • Run a single cycle at a set voltage, current
  • Run multiple cycles with the same settings for a set number of times
  • Run multiple cycles with 2 different settings for a set number for each cycle type and test cycles (e.g. discharge at 5A, charge at 2.5A for 1 cycle, then discharge at 10A, charge at 5A for 9 cycles, then repeat 5 times for a total of 50 cycles). This can be helpful for degradation testing and measuring capacity with a standard cycle at fixed intervals.

Storage Charge Option

Every test setup will ask if you want to charge the cell to a storage level as well. Leaving cells discharged after a capacity test can accelerate the degradation of the cells, and can lead to increased dendrite growth causing latent failures in the cells. Charging back up to a storage voltage (around 3.7V for li-ion cells) is always a good idea.

Data logging and Discharge End Detection

The discharge is finished when the cells reach a defined voltage in the test settings. The monitoring of this end condition can be improved quite a bit from the current implementation.

The data (voltage at current) is measured from the eload and power supply at the interval defined in the test settings. It compares these measured values to the end points, as well as logs them to a csv file. With this method of logging at a fixed interval and comparing to setpoints, we will over-discharge the cell at the end of the cycle if the actual voltage of the cell reaches the setpoint at the middle of an interval. I hope to improve the algorithm to attempt to match the curve of the cell during discharge, and predict the time that the cell will pass the threshold. Then turn off of the electronic load at the calculated time instead of waiting until the next measurement interval.



Now for the interesting stuff. This has allowed me to do some long term cycle and degradation test for the Solar Car battery modules for the University of Waterloo. Eventually I’ll get around to making a proper summary of that data, but for now here’s a few cycles that I’ve done on some of the Samsung 25R cells I’m using to replenish an old NiCd power tool battery pack. They look pretty similar except for different state of charge at the start of the tests due to some other testing I was doing. These graphs are all spit out of another python program which also summarizes results such as capacity in Ah and Wh, final charge voltage, actual minimum discharge voltage, and max cell temperature if there was a thermistor also attached.

It is interesting to note that all the cells seem to still drop in voltage during the rest period after the discharge. I expect there may be some leakage current in the power supply or eload that is drawing them down – a problem for another day. For now, I’ll make sure not to leave them sitting overnight.