STM32与ADS1292R在心率与体温检测中的LMT70应用与跌到检测解析

实验目的:

        以stm32f103c8t6为主控,实时检测心率,体温以及防摔检测,并通过OLED实时显示心率、体温,通过UI制作的小人站立和跌到状态,同时会有蜂鸣器报警警报。

显示效果:

        通过我们自研的心电发生器产生固定心率,在oled上显示

硬件器材:

        1、ads1292R 心电采集模块。

        2、LMT70温度检测传感器。

        3、mpu6050陀螺仪。

        4、四线 IIC 0.96 OLED。

        5、stm32f103c8t6控制板。

        6、蜂鸣器跌到报警。

        ads1292R从某宝购买,可以显示心电图和心率,这里只需要用到心率,因此将心率显示在OLED上,程序上不是很难,spi通信,但是跟其他模块一起工作时有一个时序问题,我在调试的时候就出现了,显示温度不能显示心率,显示心率则不能显示温度的问题,后来是时序的问题。

        LMT70没有买模块,这个温度传感器程序很好实现,通过stm32自带的adc,只需要配置ad采样即可,LMT70输出的是模拟量,根据模拟量还换算温度,有一个温度换算公式,我会在下面写出。

        难点在于焊接上,BGA封装,看起来就像一个芝麻大小,四个引脚,不容易焊接,我这种焊接技能满级的选手都打怵,大家还是老实买个模块吧。电路刚开始加了一个运放做跟随器,但是调试的时候发现,温度会乱跳,把电压跟随器摘掉后,温度便恢复正常。

        MPU6050主要是用来检测人体跌到的,跌到的部分也是很容易实现,这个模块的难点在于DMP初始化的时候有一个self_detect,也就是第8步的自检,你实际做的时候就会遇到我说的这个问题。解决方法可以参考网上的方法,还有一个难点是,不同家买的模块,解决方法不一样。。。。

        检测跌到主要从两个方面,一个是检测加速度,一个是检测倾斜角度,可以都使用,也可以只使用一种方法,但是我发现实际检测的时候加速度很灵敏,我的鼠标在桌子上震动一下,就会提示摔倒,然后我就把这个方法给去掉了,只保留了检测倾斜角度,设置的角度是60度,但是我发现实际的角度快有90度了,这个误差没有影响,60度和90度都可以作为摔倒的检测条件。

        检测摔倒用了一个“小人”的图标来表示站立和跌到。

        另外加了蜂鸣器,跌到的时候会蜂鸣提示声音,滴滴滴。

软件:

   软件很简单了,主要是检测心率,温度,跌到和OLED显示。

   LMT70温度检测部分,LMT70传感器有一个算法, 需要将ADC采集的模拟量进行计算,就可以得到实际的温度,我跟实际室温比较了一下,感觉温度没有什么问题。

if(sys_tick - lmt70_tick > 100) 
    {
	    lmt70_tick = sys_tick;
		AD_value=get_adc();
		adc_v=(float)AD_value*3320/4096;
		Temp = -1.809628E-09*adc_v*adc_v*adc_v -3.325395E-06*adc_v*adc_v -1.814103E-01*adc_v + 2.055894E+02;
		T_sum += Temp;
		T_sum_count++;
	 if(T_sum_count >= 20) //2s计算一次
	   {
		 Temp_real = T_sum/T_sum_count;  //计算平均温度
		 T_sum_count = 0;
		 T_sum = 0;
	   }
			
      }
	OLED_ShowNum(2,7,Temp_real,2);   //显示温度数值
	printf("Temp=%.1f  \r\n",Temp_real);

        跌到检测函数,本来想通过加速度和倾斜角度一起来检测,用两个flag,但是发现加速度过于灵敏了,我的鼠标在桌子上震一下,就会触发摔倒检测,后来就用了倾斜角度来做检测,当角度大于80度的时候,便会产生警报,角度也可以设置的小一些,大家可以自行修改。

if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)
			{
//			temp=MPU_Get_Temperature();	//得到温度值
				MPU_Get_Accelerometer(&aacx,&aacy,&aacz);	//得到加速度传感器数据
				SVM = sqrt(pow(aacx,2)+  pow(aacy,2) + pow(aacz,2));	
				//printf("pitch:%0.1f   roll:%0.1f   yaw:%0.1f   SVM:%u\r\n",fabs(pitch),fabs(roll),fabs(yaw),SVM);
				//分析x、y、z角度的异常判断
				if( fabs(pitch)>60 || fabs(roll)>60 )//倾斜大于60°即认为摔倒
				//fabs函数主要用于对浮点数或者整数类型取绝对值
				{	
					mpu_1_flag = 1;	
				}
				else
				{
					mpu_1_flag = 0;
				}
				//分析加速度SVM的异常判断
//				if( SVM>23000 || SVM<12000 )
//					i = 0;   //瞬时速度总值
//					i++;
//				if( i<=10 )
//				{
//					mpu_2_flag = 1;
//				}
//				else
//				{
//					i = 10;
//					mpu_2_flag = 0;
//			}
			
			//综合欧拉角、SVM异常判断异常	
			if( mpu_2_flag || mpu_1_flag ){
			//跌倒函数
				OLED_ShowChinese(4,5,4);
				Buzzer_OFF;
				Delay_1ms(200);
  			//Delay_1ms(100);
				Buzzer_ON;
//				
//				Delay_1ms(200);
				//Delay_1ms(200);
				
				//mpu_1_flag = 0;
				//mpu_1_flag = 0;
			}else {
			//非跌倒函数			
				OLED_ShowChinese(4,5,5);
			}
		}

心率部分比较容易实现了,我们自己的模块就有配套的源码,移植过来就可以直接使用。

Input_data2=(float32_t)(ch2_data^0x800000);
			// 实现FIR滤波
			arm_fir_f32(&S2, &Input_data2, &Output_data2, blockSize);
			
			// 比较大小
			if(min[1]>Output_data2)
				min[1]=Output_data2;
			if(max[1]<Output_data2)
				max[1]=Output_data2;
			
			BPM_LH[0]=BPM_LH[1];
			BPM_LH[1]=BPM_LH[2];
			BPM_LH[2]=Output_data2;
			if((BPM_LH[0]<BPM_LH[1])&(BPM_LH[1]>max[0]-Peak/3)&(BPM_LH[2]<BPM_LH[1]))
			{
				BPM=(float)60000.0/(point_cnt*4);
				point_cnt=0;
			}
			
			// 每隔2000个点重新测量一次最大最小值
			p_num++;;
			if(p_num>2000)
			{
				min[0]=min[1];			
				max[0]=max[1];
				min[1]=0xFFFFFFFF;
				max[1]=0;
				Peak=max[0]-min[0];
				p_num=0;
			}
			// 数据:呼吸波、心电信号、心率
			//printf("B: %8d",(u32)Output_data1);
			//printf("A: %8d",((u32)Output_data2));
		//	printf("C: %6.2f",(BPM));
			OLED_ShowNum(1,7,BPM,3);   //显示心率数值

实物视频 :

跌倒检测视屏

作者:沉醉不知归路1

物联沃分享整理
物联沃-IOTWORD物联网 » STM32与ADS1292R在心率与体温检测中的LMT70应用与跌到检测解析

发表回复