基于MPU6050的跌倒检测项目设计

一、背景

随着人口老龄化的不断加剧,老年人的健康和安全问题备受关注。本设计旨在利用STM32单片机与MPU6050传感器相结合,实现基于角度变化的跌倒检测系统。这一系统不仅能够快速、准确地检测老年人是否发生跌倒,还通过整合通信模块实现了实时的跌倒提醒功能。设计目标包括通过C编写MPU6050传感器的驱动代码和数据滤波算法,确保系统对身体姿态的敏感性和准确性。同时,通过整合通信模块,老年人在发生跌倒时能够及时地向特定用户发送提醒信息,包括短信和坐标,以便他们能够及时作出相应的帮助。为确保系统的可用性和便携性,本设计采用小型电池供电,使老年人可以随时随地使用。

注:本设计由于前期调研不够充分,没有GPS模块,也没有无线传输功能。

二、项目材料清单

面包板已经各种公母线

stm32f103c8t6

蜂鸣器

0.96寸OLED显示模块

CH340串口

ESP8266-01s

三、主控器与传感器的连接

33199154e4ea45edabf3ad41e6a6ece1.jpeg

电路连接图

这里因为我已经将原来的电路给拆了,所以只能照着这张图去给大家说下,GND和VCC就省去了。

蜂鸣器:I/O 与PB12相接

OLED:SCL与PB8,SDAPB9

MPU6050:SCL与PB10,SDA与PB11

串口:TXD与PA10,RXD与PA9

ESP8266-01s我没有驱动成功,所以放在这里只是一个摆设。需要注意的是MPU6050最好像我这样连接,因为我们需要通过它获取俯仰角和翻滚角,要保证模块的平稳。

fc26b4d14bce4a76a7e93657a8aa1aa9.png

通过串口发送数据

四、跌倒检测算法的设计

使用MPU6050传感器获取加速度计和陀螺仪的原始数据,通过STM32的I2C接口与MPU6050进行通信,读取加速度和角速度数据。该算法可以根据以下步骤来实现

步骤:

1. 计算加速度计推导的俯仰角和横滚角:

   a. 使用 atan2(AY, sqrt(AX * AX + AZ * AZ)) 计算 accPitch,将结果转换为角度。

   b. 使用 atan2(-AX, AZ) 计算 accRoll,将结果转换为角度。

2. 对陀螺仪数据进行角速度积分:

   a. 通过积分陀螺仪数据 GY,按照灵敏度系数(131.0)进行缩放,计算 gyroPitch。

   b. 通过积分陀螺仪数据 GX,使用相同的灵敏度系数,计算 gyroRoll。

3. 应用互补滤波:

   a. 将互补滤波系数 alpha 定义为 0.98。

   b. 利用互补滤波,结合加速度计推导的角度(accPitch、accRoll)和陀螺仪积分得到的角度(gyroPitch、gyroRoll):

4. 输出:

   更新后的俯仰角和横滚角代表设备平稳和稳定的方向。

下面是我写的伪代码,帮助大家理解这里:

Algorithm UpdateAttitude(int16_t AX, int16_t AY, int16_t AZ, int16_t GX, int16_t GY, int16_t GZ):

Input: Acceleration and gyroscope data (AX, AY, AZ, GX, GY, GZ)

Output: None (updates global variables pitch and roll)

1:accPitch = atan2(AY, sqrt(AX * AX + AZ * AZ)) * (180.0 / M_PI)

2:accRoll = atan2(-AX, AZ) * (180.0 / M_PI)

 

    3:gyroPitch = pitch + (float)GY / 131.0  

    4:gyroRoll = roll + (float)GX / 131.0

 

    5:alpha = 0.98  

    6:pitch = alpha * gyroPitch + (1.0 - alpha) * accPitch

    7:roll = alpha * gyroRoll + (1.0 - alpha) * accRoll

五、主逻辑代码

软件使用的Keil5,这些库函数都可以从江科大的视频获得,所以这里仅仅展示主逻辑代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MPU6050.h"
#include "Buzzer.h"
#include "Serial.h"
#include <math.h>
#include <stdbool.h>

bool pose1 = true;
bool pose2 = true;
#define M_PI (3.14159265358979323846264338327950288)
uint8_t ID;								//定义用于存放ID号的变量
int16_t AX, AY, AZ, GX, GY, GZ;			//定义用于存放各个数据的变量


// 定义全局变量用于存储姿态角度
float pitch = 0.0; // 俯仰角
float roll = 0.0;  // 横滚角

