申继鹏 发表于 2014-5-6 18:54:32

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

       最近在用arduino做自平衡小车,用的是mpu6050的传感器模块。本来是没啥问题的,现成的程序也有,只是看了一下,把库加进去的话,好简单的样子,貌似学不到什么东东。现在我就想求教各位大神,我可以不用那个MPU6050和I2dev的这两个库,直接在arduino上编写读取6050数据的程序吗?看了库的头文件,好多,看的头都大了,也没看出个123来,不知道怎么能在不用这个库的前提下在主程序界面编写6050的程序?有哪位大神做过吗,或者说大家一起来讨论下。不胜感激!!!
下面是我最近编写的代码,代码没啥问题,编译也没有出错,可是读取出来的数据全是零,或者没有变化。不知道是哪出了问题,希望大神们帮帮忙!
#include "Wire.h"      //包含头文件
#define SMPLRT_DIV   0x19 //陀螺仪采样率,典型值:0x07(125Hz)
#define CONFIG       0x1A //低通滤波频率,典型值:0x06(5Hz)
#define GYRO_CONFIG0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
#define ACCEL_XOUT_H 0x3B //定义加速度x轴的高八位
#define ACCEL_XOUT_L 0x3C //定义加速度x轴的低八位
#define ACCEL_YOUT_H 0x3D //定义加速度y轴的高八位
#define ACCEL_YOUT_L 0x3E //定义加速度y轴的低八位
#define ACCEL_ZOUT_H 0x3F //定义加速度z轴的高八位
#define ACCEL_ZOUT_L 0x40 //定义加速度z轴的低八位
#define TEMP_OUT_H0x41
#define TEMP_OUT_L0x42
#define GYRO_XOUT_H0x43 //定义加速度x轴的高八位
#define GYRO_XOUT_L0x44 //定义加速度x轴的低八位
#define GYRO_YOUT_H0x45 //定义加速度y轴的高八位
#define GYRO_YOUT_L0x46 //定义加速度y轴的低八位
#define GYRO_ZOUT_H0x47 //定义加速度z轴的高八位
#define GYRO_ZOUT_L0x48 //定义加速度z轴的低八位
#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 static/image/common/back.gif
大神,下载进去串口都出来的数据全是乱码啊,汉子什么的,程序编译没啥问题

那是因为你的串口监视器的波特率和程序的不一致

申继鹏 发表于 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 static/image/common/back.gif
官网有不用I2Cdev库读取6050的,编译后比用库的小很多.

程序在这一页的末尾:


多谢大神啊,正在研究中。太给力了

春泥蛋炒饭 发表于 2014-5-8 03:27:44

申继鹏 发表于 2014-5-7 19:41 static/image/common/back.gif
多谢大神啊,正在研究中。太给力了

如果你想得到这个程序的文件,到这里下:http://www.geekmomprojects.com/?wpdmact=process&did=Mi5ob3RsaW5r

申继鹏 发表于 2014-5-9 22:34:01

春泥蛋炒饭 发表于 2014-5-8 03:27 static/image/common/back.gif
如果你想得到这个程序的文件,到这里下:http://www.geekmomprojects.com/?wpdmact=process&did=Mi5ob3Rs ...

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

申继鹏 发表于 2014-5-10 22:54:36

春泥蛋炒饭 发表于 2014-5-8 03:27 static/image/common/back.gif
如果你想得到这个程序的文件,到这里下:http://www.geekmomprojects.com/?wpdmact=process&did=Mi5ob3Rs ...

大神,如果不用Wire.h库怎么写?求教

春泥蛋炒饭 发表于 2014-5-11 05:34:27

申继鹏 发表于 2014-5-10 22:54 static/image/common/back.gif
大神,如果不用Wire.h库怎么写?求教

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

kevinfrankchen 发表于 2015-2-27 11:48:43

春泥蛋炒饭 发表于 2014-5-11 05:34 static/image/common/back.gif
不用wire库的话,要使用很多底层寄存器操作,如果不是为了学习,自己写得不偿失

太棒了,一直在找这个,多谢@春泥蛋炒饭

jong 发表于 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 编辑

/* Copyright (C) 2013-2014 Kristian Lauszus, TKJ Electronics. All rights reserved.

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

Contact information
-------------------

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

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

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

uint8_t i2cWrite(uint8_t registerAddress, uint8_t *data, uint8_t length, bool sendStop)
{
Wire.beginTransmission(IMUAddress);
Wire.write(registerAddress);
Wire.write(data, length);
uint8_t rcode = Wire.endTransmission(sendStop); // Returns 0 on success

if (rcode)
{
    Serial.print(F("i2cWrite failed: "));
    Serial.println(rcode);
}
return rcode; // See: http://arduino.cc/en/Reference/WireEndTransmission
}

uint8_t i2cRead(uint8_t registerAddress, uint8_t *data, uint8_t nbytes)
{
uint32_t timeOutTimer;
Wire.beginTransmission(IMUAddress);
Wire.write(registerAddress);
uint8_t rcode = Wire.endTransmission(false); // Don't release the bus
if (rcode)
{
    Serial.print(F("i2cRead failed: "));
    Serial.println(rcode);
    return rcode; // See: http://arduino.cc/en/Reference/WireEndTransmission
}
Wire.requestFrom(IMUAddress, nbytes, (uint8_t)true); // Send a repeated start and then release the bus after reading
for (uint8_t i = 0; i < nbytes; i++)
{
    if (Wire.available())
      data = Wire.read();
    else
    {
      timeOutTimer = micros();
      while (((micros() - timeOutTimer) < I2C_TIMEOUT) && !Wire.available());
      if (Wire.available())
      data = Wire.read();
      else
      {
      Serial.println(F("i2cRead timeout"));
      return 5; // This error value is not already taken by endTransmission
      }
    }
}
return 0; // Success
}这段代码是什么意思?我看到有个平衡小车不用那两个库的,但有这个


https://github.com/TKJElectronics/KalmanFilter
这个地址的,我也在弄平衡小车,能不能把你的小车程序发给我看看,谢谢
页: [1]
查看完整版本: arduino读取MPU6050数据,不用I2dev.h和MPU6050.h库