毕业设计 基于STM32单片机的老人防摔倒报警系统 - 物联网 嵌入式

news2024/11/18 7:25:55

文章目录

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


0 前言

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

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

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

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

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

🧿 选题指导, 项目分享:

https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md

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


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 的采样频率是完全足够的

在这里插入图片描述

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

5 关键代码

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

			if(StandUp_Flag==1&&IS_RUNNING==0)
			{
				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++;//速度控制节拍+1
		systime_direction++;//方向控制节拍+1
		ADC_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));//DMP
    NVIC_SetPriority(PORTA_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_2, 3, 0));//按键中断
		OLED_P8x16Str(0,2,"Hello World!");
}

6 最后

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/70277.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Partition of an interval

In mathematics, a partition of an interval [a, b] on the real line is a finite sequence x0, x1, x2, …, xn of real numbers such that a x0 < x1 < x2 < … < xn b. In other terms, a partition of a compact interval I is a strictly increasing seq…

《小白WEB安全入门》01. 扫盲篇

扫盲篇基础知识什么是WEB什么是前端什么是后端什么是数据库什么是协议什么是WEB安全什么是服务器什么是IP地址、端口什么是局域网、广域网、内网、外网什么是URL什么是MAC地址什么是&#xff08;端口&#xff09;映射什么是域名、DNS什么是网卡、网关什么是IPv4/IPv6什么是Linu…

51单片机的温控风扇设计

一.硬件方案 系统采用51单片机作为控制平台对风扇转速进行控制。可由用户设置高、低温度值&#xff0c;测得温度值在高低温度之间时打开风扇弱风档&#xff0c;当温度升高超过所设定的温度时自动切换到大风档&#xff0c;当温度小于所设定的温度时自动关闭风扇。风扇控制状态随…

论坛系统设计与实现

摘 要 网络技术的快速发展给各行各业带来了很大的突破&#xff0c;也给各行各业提供了一种新的管理模块&#xff0c;对于论坛交流将是又一个传统管理到智能化信息管理的改革&#xff0c;设计论坛系统设计与实现的目的就是借助计算机让复杂的论坛交流操作变简单&#xff0c;变…

第8部分 帧中继

帧中继线路是中小企业常用的广域网线路&#xff0c;其通信费用较低。由于帧中继技术的一些特殊性使得帧中继的配置较为复杂&#xff0c;特别是在帧中继上运行路由协议时更是如此。作为入门&#xff0c;对帧中继的理解应着重放在DLCI、PVC、帧中继映射和子接口等概念上。本章通过…

Redis--高级篇 D5 多级缓存(JVM进程缓存、Lua语法、OpenResty安装(通过lua扩展nginx))

1、JVM进程缓存 1.1 导入商品查询案例 案例导入说明 为了演示多级缓存&#xff0c;我们先导入一个商品管理的案例&#xff0c;其中包含商品的CRUD功能。我们将来会给查询商品添加多级缓存。 1.安装MySQL 后期做数据同步需要用到MySQL的主从功能&#xff0c;所以需要大家在虚…

【Pytorch】.item() 方法介绍

文章目录一、.item() 方法介绍1. 方法介绍2. 那么有什么用呢&#xff1f;二、实例参考链接一、.item() 方法介绍 1. 方法介绍 我们先看官网中是怎么介绍的&#xff1a; 返回这个张量的值作为一个标准的Python数字。 详情页中说&#xff1a; # TORCH.TENSOR.ITEM Tensor.ite…

配对交易之统计套利配对:模型的应用

接下来&#xff0c;介绍把协整模型应用到取对数之后的股价上面。 前提假设&#xff1a;股价取对数之后是一个随机游走过程&#xff0c;即非平稳的。 现在有股票A和B,股价取对数之后的两个时间序列是以及。使用误差修正的表达方式&#xff1a; 能够唯一确定以上式子的参数是协…

uView教程-抽屉菜单 #低代码 #小程序 #uView

这种抽屉效果是如何制作的呢&#xff1f; 在guiplan低代码开发工具中&#xff0c; 点击"uView框架", 输入关键字"弹出层"进行搜索&#xff0c; 找到"带用户菜单" 点击"一键插入", 这我们一个抽屉菜单就插入进来了&#xff0c; 底部…

MapReduce编程实例-词频统计实现