// 定义函数进行姿态检测
void UpdateAttitude(int16_t AX, int16_t AY, int16_t AZ, int16_t GX, int16_t GY, int16_t GZ) {
    // 加速度计的角度计算
    float accPitch = atan2(AY, sqrt(AX * AX + AZ * AZ)) * (180.0 / M_PI);
    float accRoll = atan2(-AX, AZ) * (180.0 / M_PI);

    // 陀螺仪积分得到角速度
    float gyroPitch = pitch + (float)GY / 131.0; // 131 根据陀螺仪灵敏度调整
    float gyroRoll = roll + (float)GX / 131.0;

    // 综合加速度计和陀螺仪数据,使用互补滤波
    float alpha = 0.98; // 互补滤波系数,根据需要调整
    pitch = alpha * gyroPitch + (1.0 - alpha) * accPitch;
    roll = alpha * gyroRoll + (1.0 - alpha) * accRoll;
}

int main(void)
{
	/*模块初始化*/
	OLED_Init();		//OLED初始化
	MPU6050_Init();		//MPU6050初始化
	Serial_Init();
	Buzzer_Init();
	
	/*显示ID号*/
	OLED_ShowString(1, 1, "ID:");		//显示静态字符串
	ID = MPU6050_GetID();				//获取MPU6050的ID号
	OLED_ShowHexNum(1, 4, ID, 2);		//OLED显示ID号
	
	//Serial_SendByte(0x41);
	while (1)
	{
		MPU6050_GetData(&AX, &AY, &AZ, &GX, &GY, &GZ);		//获取MPU6050的数据
		
		// 更新姿态角度
        UpdateAttitude(AX, AY, AZ, GX, GY, GZ);
        
        // 在OLED上显示姿态角度
        OLED_ShowString(2, 1, "Pitch: ");
        OLED_ShowSignedNum(2, 8, (int16_t)pitch, 5);
        
        OLED_ShowString(3, 1, "Roll: ");
        OLED_ShowSignedNum(3, 7, (int16_t)roll, 5);
		
		// 打印姿态
        if (pitch > 30) {
            OLED_ShowString(4, 1, "Back   ");
			pose1 = false;
        } else if (pitch < -30) {
            OLED_ShowString(4, 1, "Front  ");
			pose1 = false;
        } else {
            OLED_ShowString(4, 1, "Normal ");
			pose1 = true;
        }
        
        if (roll < -70) {
            OLED_ShowString(4, 10, "Right ");
			pose2 = false;
        } else if (roll > 0) {
            OLED_ShowString(4, 10, "Left  ");
			pose2 = false;
        } else {
            OLED_ShowString(4, 10, "Normal");
			pose2 = true;
        }
		
        if (!pose1 || !pose2) {
            // 触发蜂鸣器响
            Buzzer_ON();
        } else {
            // 关闭蜂鸣器
            Buzzer_OFF();
        }
		
        // 通过串口发送姿态角度
        Serial_SendString("Pitch: ");
        Serial_SendNumber((int16_t)pitch, 5);
        Serial_SendString(", Roll: ");
        Serial_SendNumber((int16_t)roll, 5);
        Serial_SendString("\r\n");
	}
}

简单来说下这个代码大致完成了什么功能,将面板板平放之后,我发现Pitch大约在-00006左右,roll大约在-00039左右,经过多次测试当俯仰角>30时判定为后倾,当俯仰角<-30时判定为前倾,当翻滚角>0时判定为左斜,当翻滚角<-70时判定为右斜。当满足上面任意请求时,蜂鸣器发出警报向周围人求助。

ef1a965a778245efa1a4c837b7300621.png

这里的阈值是可以修改的,在测试的时候也用OLED来显示了的,到一定的范围就打印出它的姿态,正常的就是normal,其他的就是使用的方向的英文来表示,大家想提供可以使用中文,因为我这个就是个课设作业,我也是才接触的stm32,花了一周的时间学习的江科大(有很多其实都没有用到),想拿高分最好就是把无线通信还有GPS的功能加上。

六、总结

本设计致力于解决老年人跌倒检测问题,采用了STM32F103C8T6主控制器,搭配蜂鸣器模块、MPU6050三轴加速度传感器、0.96寸OLED显示模块以及ESP8266-01s模块等组件,以实现全面的跌倒监测与通信功能。技术指标方面,STM32F103C8T6主控制器具备高性能、低功耗、丰富的I/O端口和通信端口等特点。MPU6050传感器具备消除敏感度、陀螺仪积分等先进特性,而0.96寸OLED屏为系统提供实时数据显示和系统调试支持。

尚待完善的地方:

(1)优化互补滤波算法的参数,以提高姿态角度计算的准确性和稳定性。

(2)进一步完善系统的无线通信功能,特别是考虑引入GPS功能,以确保在实际应用中能够可靠地向监护人发送准确的警报信息。同时还存在ESP8266-01s模块与STM32F103C8T6进行驱动时的连接及通信问题,目前尚需解决。

 

  • 36
    点赞
  • 139
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 20
    评论
