stm32毕设分享 stm32老人跌倒检测预防系统

2023-11-27 06:20

本文主要是介绍stm32毕设分享 stm32老人跌倒检测预防系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 0 前言
  • 1 整体设计
  • 2 硬件电路
  • 3 软件设计
  • 4 跌倒检测算法
  • 5 关键代码
  • 6 最后

0 前言

🔥
这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

🚩 stm32老人跌倒检测预防系统

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:4分
  • 创新点:4分

在这里插入图片描述
在这里插入图片描述

🥇 项目详细描述地址:
https://www.zhihu.com/people/51-81-23-36/zvideos

1 整体设计

学长以STM32F103C8T6为中央处理器,GPS模块用获取当前老人位置,通过DS18B20和心率传感器采集当前人体健康信息,利用ADXL345判断老人是否发生跌倒,最后将数据发送给单片机后,单片机根据定位计算公式得出当前位置的经纬度信息。经过OLED液晶进行显示,数据还可以通过SIM800模块发送短信到设定的手机号上,将检测到的经纬度和心率体温展示在短信上。

1、电路供电部分:整个电路基本工作电压为5V,单片机烧写程序可通过STINK V2下载器进行下载。

2、人机交互。通过SIM800模块,将单片机和手机进行短信通信,手机上可以显示采集到的心率体温、是否跌倒和经纬度信息。

3、信号处理。STM32F103C8T6单片机作为CPU,进行数据的采样以及分析运算。

4、数据采集。使用心率血氧传感器进行心率采集,通过DS18B20采集体温,ADXL345判断老人是否跌倒,GPS进行定位,通过GPS接收模块,采集到相应的检测到的卫星信号后,可以计算出卫星轨道参数等数据,最后接收机中的微处理器就可以按照定位解算算法进行定位解算,得出机器所在位置的经度、纬度、最后通过GSM短信模块把当前的数据发送到用户设计端进行显示提醒。

5、数据展示。在经过运算之后,通过设备上的OLED液晶显示屏可以得到当前测试地的经纬度及老人生理状况。如图

在这里插入图片描述

2 硬件电路

图中单片机为STM32单片机,包括整个最小系统,显示器为OLED液晶显示屏,和单片机之间通过上拉电阻连接整个电路的电源采用5V电源进行供电。将开关和电源设计成一体。采用普通拨动开关进行控制。GPS模块用于检测经纬度和时间信息。SIM800模块用于短信发送,还包含按键,用于设置。包括心率血氧体温传感器和ADXL345跌倒检测其硬件电路原理图如图

在这里插入图片描述

核心主控stm32
在这里插入图片描述

stm32最小系统
在这里插入图片描述

3 软件设计

根据整个系统设计的需求来看,本次软件功能主要是首先STM32开始配置我们需要使用的引脚,然后各个模块初始化,GPS采集和处理,OLED显示和短信发送。为了方便编写和运行效果进行整理,我们在编写程序的时候考虑到美观方面,利于观察我们把每个相关的功能进行封装,在程序需要调用到那个功能的时候我们直接调用就可以了,不需要把程序都写在主函数里。软件的主要部分由主函数、按键子程序、GPS采集程序、SIM800短信模块子程序等构成、心率血氧采集AD转换、跌倒检测ADXL345等。整个主程序流程图如图

在这里插入图片描述

4 跌倒检测算法

基于穿戴式传感器的跌倒检测技术又可以根据佩戴传感器的类型及位置不同 可以分为加速度传感器检测方式和压力传感器检测方式。压力传感器的的检测方
式主要是利用在足底放置压力传感器。利用足底压力传感器与其他传感器的协同 工作,可以区分开人体的跌倒与正常行为。基于加速度传感器的检测方法主要是
实时监控人体运动的加速度参数,当人体运动的加速度参数发生改变时,通过算 法的运算判断是否发生跌倒。而基于加速度传感器的检测技术又可以细分为阀值
检测法和模式识别法

在这里插入图片描述