文章目录词频统计实现思路词频统计实现步骤1. 准备数据文件1.1 在虚拟机上创建文本文件1.2 上传文件到HDFS指定目录2. 创建Maven项目3. 添加相关依赖4. 创建日志属性文件5. 创建词频统计映射类6. 创建词频统计驱动器类7. 运行词频统计驱动器类&#xff0c;查看结果8. 修改词频统…

设计一个简单HTML爵士音乐网页(HTML+CSS)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

SpringCloud Feing 源码 (简单实用) (一)

文章目录1.远程调用2.代码解析2.1 Eureka微服务2.1 微服务结构以及配置类2.2 公共类2.3 provider微服务2.4 Feign-Order微服务3.结果展示1.远程调用 本地过程调用&#xff08;Local Procedure Call&#xff0c;LPC&#xff09;&#xff0c;是指同一台机器上运行的不同进程之间…

从MES到MOM,抓住中国工业软件的机遇

从全球市场看&#xff0c;MES也是正进入MOM阶段&#xff0c;如图四所示。目前很多还是智能化第二代MES&#xff0c;主要是加强数据记录与处理和设备自动化管理&#xff0c;通过更精确的过程状态跟踪和更完整的数据记录&#xff0c;获取更多的数据来优化生产管理&#xff0c;并通…

被微服务轰炸?莫怕!耗时35天整出的「微服务学习教程」送你

又被微服务轰炸&#xff1f;莫慌莫怕&#xff01;小编连续25天&#xff0c;整出这份最新最全「学习教程」送你&#xff01; 微服务架构学习教程&#xff1a;RPCDubboSpirngBootSpringCloud AlibabaDockerK8s 手绘了整个微服务架构的知识体系脑图&#xff0c;还有针对分部的Dub…

LabelImg标注的YOLO格式txt标签中心坐标和物体边界框长宽的转换

目录 1.LabelImg标注的YOLO格式的TXT标签 OpencvYOLO-V3实现目标跟踪 YOLO-V3实时检测实现&#xff08;opencvpython实现&#xff09;——改进——&#xff1e;更加的易懂 YOLO-V3实时检测实现&#xff08;opencvpython实现&#xff09; 1.LabelImg标注的YOLO格式的TXT标签 …

【Mysql】记录一些特殊的select语句

目录一.分页查询二.多表查询三.自连接四.子查询4.1单行子查询4.2多行子查询4.3临时表子查询4.4多行子查询4.5多列子查询一.分页查询 select...limit start,rows 表示从start1行开始取&#xff0c;取出rows行&#xff0c;start从0开始算 公式&#xff1a;limit 每页显示记录数*…

R语言NLP案例:LDA主题文本挖掘优惠券推荐网站数据

介绍 Groupon是一个优惠券推荐服务&#xff0c;您可以免费注册Groupon&#xff0c;并且Groupon每天都会向您发送包含该地区当天交易的电子邮件。如果您喜欢这笔交易&#xff0c;那么您可以立即从Groupon购买&#xff0c;并在餐馆/商店兑换。 相关视频&#xff1a;文本挖掘&…

微导纳米将于12月14日申购:前三季度收入约4亿元,同比增长67%

12月5日&#xff0c;江苏微导纳米科技股份有限公司&#xff08;下称“微导纳米”&#xff0c;SH:688147&#xff09;披露招股意向书&#xff0c;启动发行招股&#xff0c;初步询价时间定于2022年12月9日&#xff0c;将于2022年12月14日申购。 据了解&#xff0c;微导纳米拟在上…

电巢·新能源领域高速发展,驱动电解电容“老树又发新枝芽”

据统计&#xff0c;新能源汽车销量2012年为1.3万台&#xff0c;2021年上升到352.1万台&#xff0c;截止2022年9月达到456.7万台。车载充电机(OBC)的主要功能是将交流电压输入&#xff0c;以适合电池组的电流和电压水平&#xff0c;转换为直流电压输出。 新能源汽车应用中&#…

Apache Spark与 Apache Hadoop数据科学工具有哪些区别?

ApacheSpark与 Apache Hadoop数据科学工具有哪些区别&#xff1f;Apache Spark被设计为大规模处理的接口&#xff0c;而 Apache Hadoop 为大数据的分布式存储和处理提供了更广泛的软件框架。两者既可以一起使用也可以作为独立服务使用。Apache Spark 和 Apache Hadoop 都是 Apa…