armray 发表于 2015-4-30 13:29:35

tsaiwn 发表于 2015-4-30 13:01 static/image/common/back.gif
(1) Classname objname( );这样会有问题喔?
   奇怪, 难道 Arduino 的 C++ 解读 class / object 不 ...

好吧,没有耽误你正事就好。编程菜鸟,没有区分过object和class,,几个语言都学混了,都不精。

tsaiwn 发表于 2015-5-1 00:13:15

armray 发表于 2015-4-30 13:29 static/image/common/back.gif
好吧,没有耽误你正事就好。编程菜鸟,没有区分过object和class,,几个语言都学混了,都不精。

看起来应该是以下
error = MPU6050_read (MPU6050_ACCEL_XOUT_H, (uint8_t *) &accel_t_gyro, sizeof(accel_t_gyro));
没有取得正确的addressofaccel_t_gyro, 就是 &accel_t_gyro 啦
但是
这样有点奇怪
怎会拿错呢?

tsaiwn 发表于 2015-5-1 00:33:04

armray 发表于 2015-4-30 13:29 static/image/common/back.gif
好吧,没有耽误你正事就好。编程菜鸟,没有区分过object和class,,几个语言都学混了,都不精。

把 MPU6050.h 和 MPU6050.cpp 改为如下看看//MPU6050.h
#ifndef MPU6050_H
#define MPU6050_H

#if defined(ARDUINO) && ARDUINO >= 100
      #include "Arduino.h"
#else
      #include "WProgram.h"
#endif
#include"DataBuffer.h"

#define MPU6050_ACCEL_XOUT_H 0x3B
#define MPU6050_PWR_MGMT_1 0x6B
#define MPU6050_PWR_MGMT_2 0x6C
#define MPU6050_WHO_AM_I 0x75
#define MPU6050_I2C_ADDRESS 0x68