跌倒判断就是把人体跌倒行为与日常活动区别开来, 进行标记。 而不需要将所有的人体活动分类:而另一方面,
在实际应用中设备资源非常宝贵,实时系统的许多局限性也是复杂度较高的算法都无法实现, 即便实现,也会导致高成本、 高能耗、 高复杂度、
低实时性等一系列与本系统的设计初衷背道而驰的问题。 所以,在“有效”的前提下尽量“简单”是算法设计的指导思想。
同时需要强调的是,针对尤其是像老人这类生理上比较脆弱的的安全监测系统,遵循的基本原则是“可误不可漏”。
即将不是跌倒的情况判断为跌倒,这样可由使用者自行排除;但决不允许出现漏报, 即漏掉用户真正的跌倒, 却没有报警, 一旦出现这样的情况, 后果影响极大。
于此同时, 也并不代表我们要把报警的阈值设置的过低

在这里插入图片描述
学长用 MPU6050 以 5hz 的采样频率来记录数据, 即每 0.2s 采集一次数据。 据研究表明, 成年人身高 h一般在 1.5 m 到 1.9 m
之间,此处选择 h= 1.7 m 用于估算。 研究发现﹐ 人体肚脐是人体头顶至足底的黄金分割点 [10] ﹐ 即肚脐至足底的长度是人体身高的 0.618
倍﹐ 而肚脐恰好处在人体腰部,同时认为人体摔倒时纵向初速度为零,加速度 a 取为阈值 1g, g=9.8 m/s^2,根据重力加速度公式:

在这里插入图片描述
得到在极限状态下, 人体落至地面的时间大约 0.21 s。 也就是说人体平行于地面在腰部位置约 1.05m位置处做自由落体, 需要 0.21s
才能摔倒地面。 经实验, 实际情况中, 跌倒过程所需时间是远大于 0.21s 的,一般在 1.6s 到 2.0s, 所以取 5hz 的采样频率是完全足够的

在这里插入图片描述

详细过程会放在配套的资料中,篇幅有限这里就不在复述了

🧿 项目分享:

https://gitee.com/sinonfin/sharing

5 关键代码


​ int main()
​ {
​ uint8_t dirswitchtemp,spswitchtemp;
​ SmartCar_Init();
​ while(1)
​ {
​ VisualScope_Out();
​ while(DMA_IsMajorLoopComplete(HW_DMA_CH2));

if(StandUp_Flag1&&IS_RUNNING0)
{
dirswitchtemp=DirectionControlSwitch;//保存之前的开关
spswitchtemp =SpeedControlSwitch;
DirectionControlSwitch=0;
SpeedControlSwitch=0;
ZL.P*=1.5f;
ZL.D*=1.5f;
DelayMs(500);
Motor_Enable();
IS_RUNNING=1;//将小车运行标志置位
DelayMs(500);
StandUp_Flag=0;
DelayMs(1000);
ZL.P/=1.5f;
ZL.D/=1.5f;
SpeedControlSwitch=dirswitchtemp;
DirectionControlSwitch=dirswitchtemp;
}
}
}

void PIT0_ISR()
{static uint16_t FindZeroIndex=0;systime_speed++;//速度控制节拍+1systime_direction++;//方向控制节拍+1ADC_GetDataAndFilter();Angle_Calculate();//Yaw_Calculate();if(systime_direction==5){//HMC_angle=Get_Angle();systime_direction=0;Dr_Smooth=0.2;Direction_Calculate(t2-t2_mid);}if(systime_speed==20){systime_speed=0 ;GPIO_ToggleBit(HW_GPIOE,26);//闪烁Sp_Smooth=0.05;//重置平滑系数Get_Speed();Speed_Calculate();}if(FindZeroFlag){FindZeroIndex++;if(FindZeroIndex>=400)//说白了按下键之后两秒才开始记录数据{GYROY_SUM+=T_Y;GYROX_SUM+=T_X;if(FindZeroIndex>=499){FindZeroFlag=0;//次数够了,清标志位FindZeroIndex=0;TY_OFFSET=GYROY_SUM*0.01f;TX_OFFSET=GYROX_SUM*0.01f;GYROX_SUM=0;GYROY_SUM=0;}}}Motor_Output();
}


