【SOC的多种计算方法】

电子说

1.2w人已加入

描述

soc的估算方法大致有五种:电流积分法、开路电压法、阻抗法、智能估算法、状态观测器。今天先给大家介绍前两种方法。

什么是SOC
电池的状态(State of Charge,SOC)是电池能够提供的电荷总量与总电荷容量的比率,通常用百分比表示。在电池管理系统(Battery Management System,BMS)中,精准地计算电池的SOC是非常重要的,因为它可以帮助BMS判断电池的剩余能量,从而控制电池的使用和充放电过程,延长电池的寿命。

目前,常用的计算电池SOC的方法主要有电流积分法和开路电压法。这两种方法各有优缺点,但都存在一定的误差。因此,在实际应用中,常常将两种方法结合起来使用,以提高SOC的精度。

soc

本文将详细介绍如何使用电流积分法和开路电压法结合起来计算电池的SOC。

一、电流积分法
电流积分法是一种通过对电池的充放电电流进行积分,来计算电池SOC的方法。它的优点在于计算过程简单,不需要进行标定。下面是电流积分法的具体步骤:

步骤1:记录电池开始充电或放电时的SOC。

步骤2:记录电池充放电时的电流。

步骤3:对电池的电流进行积分,得到电池的电量变化量。

步骤4:根据电量变化量和开始时的SOC,计算出当前的SOC。

公式:SOC = 初始SOC + ∫(I*dt)/Q

其中,I表示电流,Q表示电池的电量,dt表示时间间隔。

需要注意的是,由于电池内阻等因素的存在,电流积分法的计算结果存在一定的误差。此外,电流积分法只能对电池进行较长时间的充放电测试,才能得到较为准确的结果。

二、开路电压法
开路电压法是通过测量电池的开路电压(即在没有负载情况下的电压)来计算电池SOC的方法。开路电压法的优点在于计算过程简单,无需进行电流测量。下面是开路电压法的具体步骤:

步骤1:根据电池的型号和厂家提供的SOC-开路电压曲线,建立SOC和开路电压之间的关系。

步骤2:测量电池的开路电压。

步骤3:根据步骤1中建立的SOC-开路电压曲线,计算出当前的SOC。

需要注意的是,电池的SOC-开路电压曲线是随着电池的使用和寿命的变化而变化的,因此,需要定期进行标定,以确保计算结果的准确性。

另外,由于电池的内阻等因素的影响,开路电压法也存在一定的误差。尤其在高放电状态下,误差会更大。

三、结合使用电流积分法和开路电压法
电流积分法和开路电压法各自有其优缺点,因此,在实际应用中,常常将两种方法结合起来使用,以提高SOC的精度。

结合使用电流积分法和开路电压法的具体步骤如下:

步骤1:使用电流积分法记录电池的充放电情况,并得到当前的SOC1。

步骤2:使用开路电压法测量电池的开路电压,并根据SOC-开路电压曲线计算出当前的SOC2。

步骤3:根据SOC1和SOC2,计算出当前的SOC。

公式:SOC = k1SOC1 + k2SOC2

其中,k1和k2是权重系数,它们的和等于1。权重系数的选择需要考虑到电池的使用情况、测试时间和测试精度等因素。一般来说,如果电池进行了较长时间的充放电测试,那么k1的值应该更大;如果电池的开路电压测量精度较高,那么k2的值应该更大。

需要注意的是,在结合使用电流积分法和开路电压法时,需要进行相应的标定工作,以保证计算结果的准确性。此外,电池的内阻、温度等因素对计算结果也有一定的影响,需要进行相应的校正。

四、结论
综上所述,电流积分法和开路电压法是计算电池SOC的两种主要方法,它们各自有其优缺点。为了提高SOC的精度,在实际应用中,常常将两种方法结合起来使用。通过结合使用电流积分法和开路电压法,可以克服各自的缺点,提高SOC的精度和可靠性。然而,在使用这两种方法时需要进行相应的标定和校正,以保证计算结果的准确性。

第一种:电压法
在 STM32 中,电池电量百分比的计算需要考虑到电池的电压曲线和电量曲线。一般来说,电量百分比可以通过下面的公式计算:

电量百分比 = (当前电压值 - 最低电压值)/(最高电压值 - 最低电压值)* 100%

其中,最低电压值和最高电压值需要根据电池的实际情况进行设置。在实际使用中,可以通过 ADC 模块读取电池的电压值,然后将其转换为电量百分比。具体的 C 语言代码如下:
 

 

#define ADC_MAX_VALUE 4096 // ADC 最大值
#define VOLTAGE_DIVIDER_RATIO 2 // 电压分压比
#define BATTERY_MAX_VOLTAGE 4.2 // 电池满电电压
#define BATTERY_MIN_VOLTAGE 3.0 // 电池极低电压

float get_battery_voltage(void) {
uint16_t adc_value = HAL_ADC_GetValue(&hadc); // 读取 ADC 值
float voltage = (float)adc_value / ADC_MAX_VALUE * VREF * VOLTAGE_DIVIDER_RATIO; // 转换为电压值
return voltage;
}

