arduino mpu9250_arduino模拟输出

arduino mpu9250_arduino模拟输出Arduino有多种通信方式,每一种通信方式都有相对应的类库来支持:1)硬件串口通信——HardwareSerial类库2)软件模拟串口通信——SoftwareSerial类库3)IIC总线的使用——Wire类库4)SPI总线的使用——SPI类库 MPU6050的数据接口用的是I2C总线协议,因此我们需要Wire类库的帮助来实现Arduino与MPU6050之间的通…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

Arduino有多种通信方式,每一种通信方式都有相对应的类库来支持:

1)硬件串口通信——HardwareSerial 类库

2)软件模拟串口通信——SoftwareSerial 类库

3)IIC总线的使用——Wire 类库

4)SPI总线的使用——SPI 类库

 

MPU6050的数据接口用的是I2C总线协议,因此我们需要Wire类库的帮助来实现Arduino与MPU6050之间的通信。

MPU6050的数据写入和读出均通过其芯片内部的寄存器实现,这些寄存器的地址都是1个字节,也就是8位的寻址空间,其寄存器的详细列表说明书请点击下载:

https://www.olimex.com/Products/Modules/Sensors/MOD-MPU6050/resources/RM-MPU-60xxA_rev_4.pdf

使用Arduino的Wire类库来学习MPU6050与arduino的IIC通信,比直接学习MPU6050与单片机或其他更高级芯片的通信要容易许多。在arduino平台上完成MPU6050的测试后,应该转而在其他平台上使用MPU6050。当然能够实现设备通信只是迈出了其中的一小步,更重要的是在获得惯性测量单元的数据后,会对数据进行处理。最后,能够使用MPU6050来做一些小项目是最好的,例如平衡车、四轴飞行器等等。
 

一、了解 wire.h

1.库包含的函数:

    1) Wire.begin()和Wire.begin(address):初始化IIC连接。无参数,设备以主机模式加入IIC总线;写参数,设备以从机模式加入IIC总线,address为一个7位的从机地址。语法为:

    begin():           

    begin(address): 

    返回值:none

   

    2) Wire.requestFrom():主机向从机发送数据请求信号(n*一个字节)。使用后,从机可以使用onRequest()注册一个事件以响应主机请求。随后,数据可以被主设备用available()和read()函数接收。语法为:

    Wire.requestFrom(address, quantity):设备(从机)的地址、请求的字节数

    Wire.requestFrom(address, quantity, stop):stop参数为boolean型值,值为true则发送停止命令,释放IIC总线;值为false则发送重新开始信息,并继续保持IIC总线的有效连接。

    返回值:none

 

    3) Wire.beginTransmission():设定传输数据到指定地址的从机设备。随后可以使用write()函数发送数据,并搭配endTransmission():函数结束数据传输。

    语法:wire.beginTransmission(address):

    返回值:none

 

    4) Wire.endTransmission():结束一个由beginTransmission()开始的并且由write()排列的从机的传输。语法为:

    Wire.endTransmission()

    Wire.endTransmission(stop):stop为biilean型值,值为true(没有填写stop参数时,等效使用true)则发送一个停止信息;值为false则发送一个重新开始信息,并继续保持IIC总线的有效连接。

    返回值:0 成功   1 数据溢出   2 发送addtess时从机接受到NACK   3 发送数据时接受到NACK   4 其他错误

 

    5) Wire.write():向从机发送数据(双向?主机状态:主机将要发送的数据加入发送队列;从机状态:从机发送数据至发起请求的主机)。语法为:

    Wire.write(value):value 要发送的数值(以单字节发送)

    Wire.write(string):string 字符组的指针(以一系列字节发送)

    Wire.write(data, length):data 一个字节数组(以字节形式发送数组);length 传输的字节数

    返回值:byte型值,返回输入的字节数。

 

    6) Wire.available():返回接收到的字节数

    在主机中,一般用于主机发送数据请求后;在从机中,一般用于数据接收事件。语法为:

    Wire.available()  无参数

    返回值:byte型值,返回输入的字节数。

 

    7) Wire.read():读取1B的数据

    在主机中,使用requestFrom()函数发送数据请求信号后,需要使用read()函数来获取数据;在从机中需要使用read()读取主机发送来的数据。语法为:

    Wire.read()  无参数

    char c = Wire.read():以字符串形式接收数据(将数据作为字符接收)

    int x = Wire.read():以整型形式接收数据

    返回值:读到的字节数据

 

    8) Wire.onReceive():在从机端注册一个事件,当从机收到主机发送的数据时即被触发。语法为:

    Wire.onReceive(handler):handler 当从机接收到数据时可被触发的事件。该事件带有一个int型参数(从主机读到的字节数)且没有返回值,如 void myHandler(int numBytes)

    返回值:none

 

    9) Wire.onRequest():注册一个事件,当从机接收到主机数据请求时即被触发

    Wire.onRequest(handler):handler  可被触发的事件。该事件不带参数和返回值,如 void myHandler() 。

    返回值:none

 