### 回答1: 由于MPU6050是一个加速度计和陀螺仪结合的传感器,因此可以通过读取其采集的数据来进行跌倒检测。 以下是一个简单的例子,使用C语言实现基于MPU6050跌倒检测: ```c #include <Wire.h> #include <I2Cdev.h> #include <MPU6050.h> MPU6050 accelgyro; int16_t ax, ay, az; void setup() { Wire.begin(); accelgyro.initialize(); } void loop() { accelgyro.getMotion6(&ax, &ay, &az, 0, 0, 0); if (abs(ax) > 2000 || abs(ay) > 2000) { // 如果x或y轴的加速度超过2000,则视为跌倒事件 // 此处可以添加跌倒事件处理代码 Serial.println("Fall detected!"); } delay(100); } ``` 此代码使用了MPU6050库,需要在Arduino IDE中安装。 注意,参数2000是一个示例值,可以根据实际情况调整。 ### 回答2: 基于MPU6050跌倒检测代码可以用C语言编写。首先,我们需要包含相应的库文件和定义一些全局变量。 #include <stdio.h> #include <stdlib.h> #include <math.h> #include "mpu6050.h" //MPU6050库文件 #define THRESHOLD 30 //跌倒判断阈值 #define SAMPLES 10 //采样次数 int main() { int i; float x_acc[SAMPLES], y_acc[SAMPLES], z_acc[SAMPLES]; //三个轴的加速度数据 //初始化MPU6050 mpu6050_init(); //读取MPU6050的加速度数据 for (i = 0; i < SAMPLES; i++) { mpu6050_read_acc(&x_acc[i], &y_acc[i], &z_acc[i]); delay_ms(10); //延时10ms } //计算加速度均值 float x_mean = 0, y_mean = 0, z_mean = 0; for (i = 0; i < SAMPLES; i++) { x_mean += x_acc[i]; y_mean += y_acc[i]; z_mean += z_acc[i]; } x_mean /= SAMPLES; y_mean /= SAMPLES; z_mean /= SAMPLES; //计算加速度方差 float x_variance = 0, y_variance = 0, z_variance = 0; for (i = 0; i < SAMPLES; i++) { x_variance += pow(x_acc[i] - x_mean, 2); y_variance += pow(y_acc[i] - y_mean, 2); z_variance += pow(z_acc[i] - z_mean, 2); } x_variance /= SAMPLES; y_variance /= SAMPLES; z_variance /= SAMPLES; //计算合加速度 float total_acc = sqrt(pow(x_variance, 2) + pow(y_variance, 2) + pow(z_variance, 2)); //判断是否跌倒 if (total_acc > THRESHOLD) { printf("跌倒检测:跌倒了!\n"); } else { printf("跌倒检测:正常。\n"); } return 0; } 以上代码基于MPU6050的C语言编写了跌倒检测功能。首先初始化MPU6050,并进行一定次数的加速度数据读取。然后计算加速度数据的均值和方差,最后通过合加速度的计算判断是否跌倒。如果合加速度大于设定的阈值,则判定为跌倒,否则为正常。 ### 回答3: 基于MPU6050跌倒检测代码主要涉及以下几个方面: 1. 引入必要的库文件:首先需要引入相应的库文件,包括I2C通信库和MPU6050相关的库文件,以便能够成功读取和处理MPU6050的数据。 2. 初始化MPU6050:在代码的开始部分,需要对MPU6050进行初始化,设置合适的采样率、加速度计和陀螺仪的量程、低通滤波器等参数。 3. 循环读取数据:通过循环不断地读取MPU6050的加速度和角速度数据,可以使用MPU6050提供的API函数来获取这些数据。 4. 计算姿态角:根据读取到的加速度和角速度数据,可以通过数学计算来获得MPU6050的姿态角,例如俯仰角、横滚角等。 5. 判断是否跌倒:通过判断某些特定的姿态角和加速度的数值变化,可以判断用户是否发生了跌倒。可以设置一些阈值来进行判断,并结合时间窗口等策略来提高检测的准确性。 6. 发出跌倒警报:当检测到跌倒事件发生时,通过合适的方式发出跌倒警报,例如触发蜂鸣器、发送警报信息等。 代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <wiringPiI2C.h> #define MPU6050_ADDR 0x68 // MPU6050设备地址 int main() { int fd; fd = wiringPiI2CSetup(MPU6050_ADDR); // 初始化MPU6050 if (fd == -1) { printf("Failed to initialize MPU6050\n"); exit(1); } while (1) { // 读取加速度和角速度数据 int accel_x = wiringPiI2CReadReg16(fd, 0x3B); int accel_y = wiringPiI2CReadReg16(fd, 0x3D); int accel_z = wiringPiI2CReadReg16(fd, 0x3F); int gyro_x = wiringPiI2CReadReg16(fd, 0x43); int gyro_y = wiringPiI2CReadReg16(fd, 0x45); int gyro_z = wiringPiI2CReadReg16(fd, 0x47); // 计算姿态角 // 判断是否跌倒 // 发出跌倒警报 delay(50); // 延时一段时间后再次读取数据 } return 0; } ``` 以上是一个简单的基于MPU6050跌倒检测代码示例,具体的姿态角计算和跌倒判断部分需要根据需求和实际情况进行进一步的开发和优化。
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏天是冰红茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值