【物联网】MPU6050传感器数据采集与滤波算法

这篇具有很好参考价值的文章主要介绍了【物联网】MPU6050传感器数据采集与滤波算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

当谈到嵌入式电子设备和机器人的姿态控制和运动检测时,MPU6050往往是一个备受关注的传感器模块。它是一款小巧但功能强大的六轴传感器,集成了三轴加速度计和三轴陀螺仪。在本博客中,我们将详细介绍MPU6050的特点、工作原理以及与stm32配合的使用方法,后面看情况更新卡尔曼滤波。

mpu6050 卡尔曼滤波,物联网,算法

目录

1. MPU6050的特点和功能

1.1 六轴传感器

1.2 数字运动处理器

1.3 I2C通信接口

1.4 高精度和低功耗

2. MPU6050的工作原理

2.1 加速度计原理

2.2 陀螺仪原理

2.3 姿态解算

3.模块电路图

4. 如何使用MPU6050

4.1 硬件连接

4.2 初始化设置

4.3 读取传感器

4.4 数据处理和滤波

5. 卡尔曼滤波


1. MPU6050的特点和功能

1.1 六轴传感器

MPU6050集成了三轴加速度传感器和三轴陀螺仪,六轴传感器的主要优势在于结合了加速度计和陀螺仪的测量结果,可以提供更全面和准确的物体运动和姿态信息。通过综合加速度计和陀螺仪的数据,六轴传感器可以估计物体的姿态(如欧拉角或四元数),以及物体在三个空间方向上的加速度和角速度。

1.2 数字运动处理器

MPU6050内置的数字运动处理器可以进行复杂的运动处理和数据处理,包括传感器数据的滤波、噪声消除、运动融合算法等。它通过处理器内部的算法,提供了方便快捷的姿态解算。

1.3 I2C通信接口

MPU6050传感器通信协议可以选择使用I2C或SPI。 I2C是最常用的通信协议,适用于大多数情况下。SPI是一种高速串行通信协议,更加适用于性能要求较高的应用场景。

支持的I2C通信模式中,包括两个信号线SCL(串行时钟线)和SDA(串行数据线)。通过I2C通信,可以与MPU6050进行数据的读取和写入,另一篇博客有讲到。I2C(IIC)通信协议详解与应用

如果选择使用SPI通信协议,可以参考MPU6050的数据手册以及您所使用的STM32的文档,配置和连接SPI总线,设置通信参数,并使用SPI协议与MPU6050进行数据交换,我是很少使用SPI通信的,详细的通信协议另一篇博客也有讲到,想了解的也可以去看一下。了解SPI通信:串行外设接口的基本工作原理,51、stm32实现SPI

1.4 高精度和低功耗

为了实现MPU6050的高精度,我们可以进行传感器校准、数据滤波、温度补偿、数据处理和算法优化,以及系统调优等步骤。通过这些措施,可以提高MPU6050的测量精度和稳定性,确保获得准确可靠的运动测量和姿态估计结果,同时通过智能功耗控制来延长电池寿命。

2. MPU6050的工作原理

2.1 加速度计原理

加速度计测量物体的加速度,其工作基于微小的质量和弹性部件组成的微型机械结构。加速度使得这些部件发生变形,并通过电容或压阻传感器转换成电信号。MPU6050的加速度计可以测量在三个轴上的线性加速度。

mpu6050 卡尔曼滤波,物联网,算法

2.2 陀螺仪原理

陀螺仪测量物体的角速度,其工作基于角动量守恒定律。陀螺仪由旋转部件和感测部件组成,当物体发生旋转时,感测部件会受到力矩的作用而产生电信号。MPU6050的陀螺仪可以测量在三个轴上的旋转速率。

mpu6050 卡尔曼滤波,物联网,算法

2.3 姿态解算

姿态解算是将加速度计和陀螺仪的数据进行融合,从而获得物体的姿态信息(例如欧拉角)。通过运动融合算法,可以综合利用两类传感器的优势,同时弥补它们的局限性。常用的算法包括卡尔曼滤波、互补滤波和四元数等,卡尔曼滤波后面会涉及。

mpu6050 卡尔曼滤波,物联网,算法

3.模块电路图

mpu6050 卡尔曼滤波,物联网,算法

4. 如何使用MPU6050

4.1 硬件连接

GY-521模块上各个引脚的作用