二、关于MPU6050:

1.关于输出精度:

    以MPU6050加速度测量值为例:量程是±8g时,测量精度是4096LSB/g,

    LSB的意思是最小有效位,为数字输出方式下使用;

    一般我们可以用mg/LSB来表示G-Sensor灵敏度,例如:mpu6050输出的位数为16位(2的16次方共65536个LSB)对应满量程,当量程为±2g时对应灵敏度就为4g/65536LSB=0.06103515625mg/LSB,取倒数为16384LSB/g。所以我们可以看到mpu605X寄存器手册中的accelerometers’ sensitivity per LSB in ACCEL_xOUT:

arduino mpu9250_arduino模拟输出

    因为mpu6050只能16位输出,所以测量范围越大,对应精度就越低。上面表格的数据存在一个规律,即:

    Full Scalse Range * LSB Sensitivity = 32768

(参考:http://www.geek-workshop.com/thread-9146-1-1.html)

 

三、基础使用:

以下实例实现 Arduino uno 与 MPU6050 的 IIC 通信,并通过 Arduino 与 PC 机的串口通讯将 MPU6050 的测量值打印在Arduino IDE 的串口监视器上。实例中未使用中断功能。读取的数据只经过单位的转换,未做其他数据处理(如果要应用在项目上,可能要对原始数据进行滤波处理、数学演算等,才能给程序使用。)

//连线方法
//MPU-UNO
//VCC-5V
//GND-GND
//SCL-A5
//SDA-A4
//ADO-GND
//未使用中断功能,即没有做 INT-digital pin 2 (interrupt pin 0) 这样的接线

//参考手册:MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2

#include <Wire.h>

long accelX, accelY, accelZ;      // 定义为全局变量,可直接在函数内部使用
float gForceX, gForceY, gForceZ;

long gyroX, gyroY, gyroZ;
float rotX, rotY, rotZ;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  setupMPU();
}

void loop() {
  recordAccelRegisters();
  recordGyroRegisters();
  printData();
  delay(100);
}

void setupMPU(){
  // REGISTER 0x6B/REGISTER 107:Power Management 1
  Wire.beginTransmission(0b1101000); //This is the I2C address of the MPU (b1101000/b1101001 for AC0 low/high datasheet Sec. 9.2)
  Wire.write(0x6B); //Accessing the register 6B/107 - Power Management (Sec. 4.30) 
  Wire.write(0b00000000); //Setting SLEEP register to 0, using the internal 8 Mhz oscillator
  Wire.endTransmission();

  // REGISTER 0x1b/REGISTER 27:Gyroscope Configuration
  Wire.beginTransmission(0b1101000); //I2C address of the MPU
  Wire.write(0x1B); //Accessing the register 1B - Gyroscope Configuration (Sec. 4.4) 
  Wire.write(0x00000000); //Setting the gyro to full scale +/- 250deg./s (转化为rpm:250/360 * 60 = 41.67rpm) 最高可以转化为2000deg./s 
  Wire.endTransmission();
  
  // REGISTER 0x1C/REGISTER 28:ACCELEROMETER CONFIGURATION
  Wire.beginTransmission(0b1101000); //I2C address of the MPU
  Wire.write(0x1C); //Accessing the register 1C - Acccelerometer Configuration (Sec. 4.5) 
  Wire.write(0b00000000); //Setting the accel to +/- 2g(if choose +/- 16g,the value would be 0b00011000)
  Wire.endTransmission(); 
}

void recordAccelRegisters() {
  // REGISTER 0x3B~0x40/REGISTER 59~64
  Wire.beginTransmission(0b1101000); //I2C address of the MPU
  Wire.write(0x3B); //Starting register for Accel Readings
  Wire.endTransmission();
  Wire.requestFrom(0b1101000,6); //Request Accel Registers (3B - 40)

  // 使用了左移<<和位运算|。Wire.read()一次读取1bytes,并在下一次调用时自动读取下一个地址的数据
  while(Wire.available() < 6);  // Waiting for all the 6 bytes data to be sent from the slave machine (必须等待所有数据存储到缓冲区后才能读取) 
  accelX = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX (自动存储为定义的long型值)
  accelY = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY
  accelZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ
  processAccelData();
}

void processAccelData(){
  gForceX = accelX / 16384.0;     //float = long / float
  gForceY = accelY / 16384.0; 
  gForceZ = accelZ / 16384.0;
}

