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

基于单片机的常规肺活量SVC简单计算

常规肺活量 SVC(Slow Vital Capacity)是指尽力吸气后缓慢而又完全呼出的最大气量。

成年男性的肺活量通常在 3500-4000ml 之间,成年女性的肺活量通常在 2500-3000ml 之间。

单片机一般通过外接流量传感器,使用ADC高速采集的方式来获取当前流速数据。

肺活量吹气检查流程大致为 : 呼气 --> 吸气 --> 呼气 --> 深吸气到头 --> 深呼气到头 --> 深吸气 --> 深呼气 --> 深吸气 --> 深呼气。。。

#define nFLOW_SAMPLE               (10)//ms	
#define qAbs(x)                    (((x) > 0.0f) ? (x) : -(x))
#define qFuzzyIsNull(x)            (qAbs(x) <= 0.00001f)
#define qMax(x,y)                  ((x) > (y) ? (x) : (y))
#define qMin(x,y)                  ((x) < (y) ? (x) : (y))

#define STAGE_MAX_SIZE             (1000)

static float vecdStage_1[STAGE_MAX_SIZE] = {0};
static float vecdStage_2[STAGE_MAX_SIZE] = {0};	  
static float vecdStage_3[STAGE_MAX_SIZE] = {0};
static float vecdStage_4[STAGE_MAX_SIZE] = {0}; 


//SVC(slow VC)常规肺活量指标
typedef struct {
    int bIsIntact;     // 源头数据完整性

    float dVT;         // 潮气量 静息呼吸时每次吸入或呼出的气体容积
    float dIRV;        // 补吸气量 平静吸气末用力吸气所能吸入的最大气容积
    float dERV;        // 补呼气量 平静呼气末用力呼气所能呼出的最大气容积
    float dIC;         // 深吸气量 平静呼气末用力吸气所能吸入的最大气容积 IC = VT + IRV
    float dVC;         // 慢肺活量 尽力深吸气后作深慢呼气所能呼出的最大气容积 VC = IC + ERV
    float dDvVC;       // 肺活量差值(3次中的最大差值)
}LungVolExamParam;



