【Arduino小车实践】陀螺仪的使用

news2024/11/24 15:22:06

一、MPU6050简介

  MPU6050是一款陀螺仪模块,可以测量X、Y、Z三轴的角速度和加速度,还带有温度传感器和数字运动处理器(DMP)。

二、学习步骤

1. I2C协议

        MPU6050是通过I2C协议进行驱动的,配置寄存器和获取数据都需要通过I2C协议去实现开发板与MPU6050之间的通信。

2. MPU6050的相关寄存器

3. 数据处理

        把获取到的原始数据进行处理,如通过互补滤波融合得到角度。

三、I2C协议

        I2C协议通过数据总线SDA和时钟总线SCL去完成单片机与一些传感器模块的通信。SCL和SDA线根据I2C的协议的标准进行一系列高低电平的变化(时序)就可以完成信息的传输。

硬件I2C软件I2C
通过硬件电路去实现的I2C协议通过在单片机上找两个IO口去充当SCL和SDA线,再通过人为编写软件去控制SCL和SDA线的高低电平变化去模拟I2C协议
使用起来比较简单,执行速度比较快,耗时短;稳定性不一定好通过软件模拟的,执行速度不如硬件I2C快,有一定的耗时,不过稳定性就比硬件I2C好

四. MPU6050硬件介绍

        从MPU6050模块正面上我们还可以看到上面标注了X、Y轴的坐标系,那个就是MPU6050自身的坐标系,如下图所示。


  以下是MPU6050的相关管脚,我们使用MPU6050时其实只需要用到VCC、GND、SCL和SDA这四个管脚。

VCC3.3 - 5V(内部有稳压芯片)
GND地线
SCLMPU6050作为从机时IIC时钟线
SDAMPU6050作为从机时IIC数据线
XCLMPU6050作为主机时IIC时钟线
XDAMPU6050作为主机时IIC数据线
AD0地址管脚,该管脚决定了IIC地址的最低一位
INT中断引脚

         AD0管脚的作用:我们知道I2C通信中从机是要有的地址的,以区别多个从机。当AD0管脚接低电平时,从机地址是0xD0。从MPU6050的寄存器中我们可以得到答案,MPU6050作为一个I2C从机设备的时候,有8位地址,高7位的地址是固定的,就是WHO AM I 寄存器中的默认值—0x68,最低一位是由AD0的连线决定的。
  读取MPU6050原始数据这个过程中一个很重要的思路就是一步一步,确保每步都正确后就很容易读出正确的数据。我们对MPU6050进行读写传感器数据就是对MPU6050的寄存器用I2C协议进行读写。对此我们还要了解MPU6050的寄存器,这个过程跟学习51单片机差不多,就是配置寄存器,读取相关数据。

五.MPU6050的几个重要寄存器

SMPLRT_DIV寄存器寄存器地址为0x19
CONFIG寄存器寄存器地址为0x1A
GYRO_CONFIG寄存器寄存器地址为0x1B
寄存器地址为0x1B寄存器地址为0x1C
三轴加速度计的相关寄存器ACCEL_XOUT_H(0x3B) ACCEL_XOUT_L(0x3C)
ACCEL_YOUT_H(0x3D) ACCEL_YOUT_L(0x3E)
ACCEL_ZOUT_H(0x3F) ACCEL_ZOUT_H(0x40)
三轴陀螺仪的相关寄存器GYRO_XOUT_H(0x43) GYRO_XOUT_L(0x44)
GYRO_YOUT_H(0x45) GYRO_YOUT_L(0x46)
GYRO_ZOUT_H(0x47) GYRO_ZOUT_H(0x48)
温度传感器相关的寄存器TEMP_OUT_H(0x41) TEMP_OUT_L(0x42)
PWR_MGMT_1寄存器寄存器地址为0x6B
WHO_AM_I寄存器寄存器的地址为0x75

