极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 30652|回复: 11

arduino读取MPU6050数据,不用I2dev.h和MPU6050.h库

[复制链接]
发表于 2014-5-6 18:54:32 | 显示全部楼层 |阅读模式
       最近在用arduino做自平衡小车,用的是mpu6050的传感器模块。本来是没啥问题的,现成的程序也有,只是看了一下,把库加进去的话,好简单的样子,貌似学不到什么东东。现在我就想求教各位大神,我可以不用那个MPU6050和I2dev的这两个库,直接在arduino上编写读取6050数据的程序吗?看了库的头文件,好多,看的头都大了,也没看出个123来,不知道怎么能在不用这个库的前提下在主程序界面编写6050的程序?有哪位大神做过吗,或者说大家一起来讨论下。不胜感激!!!
下面是我最近编写的代码,代码没啥问题,编译也没有出错,可是读取出来的数据全是零,或者没有变化。不知道是哪出了问题,希望大神们帮帮忙!
#include "Wire.h"        //包含头文件
#define SMPLRT_DIV   0x19 //陀螺仪采样率,典型值:0x07(125Hz)
#define CONFIG       0x1A //低通滤波频率,典型值:0x06(5Hz)
#define GYRO_CONFIG  0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)  
#define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)  
#define ACCEL_XOUT_H 0x3B //定义加速度x轴的高八位[15:8]
#define ACCEL_XOUT_L 0x3C //定义加速度x轴的低八位[7:0]
#define ACCEL_YOUT_H 0x3D //定义加速度y轴的高八位[15:8]
#define ACCEL_YOUT_L 0x3E //定义加速度y轴的低八位[7:0]
#define ACCEL_ZOUT_H 0x3F //定义加速度z轴的高八位[15:8]
#define ACCEL_ZOUT_L 0x40 //定义加速度z轴的低八位[7:0]
#define TEMP_OUT_H  0x41
#define TEMP_OUT_L  0x42
#define GYRO_XOUT_H  0x43 //定义加速度x轴的高八位[15:8]
#define GYRO_XOUT_L  0x44 //定义加速度x轴的低八位[7:0]
#define GYRO_YOUT_H  0x45 //定义加速度y轴的高八位[15:8]
#define GYRO_YOUT_L  0x46 //定义加速度y轴的低八位[7:0]
#define GYRO_ZOUT_H  0x47 //定义加速度z轴的高八位[15:8]
#define GYRO_ZOUT_L  0x48 //定义加速度z轴的低八位[7:0]
#define PWR_MGMT_1   0x6B //电源管理,典型值:0x00(正常启用)
#define WHO_AM_I     0x75 //IIC地址寄存器(默认数值0x68,只读)
#define SlaveAddress 0xD0 //IIC写入时的地址字节数据,+1为读取
int ax0,ax1,axout;        //定义加速度传感器从寄存器地址获取的高八位低八位数据以及输出的模拟量
int ay0,ay1,ayout;        
int az0,az1,azout;        