class MPU6050{
      public:
                MPU6050();
                void readFromSensor(DataBuffer * db);
                int MPU6050_read(int start);
                int MPU6050_write_reg(int reg, uint8_t *data);
                typedef union accel_t_gyro_union {
                        struct {
                        uint8_t x_accel_h;
                        uint8_t x_accel_l;
                        uint8_t y_accel_h;
                        uint8_t y_accel_l;
                        uint8_t z_accel_h;
                        uint8_t z_accel_l;
                        uint8_t t_h;
                        uint8_t t_l;
                        uint8_t x_gyro_h;
                        uint8_t x_gyro_l;
                        uint8_t y_gyro_h;
                        uint8_t y_gyro_l;
                        uint8_t z_gyro_h;
                        uint8_t z_gyro_l;
                        } reg;
                        uint8_t buffer;
                        struct {
                        int x_accel;
                        int y_accel;
                        int z_accel;
                        int temperature;
                        int x_gyro;
                        int y_gyro;
                        int z_gyro;
                        } value;
                };
      accel_t_gyro_union accel_t_gyro;

};
#endif
//MPU6050.cpp
#include"MPU6050.h"
#include"DataBuffer.h"
#include <math.h>
#include <Wire.h>
#include <SoftwareSerial.h>
MPU6050::MPU6050(){

};
int MPU6050::MPU6050_read(int start)
{b
      int i, n;
      int size = sizeof(accel_t_gyro);
      Wire.begin();
      Wire.beginTransmission(MPU6050_I2C_ADDRESS);

      n = Wire.write(start);
      if (n != 1)
                return (-10);

      n = Wire.endTransmission(false);
      if (n != 0)
                return (n);

      // Third parameter is true: relase I2C-bus after data is read.
      Wire.requestFrom(MPU6050_I2C_ADDRESS, size, true);
      i = 0;
      while(Wire.available() && i<size)
      {
          accel_t_gyro.buffer=Wire.read();
      }               
      if ( i != size)
                return (-11);
      return (0);
}
void MPU6050::readFromSensor(DataBuffer * db) {

      int error;
      error = MPU6050_read (MPU6050_ACCEL_XOUT_H);
      if(error != 0) {
                Serial.print(F("Read accel, temp and gyro, error = "));
                Serial.println(error,DEC);
      }
      uint8_t swap;
      #define SWAP(x,y) swap = x; x = y; y = swap//这一大段其实并没有用到,,也没有传给蓝牙
      SWAP (accel_t_gyro.reg.x_accel_h, accel_t_gyro.reg.x_accel_l);
      SWAP (accel_t_gyro.reg.y_accel_h, accel_t_gyro.reg.y_accel_l);
      SWAP (accel_t_gyro.reg.z_accel_h, accel_t_gyro.reg.z_accel_l);
      SWAP (accel_t_gyro.reg.t_h, accel_t_gyro.reg.t_l);
      SWAP (accel_t_gyro.reg.x_gyro_h, accel_t_gyro.reg.x_gyro_l);
      SWAP (accel_t_gyro.reg.y_gyro_h, accel_t_gyro.reg.y_gyro_l);
      SWAP (accel_t_gyro.reg.z_gyro_h, accel_t_gyro.reg.z_gyro_l);

      Serial.print(F("accel x,y,z: "));
      Serial.print(accel_t_gyro.value.x_accel, DEC);
      Serial.print(F(", "));
      Serial.print(accel_t_gyro.value.y_accel, DEC);
      Serial.print(F(", "));
      Serial.print(accel_t_gyro.value.z_accel, DEC);
      Serial.print(F(", at "));
      Serial.print(db->Index);
      Serial.println(F(""));

    if((db->Index) < (db->BUFFER_SIZE) && (db->Index) > 1) {
                int tempX = accel_t_gyro.value.x_accel;
                int tempY = accel_t_gyro.value.y_accel;
                int tempZ = accel_t_gyro.value.z_accel;

                char temp = (char)(tempX >> 8);
                if(temp == 0x00)
                        temp = 0x7f;
                db->aAccelBuffer = temp;
                db->Index++;
                temp = (char)(tempX);
                if(temp == 0x00)
                        temp = 0x01;
                db->aAccelBuffer = temp;
                db->Index++;

                temp = (char)(tempY >> 8);
                if(temp == 0x00)
                        temp = 0x7f;
                db->aAccelBuffer = temp;
                db->Index++;
                temp = (char)(tempY);
                if(temp == 0x00)
                temp = 0x01;
                db->aAccelBuffer = temp;
                db->Index++;

                temp = (char)(tempZ >> 8);
                if(temp == 0x00)
                        temp = 0x7f;
                db->aAccelBuffer = temp;
                db->Index++;
                temp = (char)(tempZ);
                if(temp == 0x00)
                        temp = 0x01;
                db->aAccelBuffer = temp;
                db->Index++;
    }
}
int MPU6050::MPU6050_write_reg(int reg, uint8_t *data)
{
      int error,n;
      Wire.beginTransmission(MPU6050_I2C_ADDRESS);

      n = Wire.write(reg);
      if (n != 1)
                {error=-20;return (error);}

      n = Wire.write(data, 1);
      if (n != 1)
                {error=-21;return (error);}

      error = Wire.endTransmission(true);
      if (error != 0)
                return (error);
      return (error);
}

armray 发表于 2015-5-1 10:18:35