VCC 供电引脚,接3V-5V电源,一般使用5V
GND 接地引脚,连接到电源的地
SCL I2C时钟线引脚,用于与主控器件进行时钟同步
SDA I2C数据线引脚,用于与主控器件进行数据通信
XDA 可用于将其他I2C模块与MPU6050连接
XCL 可用于将其他I2C模块与MPU6050连接
AD0 I2C地址选择引脚,可通过将其连接到VCC或GND,来选择MPU-6050的I2C地址
INT 中断引脚,可用于连接到微控制器的中断引脚,用于传输中断信号

mpu6050 卡尔曼滤波,物联网,算法

4.2 初始化设置

在开始使用MPU6050之前,需要进行初始化设置。通过I2C通信接口,将适当的值写入MPU6050的配置寄存器中,以配置采样率、传感器范围和滤波器等参数。您可以参考MPU6050的数据手册或使用相关的开发库来进行设置。

这里初始化的I2C通信引脚是PB7和PB6,时钟使用的是I2C1。

#include "stm32fxxx.h"
#include "stm32fxxx_i2c.h"

#define MPU6050_ADDRESS 0xD0  // MPU-6050 I2C地址
#define I2Cx             I2C1  // 使用的I2C外设

void MPU6050_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    I2C_InitTypeDef I2C_InitStruct;

    // 使能I2C时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2Cx, ENABLE);
    
    // I2C引脚配置
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStruct);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2Cx);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2Cx);

    // I2C配置
    I2C_StructInit(&I2C_InitStruct);
    I2C_InitStruct.I2C_Timing = 0x40912732;
    I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStruct.I2C_OwnAddress1 = 0;
    I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_Init(I2Cx, &I2C_InitStruct);
    I2C_Cmd(I2Cx, ENABLE);

    // 初始化MPU-6050
    I2C_GenerateSTART(I2Cx, ENABLE);
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

    I2C_Send7bitAddress(I2Cx, MPU6050_ADDRESS, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    I2C_SendData(I2Cx, 0x19);  // 设置采样率和低通滤波器
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_SendData(I2Cx, 0x07);  // 配置值
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    I2C_SendData(I2Cx, 0x1A);  // 设置低通滤波器频率
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_SendData(I2Cx, 0x03);  // 配置值
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    I2C_SendData(I2Cx, 0x1B);  // 设置陀螺仪量程
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_SendData(I2Cx, 0x18);  // 配置值(+/-2000°/s)
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    I2C_SendData(I2Cx, 0x1C);  // 设置加速度计量程
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_SendData(I2Cx, 0x18);  // 配置值(+/-16g)
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    I2C_GenerateSTOP(I2Cx, ENABLE);
}
/*
1. RCC_APB1PeriphClockCmd:使能I2C外设的时钟。
2. GPIO_InitTypeDef:配置I2C引脚的结构体。
3. GPIO_Init:初始化GPIO引脚。
4. GPIO_PinAFConfig:配置引脚的复用功能。
5. I2C_StructInit:将I2C_InitStruct结构体成员初始化为默认值。
6. I2C_Init:初始化I2C外设。
7. I2C_Cmd:使能I2C外设。
8. I2C_GenerateSTART:产生I2C起始信号。
9. I2C_CheckEvent:检查指定的I2C事件是否发生。
10. I2C_Send7bitAddress:发送7位设备地址给I2C外设。
11. I2C_SendData:发送数据给I2C外设。
12. I2C_GenerateSTOP:产生I2C停止信号。

在`MPU6050_Init`函数中,首先通过`RCC_APB1PeriphClockCmd`函数使能I2C外设的时钟。
然后,通过`GPIO_InitStruct`结构体和`GPIO_Init`函数配置I2C引脚,同时使用`GPIO_PinAFConfig`函数配置引脚的复用功能。
接下来,通过`I2C_InitStruct`结构体设置I2C相关参数,包括I2C时钟频率、模式、占空比等,并使用`I2C_Init`函数进行初始化。
通过`I2C_Cmd`函数使能I2C外设。
接下来,调用`I2C_GenerateSTART`函数产生I2C起始信号,并通过循环等待确认I2C通信是否就绪,然后发送设备地址。
然后,通过`I2C_SendData`函数依次发送要写入的寄存器地址和配置值,实现对MPU-6050的初始化设置。具体的寄存器地址和配置值请根据MPU-6050的数据手册进行配置。
最后,通过`I2C_GenerateSTOP`函数产生I2C停止信号,结束I2C通信。
*/

4.3 读取传感器

一旦完成初始化设置,就可以开始读取传感器数据了。通过I2C接口从MPU6050读取加速度计和陀螺仪的原始数据。这些数据以原始值的形式提供,通常是数字表示,并需要进行一些处理才能得到有用的信息。


