赞
踩
现阶段网络上的算法读出的血氧值较为不稳定,且许多情况下无法得出有效值,本算法的原理见:MAX30102 血氧调试笔记_Yulong_u012183892-CSDN博客_max30102。
为了控制传感器采样的速率,算法在定时器中实现,可以灵活调整采样速率达到更好的效果。定时器中段的服务函数如下:
- //定时器3中断服务程序 读入数据处理
- void TIM3_IRQHandler(void) //TIM3中断
- {
- if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
- {
- TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx更新中断标志
- max30102_read_fifo();//数据读入
- i++;//记录周期数
- int temp=fifo_ir;
- int temp2=fifo_red;
- while(temp+temp2<20000){//未检测出手指时代码会在此处跑死,原因为拟合函数只在检测到手指时有效
- printf("未检测出手指\r\n");
- max30102_read_fifo();
- temp=fifo_ir;
- temp2=fifo_red;
- }
- if(i==0){//周期数值初始
- max=temp;
- min=temp;
- max2=temp2;
- min2=temp2;
- }
- //取得周期内最大最小数据
- if(max<temp){
- max=temp;
- }
- if(min>temp){
- min=temp;
- }
- if(max2<temp2){
- max2=temp2;
- }
- if(min2>temp2){
- min2=temp2;
- }
-
- if(i>=39){//39数据为1周期
- i=0;
- ac=max-min;//单个周期内最大最小数据差为交流分量
- dc=min; //数据=直流分量+交流分量
- ac2=max2-min2;//同理
- dc2=min2;
- max=temp;
- min=temp;
- max2=temp2;
- min2=temp2;
- }
-
- }
- }
取得ac,dc,ac2,dc2后可以由主函数中的代码
- //结果生成,数据较为稳定,开头几个数据可以不要,比较不稳
- ac_ir=(float)ac;//注意转换,否则无法赋值
- dc_ir=(float)dc;
- ac_red=(float)ac2;
- dc_red=(float)dc2;
- R2=(ac_red* dc_ir)/(ac_ir*dc_red);
- SPO2 =-45.060*R2*R2+ 30.354 *R2 + 94.845;
得出较为稳定的血氧结果,串口输出结果如下图所示:
第一列数字为检测出的血氧饱和度,第二列为计算出的R2值,在手指移开时的结果如下图所示:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。