void recordGyroRegisters() {
  // REGISTER 0x43~0x48/REGISTER 67~72
  Wire.beginTransmission(0b1101000); //I2C address of the MPU
  Wire.write(0x43); //Starting register for Gyro Readings
  Wire.endTransmission();
  Wire.requestFrom(0b1101000,6); //Request Gyro Registers (43 ~ 48)
  while(Wire.available() < 6);
  gyroX = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX
  gyroY = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY
  gyroZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ
  processGyroData();
}

void processGyroData() {
  rotX = gyroX / 131.0;
  rotY = gyroY / 131.0; 
  rotZ = gyroZ / 131.0;
}

void printData() {
  Serial.print("Gyro (deg)");
  Serial.print(" X=");
  Serial.print(rotX);
  Serial.print(" Y=");
  Serial.print(rotY);
  Serial.print(" Z=");
  Serial.print(rotZ);
  Serial.print(" Accel (g)");
  Serial.print(" X=");
  Serial.print(gForceX);
  Serial.print(" Y=");
  Serial.print(gForceY);
  Serial.print(" Z=");
  Serial.println(gForceZ);
}

Jetbrains全家桶1年46,售后保障稳定

代码中相关设置的依据以及使用的寄存器: 
1)MPU6050的IIC地址:
arduino mpu9250_arduino模拟输出
2)电源管理寄存器:
arduino mpu9250_arduino模拟输出
3)陀螺仪配置:
arduino mpu9250_arduino模拟输出
4)加速度计配置:
arduino mpu9250_arduino模拟输出
5)加速度计测量值:
arduino mpu9250_arduino模拟输出
6)陀螺仪测量值:
arduino mpu9250_arduino模拟输出
三、简单应用:
 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/234290.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 此工作站和主域直接信任失败_依赖服务或组无法启动win10

    此工作站和主域直接信任失败_依赖服务或组无法启动win10背景:此工作站和主域的信任关系失败(客户机连接服务器)。问题问题分析如果不能远程连接到服务器,我们也不能ping通服务器,有可能是我们的服务器脱域解决方案:一.重启;用这种方法不行二.重加域1.重新退出域;2.重新加入域;以下则表示成功…

    2022年10月19日
  • 数据库读写分离目的是做什么[通俗易懂]

    数据库设置主从库,主库用来写数据,多个从库来查询数据。消除读写的冲突,提高性能主从的一致性问题需要考虑主从一致,用的是binlog来同步,就是回慢4.主从同步就是两个思路A、半同步复制,等从库复制成功才返回写成功B、设一个key记录着一次写的数据,然后设置一个同步时间,如果在这个时间内,有一个读请求,看看对应的key有没有相关数据,有的话,说明数据近期发生过写事件,这样key的…

  • 软件工程期末试题及答案(史上最全)

    软件工程期末试题及答案(史上最全)软件工程期末试题及答案1.开发瀑布模型中的软件定义时期各个阶段依次是:(B)A)可行性研究,问题定义,需求分析。B)问题定义,可行性研究,需求分析。C)可行性研究,需求分析,问题定义。D)以上顺序都不对。(软件开发时期:概要设计、详细设计、软件实现、软件测试)2.可行性研究主要从以下几个方面进行研究:(A)A)技术可行性,经济可行性,操作可行性。B)技术可行性,经济可行性,系统可行性。C)经济可行性,系统可行性,操作可行性。D)经济可行性,系统可行性,时间可行性。..

  • visual studio2015 密钥_visualstudio2013

    visual studio2015 密钥_visualstudio2013参考自:《visualstudio2012密钥》https://zhidao.baidu.com/question/555696036850635212.htmlvs2012密钥序列号(保证完美激活);YKCW6-BPFPF-BT8C9-7DCTH-QXGWCRBCXF-CVBGR-382MK-DFHJ4-C69G8YQ7PR-QTHDM-…

    2022年10月14日
  • 一文完全理解模型ks指标含义并画出ks曲线(包含代码和详细解释)「建议收藏」

    KS(Kolmogorov-Smirnov):KS用于模型风险区分能力进行评估,指标衡量的是好坏样本累计分部之间的差值。好坏样本累计差异越大,KS指标越大,那么模型的风险区分能力越强。——神秘的KS值和GINI系数上面是ks的简单介绍,相信大家看了这几句话,肯定还是不懂ks到底是个什么。我也是研究了比较久,终于搞清楚了ks的具体计算方式。搞清楚了计算方式后,ks的含义自然就清楚了。下面…

  • JDK自带工具jps,jstat,jmap,jconsole使用[通俗易懂]

    JDK自带工具jps,jstat,jmap,jconsole使用

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号