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

相关文章

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

Linux系统之主机网络配置方式

《Linux系统之主机网络配置方式》:本文主要介绍Linux系统之主机网络配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、查看主机的网络参数1、查看主机名2、查看IP地址3、查看网关4、查看DNS二、配置网卡1、修改网卡配置文件2、nmcli工具【通用

Linux系统之dns域名解析全过程

《Linux系统之dns域名解析全过程》:本文主要介绍Linux系统之dns域名解析全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、dns域名解析介绍1、DNS核心概念1.1 区域 zone1.2 记录 record二、DNS服务的配置1、正向解析的配置

Linux系统中配置静态IP地址的详细步骤

《Linux系统中配置静态IP地址的详细步骤》本文详细介绍了在Linux系统中配置静态IP地址的五个步骤,包括打开终端、编辑网络配置文件、配置IP地址、保存并重启网络服务,这对于系统管理员和新手都极具... 目录步骤一:打开终端步骤二:编辑网络配置文件步骤三:配置静态IP地址步骤四:保存并关闭文件步骤五:重

Python解析器安装指南分享(Mac/Windows/Linux)

《Python解析器安装指南分享(Mac/Windows/Linux)》:本文主要介绍Python解析器安装指南(Mac/Windows/Linux),具有很好的参考价值,希望对大家有所帮助,如有... 目NMNkN录1js. 安装包下载1.1 python 下载官网2.核心安装方式3. MACOS 系统安

Windows系统下如何查找JDK的安装路径

《Windows系统下如何查找JDK的安装路径》:本文主要介绍Windows系统下如何查找JDK的安装路径,文中介绍了三种方法,分别是通过命令行检查、使用verbose选项查找jre目录、以及查看... 目录一、确认是否安装了JDK二、查找路径三、另外一种方式如果很久之前安装了JDK,或者在别人的电脑上,想

Linux系统之authconfig命令的使用解读

《Linux系统之authconfig命令的使用解读》authconfig是一个用于配置Linux系统身份验证和账户管理设置的命令行工具,主要用于RedHat系列的Linux发行版,它提供了一系列选项... 目录linux authconfig命令的使用基本语法常用选项示例总结Linux authconfi

Java嵌套for循环优化方案分享

《Java嵌套for循环优化方案分享》介绍了Java中嵌套for循环的优化方法,包括减少循环次数、合并循环、使用更高效的数据结构、并行处理、预处理和缓存、算法优化、尽量减少对象创建以及本地变量优化,通... 目录Java 嵌套 for 循环优化方案1. 减少循环次数2. 合并循环3. 使用更高效的数据结构4

Nginx配置系统服务&设置环境变量方式

《Nginx配置系统服务&设置环境变量方式》本文介绍了如何将Nginx配置为系统服务并设置环境变量,以便更方便地对Nginx进行操作,通过配置系统服务,可以使用系统命令来启动、停止或重新加载Nginx... 目录1.Nginx操作问题2.配置系统服android务3.设置环境变量总结1.Nginx操作问题