//初始化MPU6050
void InitMPU6050(){
    Single_WriteI2C(PWR_MGMT_1, 0x00);//解除休眠状态
    Single_WriteI2C(SMPLRT_DIV, 0x07);//陀螺仪采样率为1K/(1+0x07)=125Hz
    Single_WriteI2C(CONFIG, 0x06); //低通滤波器的截止频率为1K,带宽为5Hz
    Single_WriteI2C(GYRO_CONFIG, 0x18);//配置陀螺仪量程为2000deg/s,不自检
    Single_WriteI2C(ACCEL_CONFIG, 0x00);//配置加速度计量程为2g,不自检
}

六、原始数据的单位换算

        由于MPU6050数据寄存器是一个16位的,由于最高位是符号位,故而数据寄存器的输出范围是-7FFF~7FFF ,也既是-32767~32767。
  如果选择陀螺仪范围是±2000,那么意味着-32767对应的是-2000(°/s),32767对应是2000(°/s),当读取陀螺仪的值是1000时,对应的角速度计算如下:32767/2000 =1000/x; 既x = 1000/16.4(°/s),可以看出32767/2000 = 16.4 ,对应手册中的精度 16.4 LSB/(°/s),其他范围也是如此。
  如果是加速度计,采用和陀螺仪同样的计算方法,当AFS_SEL=3时,数字-32767对应-16g,32767对应16g。把32767除以16,就可以得到2048, 即我们说的灵敏度。把从加速度计读出的数字除以2048,就可以换算成加速度的数值。举个例子,如果我们从加速度计读到的数字是1000,那么对应的加速度数据是1000/2048=0.49g。g为加速度的单位,重力加速度定义为1g, 等于9.8米每平方秒。
        总结起来就是,只要对原始数据除以它在该量程下的灵敏度就可以获得实际的物理单位,原始数据时加速度的话,物理单位就为g,原始数据为角速度的话,物理单位就为°/s。

七、 角度换算(滤波算法)

1. 一阶互补滤波

void Get_Balance_Angle(void){
  uint8 gyro_offset = 1;//静置时角速度的偏移量
  float gyro_dt = 0.004f;//陀螺仪角速度积分系数,增长缓慢就增加
  float Filter_weight = 0.02;//滤波权重
 
  Get_GyroData();//获取原始三轴角速度
  Get_AccData();//获取原始三轴加速度

  g_fBalance_Gyro = mpu_gyro_y - gyro_offset;//原始角速度减去零偏值得到实际角速度
  g_fAccel_Angle = (float)atan2(mpu_acc_x,mpu_acc_z) * 57.296;//两轴加速度求反三角得到加速度角度,乘以57.296,是把弧度转化为度

  //一阶互补滤波核心公式,得到融合角度
  g_fBalance_Angle = Filter_Weight * g_fAccel_Angle + (1-Filter_Weight) * (g_fBalance_Angle - g_fBalance_Gyro * gyro_dt);
}

2. 清华角度滤波

/*
*  参数: G_angle——加速度计角度0-90内
*        Gyro——陀螺仪角速度转花后的数值
*        GRAVITY_ADJUST_TIME_CONSTANT——时间校正系数
         DT——定时器时间 单位s
*  函数返回:无符号结果值
*/
void QingHua_AngleCalaulate(float G_angle,float Gyro){
    float fDeltaValue;
    g_fCarAngle = g_fGyroscopeAngleIntegral;   //最终融合角度
    fDeltaValue = (G_angle - g_fCarAngle) / GRAVITY_ADJUST_TIME_CONSTANT;  //时间系数矫正
    g_fGyroscopeAngleIntegral += (Gyro + fDeltaValue) * DT;                //融合角度
}

3、卡尔曼滤波(难理解)

