功能介绍:采用stm32单片机作为主控CPU,采用MAX30102采集心率,采用红外接触传感器来进行计步,OLED显示相关数据,并且将数据通过蓝牙HC-05模块发送到手机APP,完美实现了智能蓝牙手环的相关功能,文末有资料分享:
28-基于stm32单片机心率监测计步智能蓝牙手环(程序+原理图+元件清单全套资料)
程序部分展示,有中文注释,新手容易看懂
//血液检测信息更新
void blood_data_update(void)
{
//标志位被使能时 读取FIFO
g_fft_index=0;
while(g_fft_index < FFT_N)
{
while(MAX30102_INTPin_Read()==0)
{
if(KEY0==0)
{
while(KEY0!=1);
adcx++;
OLED_Printf_EN(6,0,"STEPS:%d ",adcx);
}
//读取FIFO
max30102_read_fifo(); //read from MAX30102 FIFO2
//将数据写入fft输入并清除输出
if(g_fft_index < FFT_N)
{
//将数据写入fft输入并清除输出
s1[g_fft_index].real = fifo_red;
s1[g_fft_index].imag= 0;
s2[g_fft_index].real = fifo_ir;
s2[g_fft_index].imag= 0;
g_fft_index++;
}
}
}
}
//血液信息转换
void blood_data_translate(void)
{
float n_denom;
uint16_t i;
// 4 pt Moving Average
// printf("****************red******************************************************************\r\n");
// for(i = 0;i < FFT_N;i++)
// {
// printf("%f\r\n",s1[i].real);
// }
// printf("***************** ir*****************************************************************\r\n");
// for(i = 0;i < FFT_N;i++)
// {
// printf("%f\r\n",s2[i].real);
// }
//直流滤波
float dc_red =0;
float dc_ir =0;
float ac_red =0;
float ac_ir =0;
for (i=0 ; i<FFT_N ; i++ )
{
dc_red += s1[i].real ;
dc_ir += s2[i].real ;
}
dc_red =dc_red/FFT_N ;
dc_ir =dc_ir/FFT_N ;
for (i=0 ; i<FFT_N ; i++ )
{
s1[i].real = s1[i].real - dc_red ;
s2[i].real = s2[i].real - dc_ir ;
}
//移动平均滤波
//printf("***********8 pt Moving Average red******************************************************\r\n");
for(i = 1;i < FFT_N-1;i++)
{
n_denom= ( s1[i-1].real + 2*s1[i].real + s1[i+1].real);
s1[i].real= n_denom/4.00;
n_denom= ( s2[i-1].real + 2*s2[i].real + s2[i+1].real);
s2[i].real= n_denom/4.00;
}
//八点平均滤波
for(i = 0;i < FFT_N-8;i++)
{
n_denom= ( s1[i].real+s1[i+1].real+ s1[i+2].real+ s1[i+3].real+ s1[i+4].real+ s1[i+5].real+ s1[i+6].real+ s1[i+7].real);
s1[i].real= n_denom/8.00;
n_denom= ( s2[i].real+s2[i+1].real+ s2[i+2].real+ s2[i+3].real+ s2[i+4].real+ s2[i+5].real+ s2[i+6].real+ s2[i+7].real);
s2[i].real= n_denom/8.00;
// printf("%f\r\n",s1[i].real);
}
//printf("************8 pt Moving Average ir*************************************************************\r\n");
// for(i = 0;i < FFT_N;i++)
// {
// // printf("%f\r\n",s2[i].real);
// }
//printf("**************************************************************************************************\r\n");
//开始变换显示
g_fft_index = 0;
//快速傅里叶变换
FFT(s1);
FFT(s2);
//解平方
// printf("开始FFT算法****************************************************************************************************\r\n");
for(i = 0;i < FFT_N;i++)
{
s1[i].real=sqrtf(s1[i].real*s1[i].real+s1[i].imag*s1[i].imag);
s1[i].real=sqrtf(s2[i].real*s2[i].real+s2[i].imag*s2[i].imag);
}
//计算交流分量
for (i=1 ; i<FFT_N ; i++ )
{
ac_red += s1[i].real ;
ac_ir += s2[i].real ;
}
下面是原理图展示: