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

一、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)=125HzSingle_WriteI2C(CONFIG, 0x06); //低通滤波器的截止频率为1K,带宽为5HzSingle_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.mzph.cn/news/158.shtml

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

相关文章

CentOS环境下的Nginx安装

Nginx 安装 下载 nginx 下载地址:http://nginx.org/en/download.html 将下载好的压缩包拷贝到根目录下 通过xshell如果出现 bash: rz: 未找到命令 ,需要先运行下面的命令 yum -y install lrzsz安装 解压到当前目录 tar -zxvf nginx-1.22.1.tar.gz安…

Hive SQL 迁移 Flink SQL 在快手的实践

摘要:本文整理自快手数据架构工程师张芒,阿里云工程师刘大龙,在 Flink Forward Asia 2022 生产实践专场的分享。本篇内容主要分为四个部分: Flink 流批一体引擎 Flink Batch 生产实践 核心优化解读 未来规划 点击查看原文视频…

走进人工智能| Computer Vision 数字化时代的视觉启示录

前言: 计算机视觉是通过模仿人类视觉系统的工作原理,使计算机能够感知、理解和解释图像和视频的能力。 文章目录 序言背景适用领域技术支持应用领域程序员如何学总结 序言 计算机视觉是人工智能领域的一个重要分支,它涉及使计算机能够“看”…

靶场的安装

sqli-lab 1.将安装包解压放到WWW目录下 2.修改 db-creds.inc文件里面的数据库的用户名密码为自己的用户名密码 路径:D:\phpStudy_64\phpstudy_pro\WWW\sqli-labs-master\sql-connections\db-creds.inc 3. 更改php版本位5.9版本,不然会报错 4.安装数…

MFC学习之2048小游戏程序源码

2048游戏的开发原理相对简单,它基于一个4x4的方格,通过控制数字方块的移动来合成相同的数字方块,并生成新的数字方块。 具体实现过程如下: 确定需求:首先需要明确游戏的功能需求,如产生随机数字方块、控制…

MYSQL执行一条SELECT语句的具体流程

昨天CSDN突然抽风 我一个ctrlz把整篇文章给撤掉了还不能复原 直接心态崩了不想写了 不过这部分果然还是很重要,还是写出来吧 流程图 这里面总共有两层结构Server层 储存引擎 Server 层负责建立连接、分析和执行 SQL。MySQL 大多数的核心功能模块都在这实现,主要包…

WebSocket理解

WebSocket理解 WebSocket定义与HTTP关系相同点:不同点:联系总体过程 HTTP问题长轮询Ajax轮询 WebSocket特点 WebSocket 定义 本质上是TCP的协议 持久化的协议 实现了浏览器和服务器的全双工通信,能更好的节省服务器资源和带宽 与HTTP关系 相同点: 基于…

接口测试 react+unittest+flask 接口自动化测试平台

目录 1 前言 2 框架 2-1 框架简介 2-2 框架介绍 2-3 框架结构 3 平台 3-1 平台组件图 1 新建用例 2 生成测试任务 3 执行并查看测试报告 3-2 用例管理 3-2-1 用例设计 3-3 任务管理 3-3-1 创建任务 3-3-2 执行任务 3-3-3 测试报告 3-3-4 邮件通知 1 前言 构建…

【力扣算法12】之 11. 盛最多水的容器 python

文章目录 问题描述示例1示例2提示 思路分析代码分析完整代码详细分析运行效果截图调用示例运行结果完结 问题描述 给定一个长度为 n 的整数数组 height 。有n条垂线,第i条线的两个端点是(i, 0)和(i, height[i])。 找出其中的两条线,使得它们与 x 轴共同构…

解决IDEA项目external libraries依赖包消失的问题

有时候电脑重启后,再打开IDEA上的项目时会出现external libraries目录下的依赖包都消失了的情况,只剩下了一个JDK的包 网上说可以通过刷新IDEA的缓存解决,但我试了没有效果,最后使用如下办法解决: 1.删除项目目录下的…

图论算法笔记

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 第12章 最短路径算法12-1 有权图的最短路径问题最短路径问题-路径规划单源最短路径带权图的最短路径和无权图的最短路径带权图的最短路径算法-Dijkstra算法 12-2 Di…

搭载率突破40%!智能数字座舱比拼,车企还有降本空间吗?

进入2023年,汽车行业的「降本」风潮,驱动产业链上下游开始思考智能化、电动化的投入产出。除了显性的硬件成本(继续堆料,强调性价比,还是减配),软件及背后的开发成本,对于车企来说&a…

GitLab 入选 Forrester Wave™️ 集成软件交付平台,并获评唯一「领导者」!

越来越多企业意识到多工具链集成带来的低效和高成本问题,同时承受着可见性低、反馈不畅通、网络风险大等痛点,应用平台方法来交付软件的呼声越来越大。 极狐(GitLab) 很早就意识到了平台方法的价值,也坚信极狐GitLab 这种单一应用程序的 DevS…

学习vue2笔记

学习vue2笔记 文章目录 学习vue2笔记脚手架文件结构关于不同版本的Vuevue.config.js配置文件ref属性props配置项mixin(混入)插件scoped样式总结TodoList案例webStorage组件的自定义事件全局事件总线(GlobalEventBus)消息订阅与发布(pubsub&am…

el-date-picker 日期时间进行限制,精确到时分秒

需求:用户只能选择当时时间或当前时间之前的时间,且精确到时分秒 实现效果:用户只能选择当前时间的时间,如果选择是当天之前的时间,时分秒不做限制,如果选择的是当天时间,就要判断时分秒&#…

【数据挖掘】时间序列教程【十】

5.4 通用卡尔曼滤波 上一节中描述的状态空间模型作为观测方程的更一般的公式 和状态方程 这里是一个p1 向量是一个k1 向量, 是一个pk 矩阵, 是kk 矩阵。我们可以想到的和 给定初始状态 和 ,预测方程为(类似于上面) 并且更新方程是&#x…

华为Harmony应用开发初探

HarmonyOS是一款面向万物互联时代的、全新的分布式操作系统。在传统的单设备系统能力基础上,HarmonyOS提出了基于同一套系统能力、适配多种终端形态的分布式理念,能够支持手机、平板、智能穿戴、智慧屏、车机等多种终端设备,提供全场景(移动办公、运动健康、社交通信、媒体…

外包干了2个月,技术退步明显...

先说一下自己的情况,大专生,18年通过校招进入湖南某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

Linux进程(二)---进程的优先级和环境变量

我想在这先完成上一章的一个未说完的话题.最后一个我们讲到了僵尸进程,是指子进程已经结束,但是父进程还在运行没有来得及回收.此时这个子进程便是僵尸进程. 但是如果父进程运行完了,也没有回收就直接结束了,那这个子进程改由谁维…

用html+javascript打造公文一键排版系统3:获取参数设置、公文标题排版

我们用自定义函数setDocFmt()来实现对公文的排版。 一、获取公文参数值 要对公文进行排版,首先要读取公文“参数设置”区中的参数值。比如公文要求对公文标题的一般规定是:一般用2号小标宋体字,居中显示。标题与正文中间空一行。 这些是“参…