float angle, angle_dot;    //外部需要引用的变量
//angle_m为角速度角度和gyro_m为测到的角速度
void Kalman_Filter(float angle_m,float gyro_m){
    const float Q_angle=0.001, Q_gyro=0.003, R_angle=0.5, dt=0.005;
    //注意:dt的取值为kalman滤波器采样时间;        
    static float P[2][2] = { { 1, 0 },{ 0, 1 } };                           
    static float Pdot[4] ={0,0,0,0};
    static const char C_0 = 1;
    static float q_bias, angle_err, PCt_0, PCt_1, E, K_0, K_1, t_0, t_1;
    angle+=(gyro_m-q_bias) * dt;
    
    Pdot[0]=Q_angle - P[0][1] - P[1][0];
    Pdot[1]=- P[1][1];
    Pdot[2]=- P[1][1];
    Pdot[3]=Q_gyro;
    
    P[0][0] += Pdot[0] * dt;
    P[0][1] += Pdot[1] * dt;
    P[1][0] += Pdot[2] * dt;
    P[1][1] += Pdot[3] * dt;
    
    angle_err = angle_m - angle;
    
    PCt_0 = C_0 * P[0][0];
    PCt_1 = C_0 * P[1][0];
    
    E = R_angle + C_0 * PCt_0;
    
    K_0 = PCt_0 / E;
    K_1 = PCt_1 / E;
    
    t_0 = PCt_0;
    t_1 = C_0 * P[0][1];

    P[0][0] -= K_0 * t_0;
    P[0][1] -= K_0 * t_1;
    P[1][0] -= K_1 * t_0;
    P[1][1] -= K_1 * t_1;
    
    angle  += K_0 * angle_err;//最终融合角度
    q_bias += K_1 * angle_err;
    angle_dot = gyro_m-q_bias;//角速度
}


 

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

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

相关文章

OpenMMLab MMTracking目标跟踪环境搭建(一)

1、环境搭建 创建conda虚拟环境并激活。 conda create -n mmtrack python3.8 -y conda activate mmtrack 按照官方说明安装 PyTorch 和 torchvision 可以通过指定版本号切换到其他版本。 #如果网不好,可以这样安装 pip3 install torch1.8.2cu102 torchvision0.9…

基于SpringBoot+vue的校园闲置物品租售系统设计与实现

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

postman:模拟发送一个需要 cookie 认证的请求

目录 前言: 1、chrome 已安装插件 intercept。 2、chrome 浏览器要设置打开,在运行期间浏览器要一直打开。 3、本人是用 fiddler 对 app 的请求进行抓包,也可以使用其他工具。查看 headers 里的 cookie,并复制。 4、将复制的…

Ubuntu安装zsh主题

安装zsh sudo apt install zsh安装git(如果有跳过) sudo apt install git(1条消息) 关于Git这一篇就够了_17岁boy想当攻城狮的博客-CSDN博客 安装oh my zsh git clone https://github.com/robbyrussell/oh-my-zsh切换目录到oh-my-zsh文件夹下的tools…

0基础学习VR全景平台篇 第62篇:通用功能-通用设置

公开:公开表示该作品对所有人可见,并且会在蛙色VR平台和个人主页显示。点击公开会切换成私人模式,私人则表示只有作者本人可以访问,他人即使获取了链接也无法打开。 预览:点击“预览”可以查看VR视频的效果&#xff0…

【LeetCode热题100】打卡第37天:岛屿数量反转链表

文章目录 【LeetCode热题100】打卡第37天:岛屿数量&反转链表⛅前言 岛屿数量🔒题目🔑题解 反转链表🔒题目🔑题解 【LeetCode热题100】打卡第37天:岛屿数量&反转链表 ⛅前言 大家好,我是…

kettle开发-Day41-数据清洗之字符串替换

前言: 昨天讲到了通过case/switch组件来进行分流,来区分日期里面三大类的数据,包括正常显示的2023/7/12 2:59:58的数据,一种是包含中文上午的数据,一种是包含中文下午的数据。但是我们发现这样直接存进去的数据还是包含…

时间有界 梦想无疆(NEBASE第十三课)

时间有界 梦想无疆(NEBASE第十三课) 1、计算机网络功能 数据通信、资源共享、增加数据可靠性、提高系统处理能力(主要功能数所通信) 2.标准:一致同意的规则可以理解为标谁 ISO(国际标准化组织)在网络通信中创建了OS…

前端学习——JS进阶 (Day1)

作用域 局部作用域 全局作用域 作用域链 JS垃圾回收机制 闭包 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name&qu…

walkRE2019--属性批量赋值

1、选中待赋值的图形&#xff0c;在加工菜单栏中选择属性赋值&#xff0c;如下&#xff1a; 选择图形所在图层&#xff0c;并使图层处于可编辑状态。选择要赋值的属性字段&#xff08;即要更新的列&#xff09;&#xff0c;选择要赋值的表达式&#xff08;即赋值为&#xff09;…

