思考了一晚上不知道为什么,求助论坛大神,关于Arduino中的wire
首先我写了五个文件放在同一目录下:MPU6050.h 、MPU6050.CPP 、PASSOMETER.INO、DATABUFFER.H、DATABUFFER.H功能实现放在passometer.ino里面,其他的 当类库使用,编译通过,可以运行。
在MPU6050.CPP中有这样两个函数:MPU6050_read和readFromsensor,前一个函数在第二中得到调用。
int MPU6050::MPU6050_read(int start, uint8_t *buffer, int size)
{
int i, n;
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);
Wire.requestFrom(MPU6050_I2C_ADDRESS, size, true);
i = 0;
while(Wire.available() && i<size)
{
buffer=Wire.read();
}
if ( i != size)
return (-11);
return (0); // return : no error
}
void MPU6050::readFromSensor(DataBuffer * db) {
int error;
error = MPU6050_read (MPU6050_ACCEL_XOUT_H, (uint8_t *) &accel_t_gyro, sizeof(accel_t_gyro));
........
}
然后loop中申明了一个mpu6050的对象,循环调用了readFromsensor,是这样调用的:
mpu6050.readFromSensor(&databuffer);
按照预期,,Wire.read应该返回动态的一组数据,,可实际上wire.read每次读取到的都是同样的。
为了找到错误,我做了这样的尝试:
1、以为是buffer中存储时出错,,所以有直接让wire.read的内容输出的串口,,发现结果仍然是每次返回同样的数据。
2、用while(wire.available())wire.read();
来清空缓存,,结果失败。
新手遇到这样的问题好心塞,百度都百度不到,求好心人指点。
可能是你程序自己写错了
把以下这完整贴上来:
void MPU6050::readFromSensor(DataBuffer * db) {
int error;
error = MPU6050_read (MPU6050_ACCEL_XOUT_H, (uint8_t *) &accel_t_gyro, sizeof(accel_t_gyro));
........
}
感觉没有必要贴,,因为在readFromsensor一开始就调用了,MPU6050_read函数,,没有贴的部分都是读取后做的一些处理。现在的问题是在MPU6050里读到的数据就是不对的。我又尝试了将MPU6050_read直接合并到readFromSensor里面,失败了。。等下只能试试将函数弄到loop里面去会不会成功了。因为我是初学者,整个代码我只是把一个单文件改成了多文件的形式,,原来能运行的文件应该是对的,,所以一步步减小多文件与单文件的差异希望能找到错误。
void MPU6050::readFromSensor(DataBuffer * db) {
int error;
error = MPU6050_read (MPU6050_ACCEL_XOUT_H, (uint8_t *) &accel_t_gyro, sizeof(accel_t_gyro));
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++;
}
}
armray 发表于 2015-4-29 22:19 static/image/common/back.gif
感觉没有必要贴,,因为在readFromsensor一开始就调用了,MPU6050_read函数,,没有贴的部分都是读取后做的 ...
(1)你的以下这句写在何处 ?
accel_t_gyro_union accel_t_gyro;
(2)你的这句写在何处?
MPU6050mpu6050;
(3)麻烦把 MPU6050.h也贴上来
armray 发表于 2015-4-29 22:19 static/image/common/back.gif
感觉没有必要贴,,因为在readFromsensor一开始就调用了,MPU6050_read函数,,没有贴的部分都是读取后做的 ...
还有还有
你说在 loop ( ) 内用:
mpu6050.readFromSensor(&databuffer);
那请问这里的 databuffer 是写在何处, 以及如何写?
armray 发表于 2015-4-29 22:19 static/image/common/back.gif
感觉没有必要贴,,因为在readFromsensor一开始就调用了,MPU6050_read函数,,没有贴的部分都是读取后做的 ...
你的问题应该跟 Wire 没关系
应该是使用类库创建 "对象" 使用上的问题
例如 DataBuffer databuffer; 使用错误或写在错误的地方
还有
你说 "然后loop中申明了一个mpu6050的对象"
其实这也不应该,
如果你真的是 "在loop中申明一个mpu6050的对象"
则等于每次进入 loop 都重新创建新的 mpu6050的对象
因为, 每次离开 loop( ) { } 时在 loop( ) 中所有的变量与对象都会不见
意思是该些在 loop( ) 申明的变量与对象所占用内存都会被移除 !
tsaiwn 发表于 2015-4-29 23:35 static/image/common/back.gif
你的问题应该跟 Wire 没关系
应该是使用类库创建 "对象" 使用上的问题
例如 DataBuffer databuffer; 使 ...
哦哦,终于从wire的话题上打住了,看了下逻辑,也用你说的方法清理了缓存,应该不是wire的问题。问题应该还是在单文件到多文件的转换,就是引用对象时产生了差异,,整体的代码也不长,300行吧,我整理一下贴出来吧。
昨晚回去就睡了,才看到,既然大神都已经入局了,就麻烦再多看一下,帮我解决了问题吧,小弟不胜感激:lol //DataBuffer.h
#ifndef DataBuffer_H
#define DataBuffer_H
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
class DataBuffer{
public:
int BUFFER_SIZE;//buffer大小
int Index;//buffer已存数据位
byte aAccelBuffer;//存储单元
DataBuffer();//构造函数
void InitBuffer();//清空buffer
};
#endif
//DataBuffer.cpp
#include"DataBuffer.h"
DataBuffer::DataBuffer(){
BUFFER_SIZE=125;
Index=2;
}
void DataBuffer::InitBuffer(){
Index = 2;
for(int i=Index; i<BUFFER_SIZE; i++) {
aAccelBuffer = 0x00;
}
aAccelBuffer = 0xfe;
aAccelBuffer = 0xfd;
aAccelBuffer = 0xfd;
aAccelBuffer = 0xfe;
aAccelBuffer = 0x00;
}
//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, uint8_t *buffer, int size);
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;
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, uint8_t *buffer, int size)
{
int i, n;
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)
{
buffer=Wire.read();
}
if ( i != size)
return (-11);
return (0);
}
void MPU6050::readFromSensor(DataBuffer * db) {
int error;
error = MPU6050_read (MPU6050_ACCEL_XOUT_H, (uint8_t *) &accel_t_gyro, sizeof(accel_t_gyro));
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);
}
//main file
#include <math.h>
#include <Wire.h>
#include <SoftwareSerial.h>
#include"DataBuffer.h"
#include"MPU6050.h"
#define SENSOR_READ_INTERVAL 50 //��ȡMPU�ļ��ʱ��
unsigned long prevSensoredTime = 0;//�ϴζ�ȡʱ��
unsigned long curSensoredTime = 0;//��ǰʱ��
SoftwareSerial BTSerial(2, 3);
MPU6050mpu6050=MPU6050();
DataBuffer databuffer=DataBuffer();
void setup() {
Serial.begin(9600);
BTSerial.begin(9600);
Wire.begin();
int error;
uint8_t c;
error = mpu6050.MPU6050_read (MPU6050_WHO_AM_I, &c, 1);
Serial.print(F("WHO_AM_I : "));
Serial.print(c,HEX);
Serial.print(F(", error = "));
Serial.println(error,DEC);
error = mpu6050.MPU6050_read (MPU6050_PWR_MGMT_2, &c, 1);
Serial.print(F("PWR_MGMT_2 : "));
Serial.print(c,HEX);
Serial.print(F(", error = "));
Serial.println(error,DEC);
mpu6050.MPU6050_write_reg (MPU6050_PWR_MGMT_1, 0);
databuffer.InitBuffer();
}
void loop() {
curSensoredTime = millis();
while(Wire.available())
{Wire.read( );}
if(curSensoredTime - prevSensoredTime > SENSOR_READ_INTERVAL) {
mpu6050.readFromSensor(&databuffer);
prevSensoredTime = curSensoredTime;
if(databuffer.Index >= databuffer.BUFFER_SIZE - 3) {
sendToRemote(&databuffer);
databuffer.InitBuffer();
Serial.println("------------- Send 20 accel data to remote");
}
}
}
void sendToRemote(DataBuffer * db) {
BTSerial.write( "accel" );
BTSerial.write( (char*)(db->aAccelBuffer) );
}
tsaiwn 发表于 2015-4-29 22:53 static/image/common/back.gif
(1)你的以下这句写在何处 ?
accel_t_gyro_union accel_t_gyro;
1、accel_t_gyro_union accel_t_gyro;写在头文件里面了
2、MPU6050 mpu6050写在主文件中,但不是loop和setup中
tsaiwn 发表于 2015-4-29 23:35 static/image/common/back.gif
你的问题应该跟 Wire 没关系
应该是使用类库创建 "对象" 使用上的问题
例如 DataBuffer databuffer; 使 ...
因为在loop中要用到,对象在setup中申明的话会报“未定义对象”的错误,所以我在函数外申明了 armray 发表于 2015-4-30 10:54 static/image/common/back.gif
//DataBuffer.h
#ifndef DataBuffer_H
#define DataBuffer_H
Line 224 那句不对
MPU6050mpu6050=MPU6050();
请注意 C++ 不是 Java, 对于 class/Object 的概念与用法略有不同.
该句必须改为:
MPU6050mpu6050; // 如果是 Java 则必须写 MPU6050mpu6050 = new MPU6050( );
/// 在 C++, 这样 mpu6050 就是个可以用的 Object (对象) 了 !
另外, 以下Line 225 也不对
DataBuffer databuffer=DataBuffer();
虽然编译会过, 但是意义不同 !
必须改为
DataBuffer databuffer;
或这样也可以:
DataBuffer databuffer( );
你先改这两个看看是否问题就解决了 !?
tsaiwn 发表于 2015-4-30 11:35 static/image/common/back.gif
Line 224 那句不对
MPU6050mpu6050=MPU6050();
按照你刚才说的改了,可以运行,但输出还是一直是这样 tsaiwn 发表于 2015-4-30 11:35 static/image/common/back.gif
Line 224 那句不对
MPU6050mpu6050=MPU6050();
还有DataBuffer databuffer();这样的表达编译时通不过的哈
passometer.ino: In function 'void setup()':
passometer.ino:34:13: error: request for member 'InitBuffer' in 'databuffer', which is of non-class type 'DataBuffer()'
passometer.ino: In function 'void loop()':
passometer.ino:42:39: error: no matching function for call to 'MPU6050::readFromSensor(DataBuffer (*)())'
passometer.ino:42:39: note: candidate is:
In file included from passometer.ino:6:0:
C:\Users\rayray\AppData\Local\Temp\build1820798255905393185.tmp\MPU6050.h:21:8: note: void MPU6050::readFromSensor(DataBuffer*)
void readFromSensor(DataBuffer * db);
^
C:\Users\rayray\AppData\Local\Temp\build1820798255905393185.tmp\MPU6050.h:21:8: note: no known conversion for argument 1 from 'DataBuffer (*)()' to 'DataBuffer*'
passometer.ino:45:19: error: request for member 'Index' in 'databuffer', which is of non-class type 'DataBuffer()'
passometer.ino:45:39: error: request for member 'BUFFER_SIZE' in 'databuffer', which is of non-class type 'DataBuffer()'
passometer.ino:46:31: error: cannot convert 'DataBuffer (*)()' to 'DataBuffer*' for argument '1' to 'void sendToRemote(DataBuffer*)'
passometer.ino:47:18: error: request for member 'InitBuffer' in 'databuffer', which is of non-class type 'DataBuffer()'
编译有误。 armray 发表于 2015-4-30 12:16 static/image/common/back.gif
按照你刚才说的改了,可以运行,但输出还是一直是这样
(1) Classname objname( );这样会有问题喔?
奇怪, 难道 Arduino 的 C++ 解读 class / object 不同
(2)还是 0 ? 那我晚上再看看
tsaiwn 发表于 2015-4-30 11:35 static/image/common/back.gif
Line 224 那句不对
MPU6050mpu6050=MPU6050();
从com口传回的结果来看,用MPU6050_read在setup中执行这样的操作是正确的:
error = mpu6050.MPU6050_read (MPU6050_WHO_AM_I, &c, 1);
也就是说MPU605_read 函数本身是没有错误的;
但在readFromsensor中调用,在loop中执行就是错误的;为了消除差异,
我有试过将readFromsensor放到setup中执行,,失败;
试过将readFromsensor中的MPU6050read的调用注释掉,直接填入相关代码,,失败。
感觉最后问题的解决不是及其简单就是及其高深
页:
[1]
2