电池管理系统之神奇的BMS(二)

电量(SOC)算法

除了参数的监控与保护之外,作为BMS系统,其中最重要的功能还有一项,那便是SOC的计算。
  
  SOC,全称是State of Charge,系统荷电状态,也叫剩余电量,代表的是电池使用一段时间或长期搁置不用后的剩余容量与其完全充电状态的容量的比值,常用百分数表示。
  
  其取值范围为0~100,当SOC=0时表示电池放电完全,当SOC=100时表示电池完全充满。
  
  那么SOC有什么意义呢?
  
  任何一个产品,对于一般的终端用户而言,如果对其直接提供电压、电流之类的电池参数,那么用户可能十分费解,因为对他们来说,使用的电源产品唯一能够理解的,似乎就只有电量。
  
  比如当我询问你的手机还剩多少电?你肯定不会回答电池的端电压还有3.54V,而是直接告诉我还剩大概80%。电动车也是一样,我们甚至可以粗糙的用几个柱状图来表示电池当前的状况,这样也总比直接提供准确的电压要好理解很多,即使不准,但能让用户直观的理解工程师想要表达的意思。
  
  因此,计算出准确的SOC,不仅能提升用户体验,而且好能延长产品的使用寿命,这对于任何一块产品而言意义都非常巨大。
  
  在一般的BMS系统中,计算电量的方式大概有两种:
  
  ①:硬件
  
  所谓硬件,便是使用一些专门的电量计芯片来计算电量,比如说TI的BQ34Z100,这是一块基于阻抗跟踪技术的电量计,其计算精度不错,而且操作简单,只需要在前期进行一些简单的操作(使用TI官方软件进行基本参数配置,计算电池化学参数CHEM_ID,进行充放电循环学习导出量产文件等)然后就可以直接从芯片里读出电量值。(电量计芯片的方法本文不涉及,感兴趣的同学可以自行查阅资料)
  
  ②:软件
  
  软件计算SOC的方法也不少,有开路电压法、安时积分法、内阻法、神经网络和卡尔曼滤波法…
  
  开路电压法由于要预计开路电压,因此需要长时间静置电池组,内阻法存在着估算内阻的困难,在硬件上也难以实现,神经网络和卡尔曼滤波法则由于系统设置的困难,而且在电池管理系统中应用时成本很高,不具备优势,因此相对于开路电压法、内阻法、神经网络和卡尔曼滤波法本而言,安时积分由于简单、有效而常被采用。
  本文主要介绍基的BMS的SOC的编程语言算法。
  在这里插入图片描述

积分是一个数学模拟的概念,如果转化为生活语言,就是累积一端时间的量,如果转化为程序语言,就是把某个变量相乘在相加计算和。
  
  安时积分中的基本参量自然是电流,在任何一个能源系统运行之时,最能够体现其运行负荷状态的必然就是电流,比如一个电机,如果想要转的快,回路上的电流必然增大,比如一个灯泡,如果想要更亮更闪,回路上的电流也要增大。

SOC的数学定义是什么?
在这里插入图片描述

上面说过,SOC就是一颗电池还剩多少电,也就是容量,电池容量的定义是,在一定条件下,所放出的电量,即电池的容量,我们通常以安培、小时作为单位,简称安时(用 AH 表示)。
  
  假如有一颗电池当前的容量是20AH,就是说明,如果我们用1A的电流来进行放电,理论上它可以使用20个小时,等我们把这颗电池用光之后,再使用1A的电流来充电,理论上也需要20个小时才能充满。
  
  如果使用2A的电流来充放电,那么时间也会从20小时缩短到10小时……
  
  安时积分的基本原理就是把电流按照时间进行累计,然后记入剩余电量之中,这和用管子朝泳池里灌水是一个道理。
  
  系统启动,传感器开始电流采集,假如每隔20us采集一次,如果采集到的充电电流是1.5A,那么我就认为,在这20us的时间段内,充电电流一直都是1.5A,那么这段时间里增加的电量就是1.5A * 20us(这里为了表达清晰暂时不转换单位)。

系统充电:现在的剩余电量 = 20us前的电量 + 20us内产生的电量;

系统放电:现在的剩余电量 = 20us前的电量 - 20us内产生的电量;
  
  我们采集到的电流信息,是负载/充电器回路上的电流信息,当电流大于某个阈值的时候(300mA),我们认为是放电,当电流小于某个阈值的时候(-300mA),我们认为是充电,这个没有问题,不过,如果采集到的电流为0,那么系统就真的没有任何消耗吗?
  
  当然不是,就算是MCU本身也是需要消耗能源的,它使用的也是电池的电,只不过没有计入积分之中,如果想要算法更加精确,我认为BMS板子的固定功耗是不能忽略的,虽然电流消耗不大,但毕竟是时时刻刻的在消耗,而且这个消耗几乎不会有很大的改变,如果考虑了固定功耗,那么新的算法如下:

系统充电:现在的剩余电量 = 20us前的电量 + 20us内产生的电量 - 系统固定功耗电流;

系统放电:现在的剩余电量 = 20us前的电量 - 20us内产生的电量 - 系统固定功耗电流;

  tim_cal_ms = OSTimeGet() - time;//就算现在经过的时间
    time = OSTimeGet();             //保存现在的时间
    /* 安时积分 */
    /* 容量 = (当前功率电流 - 系统固定功耗) * 时间 */
    cap_mAms = (cap_mAms - (current_mA * tim_cal_ms)) - (SYSTEM_FIXED_POWER_CURRENT * tim_cal);
    /* 充电电量或者放电电量累积超过 10mAh */
    if((cap_mAms > 36000000) || (cap_mAms < -36000000))
    {
   
        capacity += cap_mAms / 3600000;   /*整数个 mAh */
        cap_mAms = cap_mAms  % 3600000;   /* 不足1mAh的电量,做累积 */
    }

以上便是安时积分的基本原理,看着非常简单,不过,现在还有一个问题,20us内产生的电量(current_mA * tim_cal_ms)这个值我是可以计算出来的,但是20us前的电量(cap_mAms)这个值又从何而来呢?
  
  这个自然是来自20us之前的状态,我们再往前推,找到40us前的状态,然后再往前推,找到60us之前的状态……
  
  如果一直往前推以后,肯定会发现一个问题,这个电量算法的安时积分需要一个起点,也就是系统运行之后,我的第一个参与计算的电量是多少?
  
  初始电量的来源一般采用开路电压法来确认,一颗新电池,如果在静态的情况下(无充放电)呆了2个小时以上,那么这个时候直接使用电压来寻找电量是很准确的,比如说3.6V对应100%电量,2.7V对应1%电量,3V对应50%电量,这完全可以做几次充放电实验来列出一个表,横坐标是电压,纵坐标就是电量。

 1 const OCV_VALUE_S  OcvTable_Dischg_1C[101] = {
            {
   2999, 0},
 2         {
   3129, 1},  {
   3262, 2},  {
   3292, 3},  {
   
  • 6
    点赞
  • 91
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值