​ void SmartCar_Init()
​ {
​ DelayInit();
​ /Debug_初始化/
​ /主要是DMP用到了printf**/
​ UART_QuickInit(UART3_RX_PE05_TX_PE04,115200);
​ UART_SelectDebugInstance(HW_UART3);
​ //LED初始化,用作系统运行指示*//
​ GPIO_QuickInit(HW_GPIOE,26,kGPIO_Mode_OPP);
​ GPIO_SetBit(HW_GPIOE,26);
​ /OLED初始化******/
​ OLED_Init();
​ //模拟加速度计陀螺仪初始化***/

GPIO_QuickInit(MMA7361_EN,kGPIO_Mode_OPP);
GPIO_SetBit(MMA7361_EN); //使能MMA7361
ADC_QuickInit(ADC_ACCEL_Z,kADC_SingleDiff10or11);//单端12位输入
//IIC及L3G4200D\HMC5883初始化****//
I2C_QuickInit(I2C0_SCL_PD08_SDA_PD09,I2C_SPEED);
L3G4200D_Init();


​ CT_IIC_Init();
​ while(mpu_dmp_init())
​ {
​ OLED_P8x16Str(0,0,“DMP Error”);
​ OLED_P8x16Num(0,0,mpu_dmp_init());
​ DelayMs(200);
​ }
​ OLED_P8x16Str(0,0,“DMP OK!”);
​ /**DMP数据输出中断/
​ GPIO_QuickInit(HW_GPIOE,4,kGPIO_Mode_IFT); //DMP输出输出中断
​ GPIO_CallbackInstall(HW_GPIOE,GPIOE_ISR);
​ GPIO_ITDMAConfig(HW_GPIOE,4,kGPIO_IT_FallingEdge,true);
​ /PWM初始化
/
​ FTM_PWM_QuickInit(FTM0_CH0_PC01,kPWM_EdgeAligned,10000);
​ FTM_PWM_QuickInit(FTM0_CH1_PC02,kPWM_EdgeAligned,10000);
​ FTM_PWM_QuickInit(FTM0_CH2_PC03,kPWM_EdgeAligned,10000);
​ FTM_PWM_QuickInit(FTM0_CH3_PC04,kPWM_EdgeAligned,10000);

FTM_PWM_ChangeDuty(FTM_PWM_LEFT,0);
FTM_PWM_ChangeDuty(FTM_PWM_LEFT_,0);
FTM_PWM_ChangeDuty(FTM_PWM_RIGHT,0);
FTM_PWM_ChangeDuty(FTM_PWM_RIGHT_,0);
/FTM正交解码初始化/
/*初始化位 脉冲-方向型编码器/
FTM_QD_QuickInit(FTM1_QD_PHA_PB00_PHB_PB01,kFTM_QD_NormalPolarity,kQD_CountDirectionEncoding);
FTM_QD_QuickInit(FTM2_QD_PHA_PB18_PHB_PB19,kFTM_QD_NormalPolarity,kQD_CountDirectionEncoding);

    GPIO_QuickInit(DIR_LEFT,kGPIO_Mode_IFT);//左边编码器方向角设置为悬空输入GPIO_QuickInit(DIR_RIGHT,kGPIO_Mode_IFT);//右边编码器方向角设置为悬空输入//**********************串口初始化********/UART_QuickInit(UART4_RX_PE25_TX_PE24,115200);UART_ITDMAConfig(HW_UART4,kUART_DMA_Tx,true);UART_DMASendConfig(HW_UART4,HW_DMA_CH2);//**********************按键中端配置************/GPIO_QuickInit(KEY_GPIO,KEY_OK,kGPIO_Mode_IPU);GPIO_QuickInit(KEY_GPIO,KEY_UP,kGPIO_Mode_IPU);GPIO_QuickInit(KEY_GPIO,KEY_DOWN,kGPIO_Mode_IPU);GPIO_QuickInit(KEY_GPIO,KEY_LEFT,kGPIO_Mode_IPU);GPIO_QuickInit(KEY_GPIO,KEY_RIGHT,kGPIO_Mode_IPU);GPIO_CallbackInstall(KEY_GPIO,GPIOA_ISR);//按键中断回调函数GPIO_ITDMAConfig(KEY_GPIO,KEY_OK,kGPIO_IT_FallingEdge,true);GPIO_ITDMAConfig(KEY_GPIO,KEY_UP,kGPIO_IT_FallingEdge,true);GPIO_ITDMAConfig(KEY_GPIO,KEY_DOWN,kGPIO_IT_FallingEdge,true);GPIO_ITDMAConfig(KEY_GPIO,KEY_LEFT,kGPIO_IT_RisingEdge,true);GPIO_ITDMAConfig(KEY_GPIO,KEY_RIGHT,kGPIO_IT_FallingEdge,true);//*************解码通道配置****************/  GPIO_QuickInit(HW_GPIOD,12,kGPIO_Mode_IFT);				GPIO_QuickInit(HW_GPIOD,13,kGPIO_Mode_IFT);GPIO_QuickInit(HW_GPIOD,14,kGPIO_Mode_IFT);GPIO_CallbackInstall(HW_GPIOD,GPIOD_ISR);GPIO_ITDMAConfig(HW_GPIOD,12,kGPIO_IT_RisingFallingEdge,true);GPIO_ITDMAConfig(HW_GPIOD,13,kGPIO_IT_RisingFallingEdge,true);GPIO_ITDMAConfig(HW_GPIOD,14,kGPIO_IT_RisingFallingEdge,true);//*****************PIT定时中断初始化*****************/PIT_QuickInit(HW_PIT_CH0,3000);PIT_ITDMAConfig(HW_PIT_CH0,kPIT_IT_TOF,true);PIT_CallbackInstall(HW_PIT_CH0,PIT0_ISR);/*******************NVIC配置****************/NVIC_SetPriorityGrouping(NVIC_PriorityGroup_2);  //中断优先级分成2组NVIC_SetPriority(PORTD_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_2, 0, 0));//遥控器NVIC_SetPriority(PIT0_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_2, 1, 0));//周期性中断优先级NVIC_SetPriority(PORTE_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_2, 2, 0));//DMPNVIC_SetPriority(PORTA_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_2, 3, 0));//按键中断OLED_P8x16Str(0,2,"Hello World!");
}