uint8_t get_battery_percentage(void) {
float voltage = get_battery_voltage();
uint8_t percentage = (voltage - BATTERY_MIN_VOLTAGE) / (BATTERY_MAX_VOLTAGE - BATTERY_MIN_VOLTAGE) * 100;
return percentage;
}

 

以上代码假设使用的 ADC 通道已经初始化并启动,get_battery_voltage() 函数用于读取电池电压值,get_battery_percentage() 函数用于计算电量百分比。需要注意的是,上述代码仅供参考,实际使用中需要根据具体情况进行调整。

第二种:累积电量积分法
对于电池管理系统(BMS)的电量计算,一般采用累积电量积分法。要计算电池的电量百分比,需要知道当前电池的电量和额定电量。以下是一种简单的实现方法:

获取电池实际电压值,单位为毫伏(mV)。

获取电池额定电压值,单位为毫伏(mV)。

计算电池当前电量,单位为毫安时(mAh)。

计算电池额定电量,单位为毫安时(mAh)。

根据以下公式计算电池电量百分比:电量百分比 = 当前电量 / 额定电量 * 100%

在BMS中,可以使用ADC模块来获取电池实际电压值,并使用电流传感器来获取电池充放电电流值,从而计算电池当前电量。以下是一种简单的代码实现:
 

 

#define VBAT_R1 10000 // 电阻R1的值,单位为欧姆(Ω)
#define VBAT_R2 10000 // 电阻R2的值,单位为欧姆(Ω)
#define VBAT_ADC_RES 4096 // ADC的分辨率
#define VBAT_R1_R2_RATIO 0.5 // R1和R2的比值

float get_battery_voltage(void)
{
uint16_t adc_value = 0;
float voltage = 0;
// 读取ADC的值
adc_value = HAL_ADC_GetValue(&hadc1);

// 根据ADC的值计算电压值
voltage = (float)adc_value * 3.3 / (float)VBAT_ADC_RES * VBAT_R1_R2_RATIO;

// 根据电压分压计算实际电池电压值
voltage = voltage / (VBAT_R2 / (VBAT_R1 + VBAT_R2));

return voltage;
}

float get_battery_current(void)
{
uint16_t adc_value = 0;
float current = 0;
// 读取ADC的值
adc_value = HAL_ADC_GetValue(&hadc2);

// 根据ADC的值计算电流值
current = ((float)adc_value - 2048) * 3.3 / 4096 / 0.04;

return current;
}

float get_battery_capacity(float current, float time)
{
float capacity = 0;
// 计算电量
capacity = current * time / 3600;

return capacity;
// 计算电池当前电量
float current = get_battery_current();
float time = 1; // 积分时间,单位为秒
float current_capacity = get_battery_capacity(current, time);
capacity += current_capacity;

// 计算电池电量百分比
percentage = (int)(capacity / rated_capacity * 100);

// 限制百分比在0-100之间
percentage = percentage > 100 ? 100 : percentage;
percentage = percentage < 0 ? 0 : percentage;

return percentage;
}

 

其中,get_battery_voltage()函数用于获取电池实际电压值,get_battery_current()函数用于获取电池充放电电流值,get_battery_capacity()函数用于计算电池当前电量,get_battery_percentage()函数用于计算电池电量百分比。在使用时,需要提供电池的额定电压、电量和实际电压等参数。

注意,在计算电池当前电量时,需要进行电流积分,积分时间可以根据实际应用场景进行调整。

第三种:开路电压法
开路电压法是一种基于电池开路电压与SOC之间的关系计算SOC的方法。具体计算公式如下:

SOC = f(V_oc)

其中,V_oc是电池的开路电压,f是一种特定的函数,它反映了电池开路电压与SOC之间的关系。不同类型的电池有不同的f函数,常见的有线性关系、二次函数关系等。下面是使用C语言实现线性函数开路电压法计算电池SOC的代码示例:
 

 

#include < stdio.h >
int main()
{
// 输入电池的电压、最小电压和最大电压
float voltage, min_voltage, max_voltage;
printf(“请输入电池的电压、最小电压和最大电压(以空格分隔):”);
scanf("%f %f %f", &voltage, &min_voltage, &max_voltage);
// 计算电池的SOC
float soc = (voltage - min_voltage) / (max_voltage - min_voltage) * 100;
printf(“电池的SOC为:%.2f%%”, soc);
return 0;
}

 

第四种:卡尔曼滤波法
卡尔曼滤波法是一种基于电池电流、电压及其他信息计算SOC的方法,它采用了状态估计和卡尔曼滤波技术。具体实现过程比较复杂,需要借助数学模型和计算机算法。下面是使用C语言调用卡尔曼滤波库计算电池SOC的代码示例:

 

#include < stdio.h >
#include “kalman.h”
int main()
{
// 初始化卡尔曼滤波器
kalman_state state;
kalman_init(&state, 1.0, 1.0, 1.0, 0.0);
// 输入电池的电流和电压
float current, voltage;
printf(“请输入电池的电流和电压(以空格分隔):”);
scanf("%f %f", ¤t, &voltage);
// 使用卡尔曼滤波器计算电池SOC
float soc = kalman_update(&state, current, voltage);
printf(“电池的SOC为:%.2f%%”, soc);
return 0;
}
soc

 

有需要的可以给作者留言

审核编辑 黄宇

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分