top of page
Search

Deep Dive: Health Indicators for EV battery assessment – Part I

nishiparikh978

In our previous blogs, we explored the concept of State of Health (SoH) and the underlying aging mechanisms that affect electric motorbike batteries. We also touched upon the importance of everyday practices like charging habits in influencing battery health. But how can we objectively assess battery health and predict its remaining useful life? This blog dives into the technical world of health indicators for data-driven battery diagnostics.


Health Indicators: Unveiling the Battery's Voice:


Batteries don't speak, but they do communicate their health status through a multitude of measurable parameters. These parameters, known as health indicators, provide valuable insights into the battery's internal state and potential degradation. Here are some of the key health indicators for Li-ion batteries in electric motorbikes:


Voltage based features


The voltage of a battery cell or pack is one of the most straightforward and vital indicators of its health. Voltage measurements can provide insights into the state of charge (SoC), and abnormal voltage levels can indicate potential issues such as cell imbalance or degradation. Let’s revisit the cycle aging test of NMC/Graphite battery cell that we saw in previous blog (Click here to read).

import pandas as pd
import matplotlib.pyplot as plt

# Import the data file with information of time, voltage, cycles, SOH
df = pd.read_csv('battery data.csv')

#Visualising the trend of SOH with cycles
plt.plot(data['Cycles'], data['SOH'], linewidth = 3, color = 'r')
plt.xlabel("Cycles")
plt.ylabel("SOH(%)")
plt.title("Sample Battery degradation over charge/discharge cycles")
plt.grid(True)
plt.show()

Visualizing Voltage Trends During Aging


To start, we can visualize the trend of voltage over time during charging and discharging for different cycles. For simplicity, let’s observe the charging data first. The straightforward observation that we can make is that the overall charging time decreases because of decrease in capacity, and in the constant current (CC) phase, the rate of change of voltage (dv/dt) increases with aging.

selected_cycles = [2, 50, 150, 200, 500, 1000]

# Filter data to include only selected cycles
filtered_data = df[df['Cycle number'].isin(selected_cycles)]
# Group by Cycles
grouped = filtered_data.groupby('Cycle number')
# Plot Voltage Profiles for aging cycles
for name, group in grouped:
  group = group.reset_index(drop=True)
   plt.plot(group.index, group['Voltage(V)'], label=f'Cycle {name}')
plt.xlabel('Time (minutes)')
plt.ylabel('Voltage')
plt.title('Voltage vs Time for across Cycles')
plt.legend()
plt.grid(True)
plt.show()

Output:

Investigating Voltage Stochasticity


A closer look at this data motivates us to investigate the stochasticity of the data. To do that, we can divide the data into different voltage windows, for instance, 3.0V – 3.2V, 3.2V – 3.4V, 3.4V – 3.6V, etc. and then study the behavior across different aging cycles. Analyzing smaller chunks of data provides a more granular view of voltage behavior. Moreover, real-world usage patterns may involve incomplete charging or discharging cycles. Analyzing smaller windows helps account for this as well.

One useful health indicator we can look at is the standard deviation of voltage within these windows. As the data points within these windows will decrease because the charging time is reduced, the standard deviation with aging will change.


Lets see an example code to visualize the trend of the discussed health indicators with aging cycles now.

import numpy as np

# Select smaller chunk of the data between any voltage range
filtered_df1 = df[(df['Voltage(V)'] >= 3.3) & (df['Voltage(V)'] <= 3.8)]

grouped_df = filtered_df1.groupby('Cycle number')

#Calculate Charging time
time = grouped_df['Test time'].agg([lambda x: pd.to_datetime(x.iloc[-1]) - pd.to_datetime(x.iloc[0])])
Charging_time = time['<lambda>'].dt.total_seconds()

#Standard Deviation in Voltage
std_dev_voltage = grouped_df['Voltage(V)'].std()

#Calculate dv/dt
voltage_slope = grouped_df.apply(lambda x: np.polyfit(x.index, x['Voltage(V)'], 1)[0])

# Prepare dataframe for health indicators
features_df = pd.DataFrame({
      'Cycle ID': std_dev_voltage.index,
      'Charging Time (s)': Charging_time,
      'Voltage Slope': voltage_slope,
      'Voltage Std Deviation': std_dev_voltage
})
features_df = features_df.reset_index(drop = True)

Sample code to plot the health indicators

plt.plot(features_df['Cycle ID'], features_df['Charging Time (s)']. linewidth = 3)
plt.xlabel("Cycles")
plt.ylabel("Charging time (s)")
plt.title("Charging time with cycles")
plt.grid(True)
plt.show()

The Road Ahead

By understanding the different health indicators and their significance, we can develop strategies to monitor and maintain battery health more effectively. This translates to a more enjoyable riding experience for electric motorbike owners, with longer range, better performance, and ultimately, a greener future for transportation.


Stay tuned for our next blog post, where we will explore more health indicators and delve into the use of machine learning for SoH estimation. In the meantime, share your thoughts on battery health indicators in the comments below.


References



35 views0 comments

Recent Posts

See All

Comments


bottom of page