产品经理必备技能:高效产品规划方法论

作为产品经理&#xff0c;进行产品规划是非常重要的一项工作。产品规划是一个方法化的过程&#xff0c;需要考虑多个因素&#xff0c;以确保产品能够满足用户需求并实现商业目标。以下是几点建议&#xff0c;帮助产品经理进行产品规划。 第一&#xff0c;了解用户需求和市场情况…

【Unity编辑器扩展】编辑器代码一键添加按钮响应事件

此功能能是基于UI变量代码生成工具的改良扩展&#xff1a;【Unity编辑器扩展】UI变量代码自动生成工具(编辑器扩展干货/大幅提高效率)_ui代码自动生成_TopGames的博客-CSDN博客 工具效果预览&#xff1a; UGUI的Button按钮在编辑面板添加响应事件非常繁琐&#xff0c;需要拖个…

视频孪生在数字经济产业发展中所发挥的作用

2023年中共中央、国务院印发的《数字中国建设整体布局规划》中明确提出&#xff1a;培育壮大数字经济核心产业&#xff0c;研究制定推动数字产业高质量发展的措施&#xff0c;打造具有国际竞争力的数字产业集群。 推动数字技术和实体经济深度融合&#xff0c;在农业、工业、金…

七大排序算法——堆排序,通俗易懂的思路讲解与图解(完整Java代码)

文章目录 一、排序的概念排序的概念排序的稳定性七大排序算法 二、堆排序核心思想代码实现 三、性能分析四、七大排序算法 一、排序的概念 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递…

emacs下vercial-border审美观记录

昨天一晚上时间都花在了emacs的vercial-border上。 一开始还不知道这个名词&#xff0c;以为是treemacs展示的效果&#xff0c;毕竟我是在打开treemacs的时候&#xff0c;才发现这个分割线太丑了,我的审美观在蠢蠢欲动了。 谁说程序员没有审美观的&#xff1f;只是前面有别的东…

一文带你快速设计精美可视化大屏

一文带你快速设计精美可视化大屏 文章目录 一文带你快速设计精美可视化大屏&#x1f468;‍&#x1f3eb;前言&#xff1a;什么是可视化大屏&#x1f468;‍&#x1f52c;内容1&#xff1a;可视化大屏设计原则和设计考虑&#x1f468;‍⚖️内容2&#xff1a;可视化大屏设计流程…

第四章 数学知识(三)——高斯消元,组合

文章目录 高斯消元组合数1 < b < a < 20001 < b < a < 1000001 < b < a < 1 0 18 10^{18} 1018高精度组合数卡特兰数 高斯消元练习题884. 高斯消元解异或线性方程组 组合数练习题885. 求组合数 I886. 求组合数 II887. 求组合数 III888. 求组合数 I…

【AUTOSAR】:NvM

Autosar的NvM理解 AUTOSAR_SWS_NVRAMManager.pdf块的定义块的管理类型块的状态重点梳理:几个常用的API函数AUTOSAR_SWS_MemoryAbstractionInterface.pdf里面对存储的HAL抽象衍生出几个重要的MainFunctionNV (non volatile):非亦失性,也就是我们需要将数据存储到Flash或外部E…

谈谈企业未来如何实现有序用电

摘 要&#xff1a;风光发电的大比例发展将对电网需要的转动惯量和备用产生致命影响&#xff0c;严重威胁电网的平稳运行&#xff0c;本文结合AcrelEMS企业微电网系统谈谈企业如何应对。 关键词&#xff1a;有序用电 调节负荷 综合能源管理 企业微电网 0 引言 自2020年9月以来&…

android linker加载和链接机制

文章目录 So的加载和启动So文件的读取与加载工作ReadProgramHeaderReserveAddressSpaceLoadSegmentsFindPhdr so 的链接机制动态节区 执行so文件原文地址&#xff1a; So的加载和启动 handledlopen(pathName,PTLD_LAZY)&#xff1b;//获得指定文件的句柄&#xff0c;这个handl…