|
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
Project images are for reference only. Actual production is based on the manufacturing files on the project page.
Please review the designer's notes (e.g., PCB thickness) and select the appropriate options.
PCBWay is not responsible
for issues caused by unsuitable parameter selections.
For more important ordering information, please refer to
Read More
Raspberry Pi 5 7 Inch Touch Screen IPS 1024x600 HD LCD HDMI-compatible Display for RPI 4B 3B+ OPI 5 AIDA64 PC Secondary Screen(Without Speaker)
BUY NOW- 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
-
Programmable Mist Maker - XIAO / QT PY Extension
1828 2 2 -
RadioHAT - Raspberry Pi radio development platform
1558 0 3 -
QWIIC-VL53L4CD Time-of-Flight Distance Sensor Module
1771 0 2 -
-
-
ARPS-2 – Arduino-Compatible Robot Project Shield for Arduino UNO
3789 0 6 -
-
A Compact Charging Breakout Board For Waveshare ESP32-C3
4540 3 8 -
AI-driven LoRa & LLM-enabled Kiosk & Food Delivery System
5342 2 2 -