/**
过零点位置如下:
呼气 --> (1)吸气 --> (2)呼气 --> (3)深吸气到头 --> (4)深呼气到头 --> (5)深吸气 --> (6)深呼气 --> (7) 深吸气 --> (8) 深呼气 (9)
*/		
LungVolExamParam __calc_svc_test(float*dFlowData,int nSumCnt)
{
    LungVolExamParam tLungVolExamParam = {0};         
	tLungVolExamParam.bIsIntact = true;
	
    int   vecdStage_1_count = 0;
	int   vecdStage_2_count = 0;	  
	int   vecdStage_3_count = 0;
	int   vecdStage_4_count = 0;	  
		
	//流速零点	
    int nZeroPoint = 0; 
	//开始引索
    int nStartIdx = 0;                          

    float dMaxVal, dMinVal;
    float dTmpCapatity = 0;
    float dTmpVC_1, dTmpVC_2, dTmpVC_3;
		
	int real_start_idx = 1;
	
    //分段
    for (int i = real_start_idx; i < nSumCnt; i++) {
		
        //两点间经过零点
        if (dFlowData[i - 1] * dFlowData[i] <= 0 
            && !qFuzzyIsNull(dFlowData[i]))
            nZeroPoint++;

        if(i == nSumCnt - 1) nZeroPoint++;
        
	    //第一段数据采集
        if (3 == nZeroPoint && !vecdStage_1_count) {	
			memcpy(vecdStage_1,dFlowData + nStartIdx,(i - nStartIdx) * sizeof(float));
			vecdStage_1_count = i - nStartIdx;
					
            nStartIdx = i;
        }
		//第二段数据采集
        else if (5 == nZeroPoint &&  !vecdStage_2_count) {
			memcpy(vecdStage_2,dFlowData + nStartIdx,(i - nStartIdx) * sizeof(float));
		    vecdStage_2_count = i - nStartIdx;
					
            nStartIdx = i;
        }
		//第三段数据采集
        else if (7 == nZeroPoint &&  !vecdStage_3_count) {
			memcpy(vecdStage_3,dFlowData + nStartIdx,(i - nStartIdx) * sizeof(float));
			vecdStage_3_count = i - nStartIdx;
					
            nStartIdx = i;
        }
		//第四段数据采集
        else if (9 == nZeroPoint &&  !vecdStage_4_count) {
		    memcpy(vecdStage_4,dFlowData + nStartIdx,(i - nStartIdx) * sizeof(float));
			vecdStage_4_count = i - nStartIdx;
					
            //算上最后一个数据
            nStartIdx = i + 1;  
        }
				
		//达到8后的第一个零点
	   if(8 == nZeroPoint &&
		  dFlowData[i - 1] * dFlowData[i] <= 0 &&
		  !qFuzzyIsNull(dFlowData[i - 1]))
		   nZeroPoint++;
				
    }

    //验证分段数据完整性
	if(!(vecdStage_1_count > 0 && vecdStage_2_count > 0 && vecdStage_3_count > 0 
       && vecdStage_4_count > 0)) 
		 tLungVolExamParam.bIsIntact = false;

    //第一段数据计算
    dMaxVal = dMinVal = dTmpCapatity;

	for (int i = 0; i < vecdStage_1_count; i++) { 
		//流速为L/min,累计流量为当前流速乘以时间
        dTmpCapatity += vecdStage_1[i] * (nFLOW_SAMPLE / 1000.0 / 60.0); 
        if (dMaxVal < dTmpCapatity) dMaxVal = dTmpCapatity;
        if (dMinVal > dTmpCapatity) dMinVal = dTmpCapatity;                
    }

    //潮气量
    tLungVolExamParam.dVT = dMaxVal - dMinVal;  

    //第二段数据计算
    dMaxVal = dMinVal = dTmpCapatity;
    float dTmpVal = dTmpCapatity;              // 记录阶段开始时的气容量

	for (int i = 0; i < vecdStage_2_count; i++) { 
		//流速为L/min,累计流量为当前流速乘以时间
        dTmpCapatity += vecdStage_2[i] * (nFLOW_SAMPLE / 1000.0 / 60); 
        if (dMaxVal < dTmpCapatity) dMaxVal = dTmpCapatity;
        if (dMinVal > dTmpCapatity) dMinVal = dTmpCapatity;
    }

	// 深吸气量
    tLungVolExamParam.dIC = dTmpVal - dMinVal;  
    tLungVolExamParam.dIRV = tLungVolExamParam.dIC - dTmpVal;   // 补吸气量
    tLungVolExamParam.dERV = dMaxVal - dTmpVal; // 补呼气量
    dTmpVC_1 = dMaxVal - dMinVal;               // 第一轮的肺活量

    //第三段数据计算
    dMaxVal = dMinVal = dTmpCapatity;

    for (int i = 0; i < vecdStage_3_count; i++) {	
		//流速为L/min,累计流量为当前流速乘以时间
        dTmpCapatity += vecdStage_3[i] * (nFLOW_SAMPLE / 1000.0 / 60); 
        if (dMaxVal < dTmpCapatity) dMaxVal = dTmpCapatity;
        if (dMinVal > dTmpCapatity) dMinVal = dTmpCapatity;
    }
    dTmpVC_2 = dMaxVal - dMinVal;               // 第二轮的肺活量

    //第四段数据计算
    dMaxVal = dMinVal = dTmpCapatity;

	for (int i = 0; i < vecdStage_4_count; i++) {
		//流速为L/min,累计流量为当前流速乘以时间
        dTmpCapatity += vecdStage_4[i] * (nFLOW_SAMPLE / 1000.0 / 60); 
        if (dMaxVal < dTmpCapatity) dMaxVal = dTmpCapatity;
        if (dMinVal > dTmpCapatity) dMinVal = dTmpCapatity;
    }
    dTmpVC_3 = dMaxVal - dMinVal;               // 第三轮的肺活量

    // 慢肺活量 - 取三次均值
    tLungVolExamParam.dVC = (dTmpVC_1 + dTmpVC_2 + dTmpVC_3) / 3;
    dMaxVal = qMax(dTmpVC_1, dTmpVC_2);
    dMaxVal = qMax(dMaxVal, dTmpVC_3);
    dMinVal = qMin(dTmpVC_1, dTmpVC_2);
    dMinVal = qMin(dMinVal, dTmpVC_3);
	// 最大差值
    tLungVolExamParam.dDvVC = dMaxVal - dMinVal;    

    return tLungVolExamParam;
}

http://www.dtcms.com/a/20154.html

相关文章:

  • LeetCode 热题 100
  • Synchronized 原理
  • DeepSeek R1完全本地部署实战教程01-课程大纲
  • 【Java 面试 八股文】Spring Cloud 篇
  • 鸿蒙中,UIAbility组件启动模式(3种分别是Singleton(单实例模式)Multiton(多实例模式)Specified(指定实例模式))
  • 如何学习Elasticsearch(ES):从入门到精通的完整指南
  • Java短信验证功能简单使用
  • vscode/cursor+godot C#中使用socketIO
  • SpringMVC新版本踩坑[已解决]
  • AUGUST的深度学习笔记(四,现代循环神经网络与注意力机制)
  • $符(前端)
  • 神经网络常见激活函数 9-CELU函数
  • CAS单点登录(第7版)10.多因素身份验证
  • 02.01、移除重复节点
  • Python关于类的一个坑点
  • 【Film Shot】Shot transition detection
  • Dify:修改环境变量并通过 Docker Compose 复用现有容器
  • 新建github操作
  • 【前端进阶】「全面优化前端开发流程」:利用规范化与自动化工具实现高效构建、部署与团队协作
  • Retrieval-Augmented Generation for LargeLanguage Models: A Survey
  • 用C语言解决逻辑推理问题:找出谋杀案凶手
  • C++游戏开发
  • 关于DispatchTime和DispatchWallTime
  • SQL sever数据导入导出实验
  • 【kafka系列】消费者
  • ubuntu /dev/ttyUSB1重命名为/dev/ttyUSB0。
  • CentOS 7.8 安装MongoDB 7教程
  • 【ROS2综合案例】乌龟跟随
  • 【信息学奥赛一本通 C++题解】1281:最长上升子序列
  • 反转链表2(92)