|
Python |
ER26500 battery tester
Purpose:
The ER26500 battery tester is used to test batteries from the sensors I develop. It addresses the uncertainty surrounding the condition of the batteries. Sometimes I have batteries from the customers, and I keep bateries in my toolbox aswell, in case I need to change the batteries of the sensors. I end up having several batteries not knowing which ones are still good.
Key Components:
- Rigol DL3021 Electronic load: This precision electronic load serves as a key component of the testing setup. It provides a controlled environment for discharging the batteries, allowing for accurate measurement of capacity and performance.
- Python script: A custom Python script was developed to automate the testing process. This script interact between the DL3021 and the battery under testing
Testing Methodology:
The ER26500 battery tester employs a series of controlled discharge cycles while monitoring voltage, current, and time elapsed. This data is processed to calculate the battery's actual capacity, providing a clear indicator of its health.
Benefits and Impact:
- Cost Efficiency: Identifying underperforming batteries early on prevents unnecessary replacements and minimizes costs.
- Time Savings: Automation through the Python script streamlines the testing process, allowing for efficient evaluation of multiple batteries in a shorter timeframe.
Notes:
- To run the python script you will need https://github.com/ulikoehler/LabInstruments
- In python script you have to replace 'ADD-IPADDRESS' to your IP address.
- And adapt the new_battery_stats, initial_current and load_change to your needs.
#
"""
__author__ = "Helio Pereira"
__license__ = "NA"
__version__ = "1.0"
__maintainer__ = "Helio Pereira"
__email__ = "helio_p@hotmail.co.uk"
__status__ = "Beta"
"""
#
import os
import time
import pyvisa
import statistics
from LabInstruments.DL3000 import DL3000
# Define colors for formatting
COLOR_Red="\033[1;91m" # Red
COLOR_YELLOW="\033[1;93m" # Yellow
COLOR_GREEN_BOLD = '\033[1;92m' # Bold green text
COLOR_LIGHT_BLUE_BOLD = '\033[1;96m' # Bold light blue text (cyan)
COLOR_RESET = '\033[0m'
# Print formatted header
def print_header(file_name, test_type, battery_type, version):
header = f"{COLOR_GREEN_BOLD}=== Battery Test Report ==={COLOR_RESET}"
file_info = f"File: {file_name} | Test Type: {test_type} | Battery Type: {battery_type} | Version: {version}"
print(header.center(len(file_info)))
print("\r")
print(file_info)
print("\n")
# Define test parameters
file_name = "er26500_tester_01.py"
test_type = "Voltage Recovery"
battery_type = "ER26500M"
version = "1.0"
# Define the parameters
initial_current = 0.1 # Initial discharge current in Amperes
load_change = 0.05 # Change in discharge current in Amperes
result = 0
# Lists to store voltage measurements during recovery
voltage_recovery_values = []
# Define reference statistics for a new battery (replace with actual values)
new_battery_stats = {
"min_voltage": 3.4500,
"max_voltage": 3.5850,
"mean_voltage": 3.5250,
"std_dev_voltage": 0.0040
}
os.system('cls' if os.name == 'nt' else 'clear')
# Print header
print_header(file_name, test_type, battery_type, version)
print('=== Initialize Test ===')
print("\r")
# Connect to the electronic load
rm = pyvisa.ResourceManager('@py')
print(f"{COLOR_GREEN_BOLD}Instrument{COLOR_RESET} - Searching for devices connected")
# Find connected devices
connected_devices = rm.list_resources()
# Check if DL3021 is connected
if 'TCPIP::ADD-IPADDRESS::INSTR' in connected_devices:
print(f"{COLOR_GREEN_BOLD}Instrument{COLOR_RESET} - DL3021 Device Found")
inst = DL3000(rm.open_resource('TCPIP::ADD-IPADDRESS::INSTR')) # Adjust the IP address as needed
try:
print(f"{COLOR_GREEN_BOLD}Instrument{COLOR_RESET} - Setting DL3021 constant current mode")
print(f"{COLOR_GREEN_BOLD}Instrument{COLOR_RESET} - Setting DL3021 initial discharge current to {initial_current} A")
print(f"{COLOR_GREEN_BOLD}Instrument{COLOR_RESET} - Enable DL3021 output")
# Configure the electronic load
inst.set_mode("CURRENT") # CC
inst.set_cc_current(initial_current) # Set initial discharge current
inst.enable() # Switch ON
# Measure initial battery voltage
initial_voltage = inst.voltage()
print(f"{COLOR_LIGHT_BLUE_BOLD}Battery{COLOR_RESET} - Initial Battery Voltage: {initial_voltage:.4f} V")
# Apply load change
print(f"{COLOR_GREEN_BOLD}Instrument{COLOR_RESET} - Setting DL3021 increase discharge current to {initial_current + load_change:.4f} A")
inst.set_cc_current(initial_current + load_change) # Increase load
time.sleep(2) # Wait for voltage to stabilize
# Measure voltage after load change
voltage_after_change = inst.voltage()
print(f"{COLOR_LIGHT_BLUE_BOLD}Battery{COLOR_RESET} - Voltage after Load Change: {voltage_after_change:.4f} V")
# Restore initial load
print(f"{COLOR_GREEN_BOLD}Instrument{COLOR_RESET} - Setting DL3021 initial discharge current to {initial_current:.4f} A")
inst.set_cc_current(initial_current) # Set initial discharge current
time.sleep(2) # Wait for voltage to stabilize
print("\r")
# Measure voltage recovery after load change and gather data
print('=== Measuring Voltage Recovery ===')
print("\r")
recovery_start_time = time.time()
while time.time() - recovery_start_time < 10: # Adjust the duration as needed
voltage_recovery = inst.voltage()
voltage_recovery_values.append(voltage_recovery)
print(f"{COLOR_LIGHT_BLUE_BOLD}Battery{COLOR_RESET} - Voltage during Recovery: {voltage_recovery:.4f} V")
time.sleep(1) # Adjust the interval as needed
print("\r")
# Calculate rate of change of voltage (derivative)
time_elapsed = time.time() - recovery_start_time
voltage_derivative = (voltage_recovery - voltage_after_change) / time_elapsed
print(f"{COLOR_LIGHT_BLUE_BOLD}Battery{COLOR_RESET} - Rate of Voltage Change (Derivative): {voltage_derivative:.4f} V/s")
print("\r")
# Analyze results based on voltage_derivative and voltage_after_change
if voltage_derivative < 0 and voltage_after_change > voltage_recovery:
print(f'{COLOR_YELLOW}Results{COLOR_RESET} - \033[91mFail: Negative voltage derivative and higher voltage after change indicate potential capacity reduction.\033[0m') # Red color for fail
else:
print(f'{COLOR_YELLOW}Results{COLOR_RESET} - \033[92mPass: Stable or improving voltage behavior indicates stable capacity.\033[0m') # Green color for pass
result += 1
#
# Print statistics
print('\r')
print(f"{COLOR_YELLOW}Results{COLOR_RESET} - Statistics")
min_voltage_recovery = min(voltage_recovery_values)
max_voltage_recovery = max(voltage_recovery_values)
mean_voltage_recovery = statistics.mean(voltage_recovery_values)
std_dev_voltage_recovery = statistics.stdev(voltage_recovery_values)
#
print(f"{COLOR_YELLOW}Results{COLOR_RESET} - Minimum Voltage during Recovery: {min_voltage_recovery:.4f} V")
print(f"{COLOR_YELLOW}Results{COLOR_RESET} - Maximum Voltage during Recovery: {max_voltage_recovery:.4f} V")
print(f"{COLOR_YELLOW}Results{COLOR_RESET} - Mean Voltage during Recovery: {mean_voltage_recovery:.4f} V")
print(f"{COLOR_YELLOW}Results{COLOR_RESET} - Standard Deviation of Voltage during Recovery: {std_dev_voltage_recovery:.4f} V")
#
print("\r")
# Compare with new battery statistics and print warning if difference is more than 20%
def print_comparison(name, measured, reference, perc):
global result
diff_percent = abs((measured - reference) / reference) * 100
if diff_percent > perc:
print(f'{COLOR_YELLOW}Results{COLOR_RESET} - {COLOR_Red}{name} is {diff_percent:.2f}% different from reference.{COLOR_RESET}') # Red color for warning
else:
print(f'{COLOR_YELLOW}Results{COLOR_RESET} - {COLOR_GREEN_BOLD}{name} is {diff_percent:.2f}% close to reference.{COLOR_RESET}') # Green color for close
result += 1
#
print_comparison("Min Voltage", min_voltage_recovery, new_battery_stats["min_voltage"],5)
print_comparison("Max Voltage", max_voltage_recovery, new_battery_stats["max_voltage"],5)
print_comparison("Mean Voltage", mean_voltage_recovery, new_battery_stats["mean_voltage"],5)
print_comparison("Std Dev Voltage", std_dev_voltage_recovery, new_battery_stats["std_dev_voltage"],50)
#
print('\r')
#
if result < 4:
print(f'{COLOR_YELLOW}Results{COLOR_RESET} - {COLOR_Red} === Test Fail ==={COLOR_RESET}') # Green color for close
else:
print(f'{COLOR_YELLOW}Results{COLOR_RESET} - {COLOR_GREEN_BOLD}=== Test Pass ==={COLOR_RESET}') # Green color for close
#
print('\r')
#
except Exception as e:
print(f'An error occurred: {e}')
print(f"{COLOR_GREEN_BOLD}Instrument{COLOR_RESET} - Disable DL3021")
inst.disable() # Switch OFF
#
finally:
print(f"{COLOR_GREEN_BOLD}Instrument{COLOR_RESET} - Disable DL3021")
inst.disable() # Switch OFF
else:
print(f"{COLOR_GREEN_BOLD}Instrument{COLOR_RESET} - DL3021 Device not found")
ER26500 battery tester
*PCBWay community is a sharing platform. We are not responsible for any design issues and parameter issues (board thickness, surface finish, etc.) you choose.
- Comments(0)
- Likes(0)
- 1 USER VOTES
- YOUR VOTE 0.00 0.00
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
-
10design
-
10usability
-
10creativity
-
10content
More by Hélio Pereira
-
-
-
-
-
-
3D printed Enclosure Backplate for Riden RD60xx power supplies
154 1 1 -
-