tsaiwn 发表于 2015-5-1 00:13 static/image/common/back.gif
看起来应该是以下
error = MPU6050_read (MPU6050_ACCEL_XOUT_H, (uint8_t *) &accel_t_gyro, sizeof( ...

先不说存储的问题,我用serial.println(wire.read());都是错的呢

armray 发表于 2015-5-1 10:47:44

tsaiwn 发表于 2015-5-1 00:33 static/image/common/back.gif
把 MPU6050.h 和 MPU6050.cpp 改为如下看看

果然是不行的。先抛开存储不谈吧,因为我用Serial.print(Wire.read())发现Wire.read()读取的信息一直都是错的。
MPU6050_read()在setup中读取MPU6050_PWR_MGMT_1这些信息是对的,说明MPU6050_read()函数又没有错。
这说明是调用问题,而我将readFromsensor()放在setup中调用,只运行一次,这样读取的数据也是错的。
我将MPU6050_read()合并到readFromsensor中,还是不对。

由此,在setup中调用是对的,所以我消除了第二次调用和在setup中调用差异问题,仍然有错。就是两次几乎一样的操作,第二次调用就是错的。真是无计可施。

tsaiwn 发表于 2015-5-1 14:43:33

armray 发表于 2015-5-1 10:47 static/image/common/back.gif
果然是不行的。先抛开存储不谈吧,因为我用Serial.print(Wire.read())发现Wire.read()读取的信息一直都 ...

那请你在 void loop( ) { 内的一开始加入这句看看:
void loop( ) {
   static MPU6050mpu6050;
   //...

其他都不要改, 测试看看

armray 发表于 2015-5-1 14:55:57

tsaiwn 发表于 2015-5-1 00:33 static/image/common/back.gif
把 MPU6050.h 和 MPU6050.cpp 改为如下看看

问题解决了,第一时间就赶来告诉你,是一个很白痴的问题,不是wire、对象调用这些问题。
单文件中申明这个函数唤醒传感器:int MPU6050_write_reg(int reg, uint8_t data)
                     调用它时是这样的:MPU6050_write_reg (MPU6050_PWR_MGMT_1, 0);

我的多文件中唤醒传感器也是这样的:int MPU6050::MPU6050_write_reg(int reg, uint8_t *data)
                      调用它时也是这样的:MPU6050_write_reg (MPU6050_PWR_MGMT_1, 0);

我把0值传给指针data,编译并没有出错,但却没有将0值写入寄存器,也就是传感器还在休眠状态,当然全是0值了。

传感器中的寄存器参数应该没有多少人记得住,都是用的时候才去查看产品手册的,你应该也忘了。
打扰你多次却得到一个不是问题的问题,不过从你改动的代码中也让我学到不少Arduino编程方法。

最后问一下,在MPU6050.h中申明的联合体中有两个结构体,其中两个结构体大小都是14字节,用sizeof(accel_t_gyro_union)得到的也是14(根据对齐原则,我知道14是正确的),这样我每次用wire.read读取14个值存入时怎么把这个联合体存得满呢(这个联合体要28个字节才能存满吧)?既然存不满,,最后读取value结构体中怎么会有值呢?
typedef union accel_t_gyro_union {
                        struct {
                        uint8_t x_accel_h;
                        uint8_t x_accel_l;
                        uint8_t y_accel_h;
                        uint8_t y_accel_l;
                        uint8_t z_accel_h;
                        uint8_t z_accel_l;
                        uint8_t t_h;
                        uint8_t t_l;
                        uint8_t x_gyro_h;
                        uint8_t x_gyro_l;
                        uint8_t y_gyro_h;
                        uint8_t y_gyro_l;
                        uint8_t z_gyro_h;
                        uint8_t z_gyro_l;
                        } reg;

                        struct {
                        int x_accel;
                        int y_accel;
                        int z_accel;
                        int temperature;
                        int x_gyro;
                        int y_gyro;
                        int z_gyro;
                        } value;
                };

tsaiwn 发表于 2015-5-1 17:33:15

armray 发表于 2015-5-1 14:55 static/image/common/back.gif
问题解决了,第一时间就赶来告诉你,是一个很白痴的问题,不是wire、对象调用这些问题。
单文件中申明这 ...

联合体(union)的真正位置是以其内各项目中最长的为准,
因为里面每个项目都是迭起来的,
并不是串接一起!
这是 union 与 struct 最大的差别!
就是说..
在 struct 内的各项是串接
但在 union 内的各项都是同样的起点 !

tsaiwn 发表于 2015-5-1 17:44:02

armray 发表于 2015-5-1 14:55 static/image/common/back.gif
问题解决了,第一时间就赶来告诉你,是一个很白痴的问题,不是wire、对象调用这些问题。
单文件中申明这 ...

关于联合体, 补充说明..
例如:

               typedef union accel_t_gyro_union {
                        struct {
                        uint8_t x_accel_h;
                        uint8_t x_accel_l;
                        uint8_t y_accel_h;
                        uint8_t y_accel_l;
                        uint8_t z_accel_h;
                        uint8_t z_accel_l;
                        uint8_t t_h;
                        uint8_t t_l;
                        uint8_t x_gyro_h;
                        uint8_t x_gyro_l;
                        uint8_t y_gyro_h;
                        uint8_t y_gyro_l;
                        uint8_t z_gyro_h;
                        uint8_t z_gyro_l;
                        } reg;
                        int xxx;
                        byte x;
                        float ff;
                        int kk;
                     /////
                        struct {
                        int x_accel;
                        int y_accel;
                        int z_accel;
                        int temperature;
                        int x_gyro;
                        int y_gyro;
                        int z_gyro;
                        } value;
                };
又假设你写如下:
    accel_t_gyro_unionggyy;

则 sizeof(ggyy) 就是 20
因为里面最长的项目是 byte x;
然后 ggyy.xxx 其实就是 ggyy.x 和 ggyy.x 合起来,
同时 ggyy.xxx 也就是完全与 ggyy.value.x_accel 是占用同样的位置(内存);
同时 ggyy.xxx 与 ggyy.kk 也用同样的位置 (2 bytes), 当然也与 ggyy.value.x_accel 同样位置
还有, ggyy.x就是 ggyy.reg.x_accel_h;
      ggyy.x就是 ggyy.reg.x_accel_l;

至于 ggyy.ff 用 4 bytes:ggyy.x, ggyy.x, ggyy.x, ggyy.x
该四个 byte 同时也被 ggyy.kk 和 ggyy.kk 占用
   也是 ggyy.value.x_accel; 和 ggyy.value.y_accel;

其他以此类推

armray 发表于 2015-5-2 00:03:03

tsaiwn 发表于 2015-5-1 17:44 static/image/common/back.gif
关于联合体, 补充说明..
例如:



也看了几个结构体中的对齐原则、最小公倍数原则,但都没你说得细致
,大概懂得了,就是占用空间统共是20,,但是同一个空间可以用不同的名字来访问,
,可以用不同的名字来更改同一个空间的存储值,,是吧。
感觉这样的话,我用ggyy.x对空间进行赋值后,是不是会影响ggyyx.ff中的值?
我回头我编程试试,晚安:)

tsaiwn 发表于 2015-5-2 00:39:42

armray 发表于 2015-5-2 00:03 static/image/common/back.gif
也看了几个结构体中的对齐原则、最小公倍数原则,但都没你说得细致
,大概懂得了,就是占用空间统共是20 ...

完全正确
你原先使用的那个 accel_t_gyro_union
就是因为 MPU6050 会吐出 14 bytes
每 2 bytes 为 一个 int,
可是因为每个 int 的 2 个 byte 是左右颠倒的,
所以先把每两个 byte 左右对调 swap
然后再把全部看作七个 int 拿来用

tsaiwn 发表于 2015-5-2 00:48:41

armray 发表于 2015-5-2 00:03 static/image/common/back.gif
也看了几个结构体中的对齐原则、最小公倍数原则,但都没你说得细致
,大概懂得了,就是占用空间统共是20 ...

补充一下
为何 MPU 的每个 int 会左右对调呢?
其实这与 CPU 有关,
全世界的 CPU/MCU 分为两派:
   BigEndian vs. LittleEndian
(1)Little Endian:
   High byte at high address
(2)Big Endian
   High byte at Low address
假设有个 2 byte 的 int 占用 2 个 address:
address    内含
    100      0x23
    101      0x58
这样, 请问在 address 100 的这个 int 是 0x2358 还是 0x5823 ?
请注意, 虽然这 int 占用 2 bytes,
我们只会说在 address 100 的那个 int,
不会说在 address 100 以及address 101 的那个 int !!!
Intel CPU 用 Little Endian, 所以会说该 int 是 0x5823
但 IBM, 以前 HP, 以前 SUN, 和几乎全部大计算机的 CPU,
以及摩托罗拉 等等厂商的 CPU 都是用 Big Endian, 所以会说该int是 0x2358
详细请自己百度一下 "BigEndian vs. LittleEndian"
页: 1 [2]
查看完整版本: 思考了一晚上不知道为什么,求助论坛大神,关于Arduino中的wire