常用电池电量计算方法
一.查表法
正常来说,电池厂商会提供一个OCV曲线表,在不同的温度下,OCV曲线不同,当然不同的温度下的,其电量也不尽相同,
不同的电压值对应不同的电量百分比
优点:便于调节
缺点:需要测试测很多组数据,进行平均,尤其是电池一致性不好时,处理起来,更费劲。
const int ocv_4v4[] = {
3200,
3300,3350,3380,3400, 3424,3525,3594,3644,3671,3680,
3684,3686,3688,3689,3692,3700,3709,3715,3722,3729,
3735,3739,3744,3747,3751,3756,3760,3764,3767,3771,
3775,3778,3782,3786,3789,3793,3797,3801,3805,3809,
3813,3818,3822,3827,3832,3837,3842,3848,3854,3860,
3866,3873,3880,3888,3896,3906,3917,3930,3943,3955,
3964,3972,3979,3988,3999,4013,4030,4047,4059,4067,
4074,4084,4096,4107,4119,4131,4142,4154,4166,4177,
4189,4202,4214,4226,4238,4250,4263,4275,4287,4300,
4312,4324,4336,4348,4350,4355,4358,4359,4360,4362,
};
const int ocv_4v1[] = {
3200,
3300,3350,3380,3400,3424,3525,3594,3644,3671,3680,
3684,3686,3688,3689,3692,3700,3709,3715,3722,3729,
3735,3739,3744,3747,3751,3756,3760,3764,3767,3771,
3775,3778,3782,3786,3789,3793,3797,3801,3805,3809,
3813,3818,3822,3827,3832,3837,3842,3848,3852,3857,
3860,3866,3870,3876,3880,3884,3888,3895,3899,3906,
3910,3915,3918,3920,3925,3930,3935,3942,3947,3950,
3955,3960,3964,3972,3979,3982,3988,3993,3999,4005,
4007,4013,4018,4020,4025,4030,4035,4040,4042,4047,
4053,4059,4063,4068,4074,4080,4085,4090,4095,4103,
};
define OCV_SIZE 100
for( i = 1 ;i < OCV_SIZE; i++ ){
if(volt < ocv_table[i])
break;
}
printk("volt :%d ,ocv_table is [%d] \n",volt,i);
return i;
}
二 曲线拟合法
相比上面的查表法,要稍一点技术含量,需要根据电池厂商提供的曲线来进行做几段的曲线拟合
term_volt = term_volt -40;
current_mv = upm->bat_volt;
if(current_mv >= term_volt ){
present = 100;
return present;
}
molecule = term_volt - current_mv ;
denominator = term_volt - UPM6920_CLOSE_VOLT;
present =100 - (( molecule*100) / denominator) ;
if(present >= 99)
present = 100;
更复杂一点,用积分去拟合,其实就是单线拟合改多线去拟合
用积分方式,把电池放电曲线,按同等时间分成10等分,每等分看似一个固定斜率
#define ARRAY_DIM(a) (sizeof(a) / sizeof((a)[0]))
const static int Battery_Level_Percent_Table[11] = {3000, 3650, 3700, 3740, 3760, 3795, 3840, 3910, 3980, 4070, 4150};
int toPercentage(int voltage)
{
int i = 0;
if(voltage < Battery_Level_Percent_Table[0])
return 0;
for(i; i<ARRAY_DIM(Battery_Level_Percent_Table); i++){
if(voltage < Battery_Level_Percent_Table[i])
return i*10 - (10UL * (int)(Battery_Level_Percent_Table[i] - voltage)) /
(int)(Battery_Level_Percent_Table[i] - Battery_Level_Percent_Table[i-1]);;
}
return 100;
}
/*
测试函数,输入电压值,输出百分比值
*/
void test_func(void)
{
int i;
while(1){
printf("please input value:");
scanf("%d",&i);
printf("valu = %d\n",toPercentage(i));
}
}
Battery_Level_Percent_Table中是电压的参考值,从0~100共11个点,电压值的单位为mV。
优点:不用去做一个表去查,只需要根据厂商的电池曲线进行做一元方程,即可
缺点:如果曲线非线性,过于多的直线去拟合,导致算法过于复杂。
打赏作者
近期评论