1. 项目介绍
本文介绍的项目是基于STM32设计的健康检测设备,支持体温测量,心率检测,支持运动计步(采用MPU6050陀螺仪实现),支持WIFI传输数据到手机APP打印显示。
硬件环境介绍:
MCU采用STM32F103C8T6
心率传感器采用PulseSensor
体温检测传感器采用红外测温传感器
运动计步功能采用MPU6050陀螺仪实现
OLED显示屏采用0.96寸中景园电子的OLED显示屏-SPI接口
编程软件采用: keil5
心率传感器:
MPU6050传感器:
体温测温模块
OLED显示屏:
硬件效果图:
工程源码截图:
项目源码下载地址: 基于STM32设计的健康检测设备(测温心率计步)源码.zip-嵌入式文档类资源-CSDN下载
视频演示地址:
基于STM32设计的健康检测设备(测温心率计步)
2. 项目源码介绍
2.1 计步功能实现代码
计步功能是通过MPU6050陀螺仪测量计算得到,下面贴出计步算法的核心实现代码.
/*******************************************************************************
文件名: stepAlgorithm.c
描述 : 计步算法
*******************************************************************************/
#include "stepAlgorithm.h"
#include "rtc.h"
#include "math.h"
#include "mpu6050.h"
#define TRUE 1
#define FALSE 0
#define VALUE_NUM 4
sportsInfo_t userSportsInfo;
//存放三轴数据
float oriValues[3] = {0};
//用于存放计算阈值的波峰波谷差值
float tempValue[VALUE_NUM] ={0};
int tempCount = 0;
//是否上升的标志位
u8 isDirectionUp = FALSE;
//持续上升次数
int continueUpCount = 0;
//上一点的持续上升的次数,为了记录波峰的上升次数
int continueUpFormerCount = 0;
//上一点的状态,上升还是下降
u8 lastStatus = FALSE;
//波峰值
float peakOfWave = 0;
//波谷值
float valleyOfWave = 0;
//此次波峰的时间
long timeOfThisPeak = 0;
//上次波峰的时间
long timeOfLastPeak = 0;
//当前的时间
long timeOfNow = 0;
//当前传感器的值
float gravityNew = 0;
//上次传感器的值
float gravityOld = 0;
//动态阈值需要动态的数据,这个值用于这些动态数据的阈值
float initialValue = (float) 1.3;
//初始阈值
float ThreadValue = (float) 2.0;
//三轴轴值
accValue_t accValue;
//行走信息:卡路里、里程、步数
static sportsInfo_t sportsInfo;
//计步缓存
static u8 stepTempCount =0;
/*******************************************************************************
* 函数名:onSensorChanged
* 功能描述: G-Sensor工作后会一直调用这个函数对三轴数据进行平方和开根号的处理
* 调用DetectorNewStep检测步子
*
* 参数说明:
* 输入:
* pAccValue:G-sensor的原始数据
* timeStamp_p:动态时间戳
* 返回值说明:
* 修改记录:
*******************************************************************************/
sportsInfo_t *onSensorChanged(accValue_t *pAccValue,timeStamp_t *timeStamp_p,personInfo_t * personInfo)
{
accValue_t *p = pAccValue;
personInfo_t *userInfo = personInfo;
timeStamp_t *time_p = timeStamp_p;
oriValues[0] = p->accX;
oriValues[1] = p->accY;
oriValues[2] = p->accZ;
//对三轴数据进行平方和开根号的处理
gravityNew = (float) sqrt(oriValues[0] * oriValues[0]+ oriValues[1] * oriValues[1] + oriValues[2] * oriValues[2]);
//检测步子
return DetectorNewStep(gravityNew,time_p,userInfo);
}
/*******************************************************************************
* 函数名:DetectorNewStep
* 功能描述:
* 步伐更新:如果检测到了波峰,并且符合时间差以及阈值的条件,则判定为1步
* 阀值更新:符合时间差条件,波峰波谷差值大于initialValue,则将该差值纳入阈值的计算中
* 参数说明:
输入:
values:经过处理的G-sensor数据
timeStamp_p:时间戳
* 返回值说明:
* 修改记录:sportsInfo_t *onSensorChanged(accValue_t *pAccValue,timeStamp_t *timeStamp_p,personInfo_t * personInfo)
*******************************************************************************/
sportsInfo_t *DetectorNewStep(float values,timeStamp_t *timeStamp_p,personInfo_t * personInfo)
{
static u32 time_old;
personInfo_t *userInfo = personInfo;
static u32 step_per_2_second; //每两秒所走的步数
float step_lenth,walk_speed,walk_distance,Calories;//步长
u32 time_now;
timeStamp_t *time_p = timeStamp_p;
if (gravityOld == 0)
{
gravityOld = values;
}
else
{
if (DetectorPeak(values, gravityOld))//检测到波峰
{
timeOfLastPeak = timeOfThisPeak;//更新上次波峰的时间
//将时间戳转换为以毫秒ms为单位
time_now = timeOfNow = ((time_p->hour*60+time_p->minute)*60+time_p->second)*1000+time_p->twentyMsCount*20; //获取时间 ,并转化为毫秒
//如果检测到了波峰,并且符合时间差以及阈值的条件,则判定为1步
if ( (timeOfNow - timeOfLastPeak >= 250 )//Jahol Fan 修改为300,防止轻微动都也会检测步子
//&& (timeOfNow - timeOfLastPeak <= 2000)
&&(peakOfWave - valleyOfWave >= ThreadValue)
)
{
timeOfThisPeak = timeOfNow; //更新此次波峰时间
stepTempCount++;//Jahol:加1为两步
step_per_2_second ++;
//Jahol:这样计算卡路里,不能滤除人为的误操作,导致的结果是:里程和卡路里偏大
if((time_now - time_old) >= 2000 ) //如果时间过了2秒
{
if( 1 == step_per_2_second )
{
step_lenth = userInfo->height/5;
}
else if( 2 == step_per_2_second )
{
step_lenth = userInfo->height/4;
}
else if( 3 == step_per_2_second )
{
step_lenth = userInfo->height/3;
}
else if( 4 == step_per_2_second )
{
step_lenth = userInfo->height/2;
}
else if(5 == step_per_2_second) //Jahol:为了使计步准确,设置上限值为5步,牺牲卡路里准确性
{
step_lenth = userInfo->height/1.2f;
}
else if( 7 == step_per_2_second )
{
step_lenth = userInfo->height;
}
else if(step_per_2_second >= 8) // step_diff>8
{
step_lenth = userInfo->height*1.2f;
}
else
{
step_lenth = 0;
}
walk_speed = step_per_2_second*step_lenth/2; //速度 ,单位:米/秒
walk_distance = step_per_2_second*step_lenth; //行走距离,单位:米
Calories = 4.5f*walk_speed*(userInfo->weight/2)/1800; //Jahol:weight是以kg为单位
sportsInfo.calories += Calories;
sportsInfo.distance += walk_distance;
time_old = time_now; //更新时间
step_per_2_second = 0;
}
else
{
//do nothing
}
/*
* 处理无效运动:
* 1.连续记录5才开始计步
* 2.例如记录的步用户停住超过3秒,则前面的记录失效,下次从头开始
* 3.连续4记录了步用户还在运动,之前的数据才有效
* */
if ((stepTempCount< 5 )&&(timeOfNow - timeOfLastPeak >= 3000))
{
stepTempCount = 0;
}
else if((stepTempCount>= 5)&&(timeOfNow - timeOfLastPeak <= 3000))
{
sportsInfo.stepCount += stepTempCount;
stepTempCount = 0;
}
else
{
//do nothing
}
}
//Jahol:更新阀值,问题:阀值不会一直变大,不能变小?
if (timeOfNow - timeOfLastPeak >= 250
&& (peakOfWave - valleyOfWave >= initialValue))
{
timeOfThisPeak = timeOfNow;
ThreadValue = Peak_Valley_Thread(peakOfWave - valleyOfWave);//更新阀值
设计资源 培训 开发板 精华推荐
- 具有短路保护功能的 MC78M24CTG 24V 电流提升的典型应用
- LT1172IN8、5V/1.25A 升压转换器的典型应用
- 适用于M24LR16E-R的20 mm x 40 mm天线参考板,仅供参考
- EVAL-AD7864CB,用于 AD7864 的评估板,12 位,520KSPS,用于交流电机的 4 通道 ADC
- esp32-wroom/wrover ch340c
- 功率 LED 驱动器的典型应用 最小、薄型、表面贴装应用、恒流源 0-2.0A、2.5V 至 7V、450W/in3 功率密度和高效率
- RT7258 8A、24V、600kHz 降压转换器的典型应用,具有用于 SOP-8(裸露焊盘)封装的同步栅极驱动器
- 键线分离type-c接口板
- LT4320HN8 理想二极管桥控制器的典型应用电路
- 使用 ON Semiconductor 的 NCV8508 的参考设计
- CGD和Qorvo将共同革新电机控制解决方案
- 是德科技 FieldFox 手持式分析仪配合 VDI 扩频模块,实现毫米波分析功能
- 贸泽开售可精确测量CO2水平的 英飞凌PASCO2V15 XENSIV PAS CO2 5V传感器
- 玩法进阶,浩亭让您的PCB板端连接达到新高度!
- 长城汽车研发新篇章:固态电池技术引领未来
- 纳芯微提供全场景GaN驱动IC解决方案
- 解读华为固态电池新专利,2030 叫板宁德时代?
- 让纯电/插混车抓狂?中企推全球首款-40℃可放电增混电池,不怕冷
- 智驾域控知多少:中低端车型加速上车,行泊一体方案占主体
- Foresight推出六款先进立体传感器套件 彻底改变工业和汽车3D感知