现阶段网络上的算法读出的血氧值较为不稳定,且许多情况下无法得出有效值,本算法的原理见: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值,在手指移开时的结果如下图所示:
全部代码见:MAX30102与STM32的血氧检测算法-硬件开发文档类资源-CSDN下载
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)