int gx0,gx1,gxout;        //定义陀螺仪传感器从寄存器地址获取的高八位低八位数据以及输出的模拟量
int gy0,gy1,gyout;
int gz0,gz1,gzout;
double Xa,Ya,Za;
double Xg,Yg,Zg;
//float aax,aay;
//float pi=3.1415926;
int MPU6050address = 0x68;//MPU6050的地址
void setup()
{
Wire.begin();            //设置I2通信时的本机地址
Serial.begin(9600);
Wire.beginTransmission(MPU6050address);//启动I2通信,读取MPU6050地址
// Wire.write(GYRO_CONFIG);//从传感器写入数据
// Wire.write(ACCEL_CONFIG);
Wire.write(8);          //写入8位字节
Wire.endTransmission();//结束通信
}
void loop()
{
  Wire.beginTransmission(MPU6050address);
  Wire.write(ACCEL_XOUT_H);//写加速度计x轴数据
  Wire.write(ACCEL_XOUT_L);
  Wire.write(GYRO_XOUT_H);//写陀螺仪计x轴数据
  Wire.write(GYRO_XOUT_L);
  Wire.endTransmission();
  Wire.requestFrom(MPU6050address,2);
   if(Wire.available()<=2);//用于返回接受的字节数
   {
   ax0 = Wire.read();
   ax1 = Wire.read();
   ax1 = ax1<<8;
   axout = ax0+ax1;
   
   gx0 = Wire.read();
   gx1 = Wire.read();
   gx1 = gx1<<8;
   gxout = gx0+gx1;
   }
   
  Wire.beginTransmission(MPU6050address);
  Wire.write(ACCEL_YOUT_H);
  Wire.write(ACCEL_YOUT_L);
  Wire.write(GYRO_YOUT_H);
  Wire.write(GYRO_YOUT_L);
  Wire.endTransmission();
  Wire.requestFrom(MPU6050address,2);
   if(Wire.available()<=2);
   {
   ay0 = Wire.read();
   ay1 = Wire.read();
   ay1 = ay1<<8;
   ayout = ay0+ay1;
   
   gy0 = Wire.read();
   gy1 = Wire.read();
   gy1 = gy1<<8;
   gyout = gy0+gy1;
   }
   
  Wire.beginTransmission(MPU6050address);
  Wire.write(ACCEL_ZOUT_H);
  Wire.write(ACCEL_ZOUT_L);
  Wire.write(GYRO_ZOUT_H);
  Wire.write(GYRO_ZOUT_L);
  Wire.endTransmission();
  Wire.requestFrom(MPU6050address,2);
   if(Wire.available()<=2);
   {
   az0 = Wire.read();
   az1 = Wire.read();
   az1 = ax1<<8;
   azout = az0+az1;
   
   gz0 = Wire.read();
   gz1 = Wire.read();
   gz1 = gz1<<8;
   gzout = gz0+gz1;
   }
  Xa=axout/256.00;      //把输出结果转换为重力加速度g,精确到小数点后2位
  Ya=ayout/256.00;
  Za=azout/256.00;

  Xg=gxout/256.00;
  Yg=gyout/256.00;
  Zg=gzout/256.00;
// aax = atan(Xa/Za) * (-180) / pi; //想转化为角度的,可是感觉到有点不对,就没写进去
// aay = atan(Ya/Xa) * (-180) / pi;
  
  Serial.println("Xa:");//输出6050不同轴采集到的数据
  Serial.print(Xa,DEC);
  Serial.println('\n');
  Serial.println("Ya:");
  Serial.print(Ya,DEC);
   Serial.println('\n');
  Serial.println("Za:");
  Serial.print(Za,DEC);
  Serial.println('\n');
  delay(500);
  Serial.println("Xg:");
  Serial.print(Xg,DEC);
  Serial.println('\n');
  Serial.println("Yg:");
  Serial.print(Yg,DEC);
  Serial.println('\n');
  Serial.println("Zg:");
  Serial.print(Zg,DEC);
  Serial.println('\n');
delay(500);  
}
回复

使用道具 举报

发表于 2014-5-11 05:22:55 | 显示全部楼层
申继鹏 发表于 2014-5-9 22:34
大神,下载进去串口都出来的数据全是乱码啊,汉子什么的,程序编译没啥问题

那是因为你的串口监视器的波特率和程序的不一致
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2014-5-6 18:55:21 | 显示全部楼层
小弟在这谢过各位了
回复 支持 反对

使用道具 举报

发表于 2014-5-7 00:46:43 | 显示全部楼层
官网有不用I2Cdev库读取6050的,编译后比用库的小很多.

程序在这一页的末尾:

http://playground.arduino.cc/Main/MPU-6050
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-5-7 19:41:53 | 显示全部楼层
春泥蛋炒饭 发表于 2014-5-7 00:46
官网有不用I2Cdev库读取6050的,编译后比用库的小很多.

程序在这一页的末尾:

多谢大神啊,正在研究中。太给力了
回复 支持 反对

使用道具 举报

发表于 2014-5-8 03:27:44 | 显示全部楼层
申继鹏 发表于 2014-5-7 19:41
多谢大神啊,正在研究中。太给力了

如果你想得到这个程序的文件,到这里下:http://www.geekmomprojects.com/? ... mp;did=Mi5ob3RsaW5r
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-5-9 22:34:01 | 显示全部楼层
春泥蛋炒饭 发表于 2014-5-8 03:27
如果你想得到这个程序的文件,到这里下:http://www.geekmomprojects.com/?wpdmact=process&did=Mi5ob3Rs ...

大神,下载进去串口都出来的数据全是乱码啊,汉子什么的,程序编译没啥问题
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-5-10 22:54:36 | 显示全部楼层
春泥蛋炒饭 发表于 2014-5-8 03:27
如果你想得到这个程序的文件,到这里下:http://www.geekmomprojects.com/?wpdmact=process&did=Mi5ob3Rs ...

大神,如果不用Wire.h库怎么写?求教
回复 支持 反对

使用道具 举报

发表于 2014-5-11 05:34:27 | 显示全部楼层
申继鹏 发表于 2014-5-10 22:54
大神,如果不用Wire.h库怎么写?求教