🥇 项目详细描述地址:
https://www.zhihu.com/people/51-81-23-36/zvideos

这篇关于stm32毕设分享 stm32老人跌倒检测预防系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/427192

相关文章

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

Linux系统之lvcreate命令使用解读

《Linux系统之lvcreate命令使用解读》lvcreate是LVM中创建逻辑卷的核心命令,支持线性、条带化、RAID、镜像、快照、瘦池和缓存池等多种类型,实现灵活存储资源管理,需注意空间分配、R... 目录lvcreate命令详解一、命令概述二、语法格式三、核心功能四、选项详解五、使用示例1. 创建逻

OpenCV在Java中的完整集成指南分享

《OpenCV在Java中的完整集成指南分享》本文详解了在Java中集成OpenCV的方法,涵盖jar包导入、dll配置、JNI路径设置及跨平台兼容性处理,提供了图像处理、特征检测、实时视频分析等应用... 目录1. OpenCV简介与应用领域1.1 OpenCV的诞生与发展1.2 OpenCV的应用领域2

使用Python构建一个高效的日志处理系统

《使用Python构建一个高效的日志处理系统》这篇文章主要为大家详细讲解了如何使用Python开发一个专业的日志分析工具,能够自动化处理、分析和可视化各类日志文件,大幅提升运维效率,需要的可以了解下... 目录环境准备工具功能概述完整代码实现代码深度解析1. 类设计与初始化2. 日志解析核心逻辑3. 文件处

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

Python中你不知道的gzip高级用法分享

《Python中你不知道的gzip高级用法分享》在当今大数据时代,数据存储和传输成本已成为每个开发者必须考虑的问题,Python内置的gzip模块提供了一种简单高效的解决方案,下面小编就来和大家详细讲... 目录前言:为什么数据压缩如此重要1. gzip 模块基础介绍2. 基本压缩与解压缩操作2.1 压缩文

Go语言代码格式化的技巧分享

《Go语言代码格式化的技巧分享》在Go语言的开发过程中,代码格式化是一个看似细微却至关重要的环节,良好的代码格式化不仅能提升代码的可读性,还能促进团队协作,减少因代码风格差异引发的问题,Go在代码格式... 目录一、Go 语言代码格式化的重要性二、Go 语言代码格式化工具:gofmt 与 go fmt(一)

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee