当前位置: 首页 > news >正文

SOC估算方法之(OCV-SOC+安时积分法)

一、引言

此方法主要参考电动汽车用磷酸铁锂电池SOC估算方法这篇论文

总结:

开路电压的测量需要将电池静止相当长的一段时间才能达到平衡状态进行测量。

安时积分法存在初始SOC的估算和累积的误差。

所以上述两种方法都存在一定的缺陷,因此下面主要讲解两种方法混合估算SOC的方法。

二、SOC估算流程图

三、SOC软件设计步骤

四、软件代码的书写

第一步:获取在不同温度时OCV-SOC的曲线

第二步:上电校准SOC

实际采样OCV和关机时保存的电压差超过200mV,那么此OCV可用于上电修正SOC,否则使用之前掉电保存的SOC

第三步:安时积分法

充电时:

//单节最高电压小于3600mV时,进行正常SOC积分

//单节最高电压大于3600mV时,调整SOC积分斜率(目的是充到保护电压时正好SOC=100%)

放电时:

//单节最低电压大于2900mV时,进行正常SOC积分

//单节最低电压小于2900mV时,调整SOC积分斜率(目的是放空时正好SOC=0%)

第四步:完整代码

#include "soc.h"
TLIFE tagLife;
unsigned char SBErrFlashCount;
const unsigned int OCV_SOC[3][38]=   
{{ //表0:电池温度为0℃时,OCV对应SOC2787,										  //0%2897,2992,3059,3107,3150, //1%-5%3159,3166,3172,3178,3184, //6%-10%3189,3195,3200,3205,3209, //11%-15%3214,3219,3223,3227,3231, //16%-20%3235,3238,3242,3246,3249, //21%-25%3252,3255,3258,3261,3264, //26%-30%3266,3269,3271,3274,3276, //31%-35%//此区域都给50%3334,3380,		          //99%-100% 	},{//表1:电池温度为20℃时,OCV对应SOC2837,										  //0%                       2947,3032,3095,3139,3178, //1%-5% 3184,3187,3191,3195,3198, //6%-10%  3202,3206,3210,3214,3218, //11%-15% 3223,3227,3231,3235,3239, //16%-20%  3243,3247,3251,3255,3258, //21%-25%  3262,3265,3269,3272,3275, //26%-30%  3277,3280,3282,3284,3286, //31%-35%  //此区域都给50%		3334,3380,		          //99%-100% 	 	},	{//表2:电池温度为30℃时,OCV对应SOC		2840,					  //0%                     2950,3034,3096,3140,3179, //1%-5%   3185,3188,3192,3195,3199, //6%-10%  3203,3207,3211,3215,3219, //11%-15% 3223,3227,3231,3235,3240, //16%-20%   3244,3248,3252,3256,3259, //21%-25%  3263,3267,3270,3273,3276, //26%-30%  3279,3282,3285,3287,3289, //31%-35%   //此区域都给50%3333,3360,		 		  //99%-100% 	}
};/************************************函数功能描述************************************************
Function Name : PowerONAdjustSOC(void)
Description   : 上电时修正SOC
Input         : 无
Output        : 无
*************************************************************************************************/
void PowerONAdjustSOC(void)
{unsigned int TempMinVoltage,DtV;if(FLASH.BeWriteFlag == ISNO)									  //FLASH数据无效时{tagLife.fRealTotalCapacity = tagLife.fNominalCapacity;   //电池实际总容量为标称容量(mA.h)tagLife.uiSOH_Percent = 100;                             //SOH为100%tagLife.uiDisTimes 	= 0;                                 //清0循环次数	tagLife.uiSOC_Percent = OCVtoSOC(tagBMS.uiMinVoltage);   //通过OCV获得SOCtagLife.fSOC = (tagLife.fNominalCapacity/100)*tagLife.uiSOC_Percent;  //通过SOC计算出当前容量	}	else //FLASH数据有效时{/****实际额定容量不能超过标称容量或不能小于标称容量的80%,否则进行修正****/if(tagLife.fRealTotalCapacity > tagLife.fNominalCapacity){ tagLife.fRealTotalCapacity = tagLife.fNominalCapacity; } else if(tagLife.fRealTotalCapacity < (tagLife.fNominalCapacity*0.5f)){ tagLife.fRealTotalCapacity = tagLife.fNominalCapacity; }TempMinVoltage = FLASH.ReadData[7];      //读取上次掉电前最低节电压if(tagBMS.uiMinVoltage > TempMinVoltage) //如果上电后实际采样OCV和关机时保存的电压差超过200mV,那么此OCV可用于上电修正SOC,否则使用之前掉电保存的SOC{DtV = tagBMS.uiMinVoltage - TempMinVoltage;}else{DtV = TempMinVoltage - tagBMS.uiMinVoltage;}	if( DtV >= 200 ) //压差过大,进行OCV修正{tagLife.uiSOC_Percent = OCVtoSOC(tagBMS.uiMinVoltage); 		//通过OCV重新获得SOCtagLife.fSOC = (tagLife.fNominalCapacity/100) * tagLife.uiSOC_Percent;  //通过SOC计算出当前电量}}	tagLife.ulWorkTime = 0;
}/************************************函数功能描述************************************************
Function Name : OCVtoSOC(unsigned int ocv)
Description   : 通过OCV获得SOC
Input         : OCV 开路电压值
Output        : SOC 电量值(%)
*************************************************************************************************/
unsigned int OCVtoSOC(unsigned int ocv) 
{unsigned char i=0,socarray=1,tempsoc;		获取电池温度,找对应数组	if(tagBMS.iNtcTemp[0] < 10) {socarray = 0; //电池温度小于10℃,选用表0}else if(tagBMS.iNtcTemp[0] < 25){socarray = 1; //电池温度10-25℃,选用表1}else {socarray = 2; //电池温度大于25℃,选用表2}电压查表得SOC		while(ocv > OCV_SOC[socarray][i]){i++;	if( i >= 38 ){ break; }} switch(i){case 36:  tempsoc = 50;  break; //平台区默认SOC=50%case 37:  tempsoc = 99;  break;		case 38:  tempsoc = 100; break;		default : tempsoc = i;   break;}return tempsoc;
}
/************************************函数功能描述************************************************
Function Name : CurrentIntegral(void)
Description   : 电流积分,10mS处理一次
Input         : 无
Output        : 无
*************************************************************************************************/
void CurrentIntegral(void)
{tagLife.fAddCapacity += tagBMS.ulBusCurrent;//单位mA
}/************************************函数功能描述************************************************
Function Name : PackSOCCalculate
Description   : SOC计算,1S执行一次
Input         : 无
Output        : 无
*************************************************************************************************/
void PackSOCCalculate(void)
{	FP32  ChgAf  = 0.93;   //充电电流补偿因子(调整充电时电量上升斜率,使其尽量接近充满时的斜率)FP32  DchgAf = 0.93;   //放电电流补偿因子(调整放电时电量下降斜率,使其尽量接近放空时的斜率)FP32           surtim;     //当前到满充或满放的时间,即:变化斜率 static INT     dtv;        //单位时间(这里为1S)电压变化值static UCHAR   cof,dcof;   //满充、满放标志	//放电时计算SOC		if(( tagSBS.bCell_DSGING_Status == ISYES )&&( tagSBS.bCell_CHGING_Status == ISNO )&&( dcof ==  ISNO ))//检测为放电状态,且不为满放{cof   = ISNO;  //清满充标志	if(tagBMS.uiMinVoltage > 2900)//单节最低电压大于2900mV时,进行正常SOC积分{tagLife.fAddCapacity = tagLife.fAddCapacity/360000; //加100次后求平均值,单位mA.S=>mA.H		if( tagLife.uiSOC_Percent <= 1 ){ tagLife.fAddCapacity = 0; } //防止最低节电压还未低于2900mV,电量就达到了0% 						tagLife.iDchgLastVoltag = tagBMS.uiMinVoltage;}						else//单节最低电压小于2900mV时,调整SOC积分斜率(目的是放空时正好SOC=0%){dtv = tagLife.iDchgLastVoltag - tagBMS.uiMinVoltage; //求1S后的电压变化值	tagLife.iDchgLastVoltag = tagBMS.uiMinVoltage;if( dtv > 0 ){				surtim = (tagBMS.uiMinVoltage - SET_UV)/dtv;    //求按照当前放电电流到放空剩余时间(S)				tagLife.fAddCapacity = tagLife.fSOC/surtim;     //求每次减少的容量 = 当前容量/到放空的时间   }else{tagLife.fAddCapacity = 0;		//电压未变化,容量增量为0						//tagLife.fAddCapacity = tagLife.fAddCapacity/360000; //加100次后求平均值,单位mA.S=>mA.H												}						}tagLife.fSOC = tagLife.fSOC - tagLife.fAddCapacity*DchgAf;     //单位mA.Hif( tagLife.fSOC <= 0 ){tagLife.fSOC = 0;                       //限制tagLife.ulSOC不小于0	}			tagLife.fTotalDisCapacity += tagLife.fAddCapacity; //累加放电容量(用于计算循环次数) if( tagLife.fTotalDisCapacity >= tagLife.fRealTotalCapacity ){tagLife.fTotalDisCapacity = 0; tagLife.uiDisTimes++;                   //如果放电累加容量达到额定容量,循环次数加一	} 	}/ //充电时计算SOCelse if((tagSBS.bCell_CHGING_Status == ISYES)&&( tagSBS.bCell_DSGING_Status == ISNO) &&( cof ==  ISNO ))//检测为充电状态,且不为满充{		dcof = ISNO;  //清满放标志	if(tagBMS.uiMaxVoltage < 3600)//单节最高电压小于3600mV时,进行正常SOC积分{tagLife.fAddCapacity = tagLife.fAddCapacity/360000;            //加100次后求平均值,单位mA.S=>mA.H	if( tagLife.uiSOC_Percent >= 99 ){ tagLife.fAddCapacity = 0; } //防止最高节电压还未超过3450mV,电量就达到了100% 			tagLife.iChgLastVoltag  = tagBMS.uiMaxVoltage;	}						else//单节最高电压大于3600mV时,调整SOC积分斜率(目的是充到保护电压时正好SOC=100%){dtv = tagBMS.uiMaxVoltage - tagLife.iChgLastVoltag;   //求每个时间周期后的电压变化值(1S)tagLife.iChgLastVoltag = tagBMS.uiMaxVoltage;if( dtv > 0 ){	surtim = (SET_OV - tagBMS.uiMaxVoltage)/dtv; //求按照当前充电电流到充满剩余时间(S)				tagLife.fAddCapacity = (tagLife.fRealTotalCapacity - tagLife.fSOC)/surtim; //求每次增加的容量=(总容量-当前容量)/到充满的时间  }else{tagLife.fAddCapacity = 0;		//电压未变化,容量增量为0		//tagLife.fAddCapacity = tagLife.fAddCapacity/360000;    //加100次后求平均值,单位mA.S=>mA.H												}		}tagLife.fSOC = tagLife.fSOC + tagLife.fAddCapacity*ChgAf;   //单位mA.Hif(tagLife.fSOC > tagLife.fRealTotalCapacity )           //充电时增加的总电量不能超过总容量{ tagLife.fSOC = tagLife.fRealTotalCapacity; }			}tagLife.uiSOC_Percent =(tagLife.fSOC*100)/tagLife.fRealTotalCapacity; //计算SOC值	if( tagLife.uiSOC_Percent >= 100 ) //满充{tagLife.uiSOC_Percent = 100;   //soc不能大于100%cof  = ISYES; //置满充标志	}else if( tagLife.uiSOC_Percent <= 1 ) //满放{tagLife.uiSOC_Percent = 1;    //soc不能小于1%				dcof  = ISYES; //置满放标志} tagLife.fAddCapacity = 0;	//将1S钟累加的容量清0,重新累加	tagLife.ulWorkTime++;     //计算工作时间(S)		//满放—满充对tagLife.RealQ修正if( tagSBS.bCell_UVS_Status == ISYES ) //AFE产生欠压保护(放电过程中){tagLife.bCellEmptyFlag = ISYES;   //电池放空标志		tagLife.fSOC = 0;                 //修正当前容量0mAH							}	if(( tagSBS.bCell_OVS_Status == ISYES )&&( tagBMS.ulBattV >= 5440 )) //AFE产生过压保护(充电过程中),且总电压大于54.4v{if( tagLife.bCellEmptyFlag == ISYES )     //如果电池放空过(说明电池进行了一次满放满充){tagLife.bCellEmptyFlag = ISNO; 		    //清除放空标志tagLife.fRealTotalCapacity = tagLife.fSOC;   //电池充满后变化值为电池实际额定容量	tagLife.uiSOH_Percent = (tagLife.fRealTotalCapacity*100)/tagLife.fNominalCapacity; //求电池SOH}														}							
}

相关文章:

SOC估算方法之(OCV-SOC+安时积分法)

一、引言 此方法主要参考电动汽车用磷酸铁锂电池SOC估算方法这篇论文 总结&#xff1a; 开路电压的测量需要将电池静止相当长的一段时间才能达到平衡状态进行测量。 安时积分法存在初始SOC的估算和累积的误差。 所以上述两种方法都存在一定的缺陷&#xff0c;因此下面主要讲…...

指针(下)

文章目录 指针(下)野指针、空指针野指针空指针 二级指针**main**函数的原型说明 常量指针与指针常量常量指针指针常量常量指针常量 动态内存分配常用函数**malloc****calloc****realloc****free** **void**与**void***的区别扩展&#xff1a;形式参数和实际参数的对应关系 指针…...

C# 浅谈IEnumerable

一、IEnumerable 简介 IEnumerable 是一个接口&#xff0c;它定义了对集合进行迭代所需的方法。IEnumerable 接口主要用于允许开发者使用foreach循环来遍历集合中的元素。这个接口定义了一个名为 GetEnumerator 的方法&#xff0c;该方法返回一个实现了 IEnumerator 接口的对象…...

mmdebstrap:创建 Debian 系统 chroot 环境的利器 ️

文章目录 mmdebstrap 的一般性参数说明 &#x1f4dc;mmdebstrap 的常见用法示例 &#x1f308;使用 mmdebstrap 的注意事项 ⚠️ &#x1f308;你好呀&#xff01;我是 山顶风景独好 &#x1f388;欢迎踏入我的博客世界&#xff0c;能与您在此邂逅&#xff0c;真是缘分使然&am…...

【Linux SQLite数据库】一、SQLite交叉编译与移植

SQLite 是一个用 C 语言编写的开源、轻量级、快速、独立且高可靠性的 SQL 数据库引擎&#xff0c;它提供了功能齐全的数据库解决方案。SQLite 几乎可以在所有的手机和计算机上运行&#xff0c;它被嵌入到无数人每天都在使用的众多应用程序中。此外&#xff0c;SQLite 还具有稳定…...

每天写两道(数组篇)移除元素、

27.移除元素 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k&#xff0c;要通过此题&#xff0c;您需要执行以下操作&#…...

Unity 使用 NewtonSoft Json插件报错

JsonReaderException: Unexpected character encountered while parsing value: . Path , line 0, position 0. 通过断点发现&#xff0c;头有一串ZWNBSP&#xff0c;这个是BOM格式的JSON。在文件下看不到。 解决方法&#xff1a;改编码格式&#xff0c;Remove BOM....

k8s 部署 Mysqld_exporter 以及添加告警规则

最近监控 mysql 数据库&#xff0c;用了 pmm-server、pmm-client 发现监控是真的不太好用&#xff0c;还是用回 prometheus 吧。 部署mysqld_exporter k8s 部署最新版本的 mysqld_exporter&#xff0c;支持的数据库版本 MySQL >5.6、MariaDB > 10.3。 先在数据库创建用…...

基于STM32开发的智能农业环境监测系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 初始化代码控制代码应用场景 农田环境监测温室环境控制常见问题及解决方案 常见问题解决方案结论 1. 引言 智能农业环境监测系统通过集成多种环境传感器&#xff0c;实时监测土壤湿度、温度…...

【SQL】平均售价

目录 题目 分析 代码 题目 表&#xff1a;Prices ------------------------ | Column Name | Type | ------------------------ | product_id | int | | start_date | date | | end_date | date | | price | int | ---------------…...

存储器与CPU的连接

1.单块存储芯片与CPU的连接 单独的一块独立的存储芯片提供的线有&#xff1a;地址总线&#xff0c;数据总线&#xff0c;读写控制线&#xff0c;片选线&#xff0c;如果该存储器只有八根数据总线用于输出数据&#xff0c;而cpu一次可以读64位的数据呢&#xff1f; 我们可以将八…...

unity--webgl 访问本地index.html

目录 1:使用本地服务器 1.1 使用 Python 的 SimpleHTTPServer 1.2 使用 Node.js 的 http-server 2&#xff1a;让其他人通过 IP 地址来访问你的 Unity WebGL 项目 2.1: 确保服务器可访问 2.2 获取公共 IP 地址 2.3 配置本地服务器 1.使用 Python 的 SimpleHTTPServer 2…...

慢慢欣赏DPDK RTE_MAX_ETHPORTS的定义

DPDK代码里面&#xff0c;RTE_MAX_ETHPORTS是一个常见的宏定义&#xff0c;但是在.c和.h文件找不到其定义&#xff0c;在全文件搜索条件下&#xff0c;在config/meson.build找到这么一个定义 dpdk_conf.set(RTE_MAX_ETHPORTS, get_option(max_ethports)) 该宏定义是根据构建输…...

Java Nacos与Gateway的使用

Java系列文章目录 IDEA使用指南 Java泛型总结&#xff08;快速上手详解&#xff09; Java Lambda表达式总结&#xff08;快速上手详解&#xff09; Java Optional容器总结&#xff08;快速上手图解&#xff09; Java 自定义注解笔记总结&#xff08;油管&#xff09; Jav…...

前端项目中的Server-sent Events(SSE)项目实践及其与websocket的区别

前端项目中的Server-sent Events(SSE)项目实践 前言 在前端开发中&#xff0c;实时数据更新是提升用户体验的重要因素之一。Server-SentEvents(SSE)是一种高效的技术&#xff0c;允许服务器通过单向连接将实时数据推送到客户端。下面将从SSE的基本改变&#xff0c;使用场景展…...

《老俞闲话|唯爱和热情不可辜负》读后感

《老俞闲话&#xff5c;唯爱和热情不可辜负》读后感 俞敏洪先生的这篇讲话充满了深情与智慧&#xff0c;他以自己丰富的人生经历和教育实践&#xff0c;向我们展现了一位教育家对于教育事业的热爱和对教师角色的深刻理解。 情感真挚&#xff0c;触动人心 俞敏洪先生的讲话中流…...

C语言 ——— 在杨氏矩阵中查找具体的某个数

目录 何为杨氏矩阵 题目要求 代码实现 何为杨氏矩阵 可以把杨氏矩阵理解为一个二维数组&#xff0c;这个二维数组中的每一行从左到右是递增的&#xff0c;每一列从上到下是递增的 题目要求 在杨氏矩阵中查找具体的某个数 要求&#xff1a;时间复杂度小于O(N) 代码实现…...

DAI-Net: 基于对偶自适应交互网络的药物推荐算法

引言 DAI-Net: Dual Adaptive Interaction Network for Coordinated Medication Recommendation 论文链接&#xff1a;https://ieeexplore.ieee.org/document/10614809 代码链接&#xff1a;GitHub - obananas/DAI-Net 在现代医疗保健中&#xff0c;如何利用电子健康记录&a…...

haproxy高级功能及配置

章节 一、haproxy 基础用法 二、haproxy 高级用法 三、haproxy之ACL的使用 目录 1 基于cookie的会话保持 1.1 cookie命名&#xff0c;并赋予其值 1.2 验证cookie信息 1.2.1 Windows浏览器验证 1.2.2 Linux下虚拟机验证 2 IP透传 2.1 四层与七层透传的区别 2.2 七层IP透传 2.2…...

【前端】NodeJS:记账本案例优化(MongoDB数据库)

文章目录 1 字符串转为时间对象——Moment2 记账本实例优化 1 字符串转为时间对象——Moment Moment.js中文网&#xff1a;https://momentjs.cn/docs/#/parsing/。 npm install moment // 安装moment var moment require(moment); // require moment().format(); 2 记账本实…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

【SpringBoot自动化部署】

SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一&#xff0c;能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时&#xff0c;需要添加Git仓库地址和凭证&#xff0c;设置构建触发器&#xff08;如GitHub…...

CppCon 2015 学习:Time Programming Fundamentals

Civil Time 公历时间 特点&#xff1a; 共 6 个字段&#xff1a; Year&#xff08;年&#xff09;Month&#xff08;月&#xff09;Day&#xff08;日&#xff09;Hour&#xff08;小时&#xff09;Minute&#xff08;分钟&#xff09;Second&#xff08;秒&#xff09; 表示…...

Windows 下端口占用排查与释放全攻略

Windows 下端口占用排查与释放全攻略​ 在开发和运维过程中&#xff0c;经常会遇到端口被占用的问题&#xff08;如 8080、3306 等常用端口&#xff09;。本文将详细介绍如何通过命令行和图形化界面快速定位并释放被占用的端口&#xff0c;帮助你高效解决此类问题。​ 一、准…...