不用wire库的话,要使用很多底层寄存器操作,如果不是为了学习,自己写得不偿失
回复 支持 反对

使用道具 举报

发表于 2015-2-27 11:48:43 | 显示全部楼层
春泥蛋炒饭 发表于 2014-5-11 05:34
不用wire库的话,要使用很多底层寄存器操作,如果不是为了学习,自己写得不偿失

太棒了,一直在找这个,多谢@春泥蛋炒饭
回复 支持 反对

使用道具 举报

发表于 2016-6-15 18:35:03 | 显示全部楼层
楼主这个程序有多出错误,我发现的主要是:
1.启用MPU需要在他的0x6B寄存器写0;
2.读数据的先得到高字节,楼主写反了;
3.写一个寄存器可以一次读一个字节,楼主写了4个寄存器每次只读两个,丢了两个字节数据;
4.读到的数据除以256是怎么回事。
回复 支持 反对

使用道具 举报

发表于 2016-7-15 21:41:16 | 显示全部楼层
本帖最后由 好奇吖斌 于 2016-7-18 12:10 编辑
  1. /* Copyright (C) 2013-2014 Kristian Lauszus, TKJ Electronics. All rights reserved.

  2.   This software may be distributed and modified under the terms of the GNU
  3.   General Public License version 2 (GPL2) as published by the Free Software
  4.   Foundation and appearing in the file GPL2.TXT included in the packaging of
  5.   this file. Please note that GPL2 Section 2[b] requires that all works based
  6.   on this software must also be made publicly available under the terms of
  7.   the GPL2 ("Copyleft").

  8.   Contact information
  9.   -------------------

  10.   Kristian Lauszus, TKJ Electronics
  11.   Web      :  http://www.tkjelectronics.com
  12.   e-mail   :  [email protected]
  13. */

  14. const uint8_t IMUAddress = 0x68; // AD0 is logic low on the PCB
  15. const uint16_t I2C_TIMEOUT = 100; // Used to check for errors in I2C communication

  16. uint8_t i2cWrite(uint8_t registerAddress, uint8_t data, bool sendStop)
  17. {
  18.   return i2cWrite(registerAddress, &data, 1, sendStop); // Returns 0 on success
  19. }

  20. uint8_t i2cWrite(uint8_t registerAddress, uint8_t *data, uint8_t length, bool sendStop)
  21. {
  22.   Wire.beginTransmission(IMUAddress);
  23.   Wire.write(registerAddress);
  24.   Wire.write(data, length);
  25.   uint8_t rcode = Wire.endTransmission(sendStop); // Returns 0 on success
  26.   
  27.   if (rcode)
  28.   {
  29.     Serial.print(F("i2cWrite failed: "));
  30.     Serial.println(rcode);
  31.   }
  32.   return rcode; // See: http://arduino.cc/en/Reference/WireEndTransmission
  33. }

  34. uint8_t i2cRead(uint8_t registerAddress, uint8_t *data, uint8_t nbytes)
  35. {
  36.   uint32_t timeOutTimer;
  37.   Wire.beginTransmission(IMUAddress);
  38.   Wire.write(registerAddress);
  39.   uint8_t rcode = Wire.endTransmission(false); // Don't release the bus
  40.   if (rcode)
  41.   {
  42.     Serial.print(F("i2cRead failed: "));
  43.     Serial.println(rcode);
  44.     return rcode; // See: http://arduino.cc/en/Reference/WireEndTransmission
  45.   }
  46.   Wire.requestFrom(IMUAddress, nbytes, (uint8_t)true); // Send a repeated start and then release the bus after reading
  47.   for (uint8_t i = 0; i < nbytes; i++)
  48.   {
  49.     if (Wire.available())
  50.       data[i] = Wire.read();
  51.     else
  52.     {
  53.       timeOutTimer = micros();
  54.       while (((micros() - timeOutTimer) < I2C_TIMEOUT) && !Wire.available());
  55.       if (Wire.available())
  56.         data[i] = Wire.read();
  57.       else
  58.       {
  59.         Serial.println(F("i2cRead timeout"));
  60.         return 5; // This error value is not already taken by endTransmission
  61.       }
  62.     }
  63.   }
  64.   return 0; // Success
  65. }
复制代码
这段代码是什么意思?我看到有个平衡小车不用那两个库的,但有这个


https://github.com/TKJElectronics/KalmanFilter
这个地址的,我也在弄平衡小车,能不能把你的小车程序发给我看看,谢谢
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-5-20 08:47 , Processed in 0.078251 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表