void MPU6050_ReadAccelerometer(int16_t* acc_x, int16_t* acc_y, int16_t* acc_z)
{
    uint8_t buffer[6];

    // 发送起始信号开始读取加速度计数据
    I2C_GenerateSTART(I2Cx, ENABLE);
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

    I2C_Send7bitAddress(I2Cx, MPU6050_ADDRESS, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    I2C_SendData(I2Cx, 0x3B);  // 设置读取加速度计数据的寄存器地址
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    // 发送重复起始信号,开始接收数据
    I2C_GenerateSTART(I2Cx, ENABLE);
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

    I2C_Send7bitAddress(I2Cx, MPU6050_ADDRESS, I2C_Direction_Receiver);
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

    // 读取加速度计数据
    for (int i = 0; i < 5; i++)  // 读取6个字节,最后一个字节需要NACK
    {
        while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED));
        buffer[i] = I2C_ReceiveData(I2Cx);
    }

    I2C_AcknowledgeConfig(I2Cx, DISABLE);  // 最后一个字节需要NACK
    I2C_GenerateSTOP(I2Cx, ENABLE);
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED));
    buffer[5] = I2C_ReceiveData(I2Cx);

    // 将读取的数据转换为加速度计数据
    *acc_x = (buffer[0] << 8) | buffer[1];
    *acc_y = (buffer[2] << 8) | buffer[3];
    *acc_z = (buffer[4] << 8) | buffer[5];
}
/*
在`MPU6050_ReadAccelerometer`函数中,我们首先定义了一个缓冲区`buffer`,用于存储读取的加速度计数据。

然后,通过发送起始信号开始读取加速度计数据。首先向MPU-6050发送写入加速度计数据的寄存器地址0x3B,然后通过发送重复起始信号,并切换为接收模式。

接下来,我们通过循环读取6个字节的加速度计数据。通过调用`I2C_CheckEvent`函数确认是否接收到了数据,并使用`I2C_ReceiveData`函数将数据存储到`buffer`数组中。

最后一个接收到的字节需要发送NACK,而不是ACK。通过调用`I2C_AcknowledgeConfig`函数禁用ACK,并通过`I2C_GenerateSTOP`发送停止信号。

最后,我们将读取到的加速度计数据从`buffer`数组中转换为`acc_x`、`acc_y`和`acc_z`变量。

*/

4.4 数据处理和滤波

在获得原始数据后,您可以根据需求进行进一步的数据处理和滤波。例如,您可以使用滑动窗口平均或低通滤波器来减少噪声和不稳定性。此外,您还可以根据加速度计和陀螺仪数据,使用姿态解算算法计算物体的姿态,如俯仰角、横滚角和偏航角。

#include "stm32fxxx.h"
#include "stm32fxxx_i2c.h"
#include "kalman.h"  // 引入卡尔曼滤波器库

#define MPU6050_ADDRESS 0xD0  // MPU-6050 I2C地址
#define I2Cx             I2C1  // 使用的I2C外设

kalman_state acc_x_kf, acc_y_kf, acc_z_kf;  // 卡尔曼滤波器状态变量

void MPU6050_ReadAccelerometer(int16_t* acc_x, int16_t* acc_y, int16_t* acc_z)
{
    // 与前述示例代码相同的读取代码
    // ...
}

void MPU6050_FilterAccelerometer()
{
    int16_t acc_x_raw, acc_y_raw, acc_z_raw;

    MPU6050_ReadAccelerometer(&acc_x_raw, &acc_y_raw, &acc_z_raw);

    acc_x_kf = kalman_filter(&acc_x_kf, (float)acc_x_raw);
    acc_y_kf = kalman_filter(&acc_y_kf, (float)acc_y_raw);
    acc_z_kf = kalman_filter(&acc_z_kf, (float)acc_z_raw);
}

int main()
{
    // 初始化I2C和MPU-6050
    // ...

    // 初始化卡尔曼滤波器
    kalman_init(&acc_x_kf, 1, 1, 0.01);  // 参数根据实际需要调整
    kalman_init(&acc_y_kf, 1, 1, 0.01);
    kalman_init(&acc_z_kf, 1, 1, 0.01);

    while (1)
    {
        MPU6050_FilterAccelerometer();

        // 使用过滤后的加速度计读数进行后续处理
        // ...
    }
}
/*
在上面的示例代码中,我们首先在全局定义了三个卡尔曼滤波器状态变量,分别对应X轴、Y轴和Z轴的加速度计数据。

然后,在`MPU6050_ReadAccelerometer`函数中,我们读取原始的加速度计数据。

接下来,在`MPU6050_FilterAccelerometer`函数中,我们将原始数据传入卡尔曼滤波器进行滤波计算。`kalman_filter`函数是卡尔曼滤波器库中实现的滤波函数,通过传入当前的滤波器状态和原始数据,返回经过滤波后的结果。

在主函数中,我们初始化了卡尔曼滤波器状态变量,然后在循环中不断调用`MPU6050_FilterAccelerometer`函数进行滤波,并使用滤波后的数据进行后续处理。
*/

5. 卡尔曼滤波

深入了解卡尔曼滤波:最优状态估计的数学神器

MPU6050芯片手册、模块电路图、测试程序文章来源地址https://www.toymoban.com/news/detail-626834.html

到了这里,关于【物联网】MPU6050传感器数据采集与滤波算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【STM32学习】——I2C通信协议&MPU6050姿态传感器&软件I2C读写MPU6050

    ​   目录 前言 一、I2C通信协议 1.简介 2.硬件电路设计 3.I2C时序(软件)

    2024年02月16日
    浏览(56)
  • MPU6050 加速度计和陀螺仪传感器与 Arduino 连接

    MPU6050是一款非常流行的加速度计陀螺仪芯片,具有六轴感应和 16 位测量分辨率。这种意义上的高精度和低廉的成本使其在 DIY 社区中非常受欢迎。甚至许多商业产品都配备了 MPU6050。陀螺仪和加速度计的组合通常被称为惯性测量单元或 IMU。 IMU 传感器用于各种应用,例如手机

    2024年02月02日
    浏览(57)
  • 人工智能+物联网:从传感器到机器学习:智能化的数据采集和分析

    作者:禅与计算机程序设计艺术 大数据时代是一个数据爆炸的时代。如何从海量数据中快速找到隐藏在其中价值的信息,成为当今企业竞争中不可或缺的能力?人工智能和物联网正在成为经济领域和产业界的主流,新一代互联网物联网平台、AI智能终端、海量数据和算法驱动

    2024年02月09日
    浏览(73)
  • LabVIEW-模拟传感器采集数据并预测数据

    已知某传感器过去的一段时间内采集的数据为d1,d2,d3,......,dn,现欲以m点的数据宽度,预测 tao 步后的数据值,即将一维的时间序列数据重构为如下m+1列的形式: d(1)    d(2 )   .......    d(m),        d(m+tao) d(2)    d(3 )   .......    d(m+1),    d(m+tao+1) ......................

    2024年02月16日
    浏览(48)
  • Java采集传感器数据,亲测有效!

    先说背景 , 最近公司项目需要用到传感器,采集设备温湿度,倾斜角,电流…,公司采购采购了一个温湿度传感器给我们开发测试使用,如下图: 看着还挺精致有没有。 有了这个温湿度传感器,我们如何读取其采集到的数据呢。需要一个 RS485转串口工具 ,下面这个蓝色的

    2024年01月15日
    浏览(52)
  • 车载测试:详解ADAS传感器(相机)标定数据采集方法

    1.基本原理 相机外参标定,通过拍摄多角度棋盘格标定相机外参。 2.外参标定板设计 标定板分为垂直标定板和水平标定板,由于地面的水平标定板不容易被检测到,本文采用垂直标定板进行相机标定。 在标定过程中标定板需要和车身坐标成正交状态,也就是标定板垂直边需

    2024年02月13日
    浏览(84)
  • 单片机采集传感器数据(整形,浮点型)modbus上传

    浮点型数据 占两个寄存器(四个字节) short 整形 占一个寄存器 (两个字节) 注意!!!! stm32 是小端模式,而modbus解析数据是大端模式 所以先发送高字节 如int a=16777220,化为十六进制是0x01 00 00 04, 则04属于低字节,01属于高字节 例如float a=125.6     十六进制0x42 fb 33 3

    2024年02月09日
    浏览(48)
  • STM32+DHT11采集温湿度传感器数据

            DHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够 实时的采集本地湿度和温度。 DHT11 与单片机之间能采用简单的单总线进行通信,仅

    2024年02月07日
    浏览(44)
  • 4G MQTT采集RS485协议传感器到数据库

    1、Modbus slave设置从机Modbus TCP参数 设置Modbus TCP协议和地址 模拟软件设置的是 当前电脑的,所以后面 配置Modbus TCP的从机时,就要填当前电脑的ip地址,不要写 bl系列设备的ip地址 设置数据参数 设备地址:22 功能码:04 数据类型:16 起始地址:0 数量:5个 2、设置BL102将Modbus

    2024年02月02日
    浏览(41)
  • QML android 采集手机传感器数据 并通过udp 发送

    利用 qt 开发 安卓 app ,采集手机传感器数据 并通过udp 发送

    2024年02月02日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包