Hi,
For starters, I'm using:
-Seeeduino Mega
-Sparkfun MPU-6050 breakout boardhttps://www.sparkfun.com/products/11028
-Jeff Rowbergs library for the mpu-6050https://github.com/jrowberg/i2cdevlib/blob/master/Arduino/I2Cdev/I2Cdev.cpp
With the example code MPU6050_DMP6, the measurements are really good, but the duino periodically freezes. I tracked this down through the libraries and it invariably leads (through different ways) to a Wire.endTransmission command in the i2cdev library (line 295), in the call to I2Cdev::readBytes(). Here is the relevant code:
int8_t count = 0;
uint32_t t1 = millis();
Serial.println("ARDUINO > 100");
// Arduino v1.0.1+, Wire library
// Adds official support for repeated start condition, yay!
// I2C/TWI subsystem uses internal buffer that breaks with large data requests
// so if user requests more than BUFFER_LENGTH bytes, we have to do it in
// smaller chunks instead of all at once
for (uint8_t k = 0; k < length; k += min(length, BUFFER_LENGTH)) {
Wire.beginTransmission(devAddr);
Wire.write(regAddr);
Wire.endTransmission();
Wire.beginTransmission(devAddr);
Wire.requestFrom(devAddr, (uint8_t)min(length - k, BUFFER_LENGTH));
for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) {
data[count] = Wire.read();
#ifdef I2CDEV_SERIAL_DEBUG
Serial.print(data[count], HEX);
if (count + 1 < length) Serial.print(" ");
#endif
}
Serial.println("ending transmission");
Wire.endTransmission();
Serial.println("ended Transmission");
}
#endif
I found this: http://letsmakerobots.com/node/28941
Where a suggestion is that the hardware buffer is overflowing, but as far as I can tell Jeff's code is handling for that. Coming from a mech background, I'm a bit stumped on how to solve this...
Anybody have this, or a similar problem (or better yet solution)?
Ok, I commented out the last Wire.beginTransmission and Wire.endTransmission, like so:
// Arduino v1.0.1+, Wire library
// Adds official support for repeated start condition, yay!
// I2C/TWI subsystem uses internal buffer that breaks with large data requests
// so if user requests more than BUFFER_LENGTH bytes, we have to do it in
// smaller chunks instead of all at once
for (uint8_t k = 0; k < length; k += min(length, BUFFER_LENGTH)) {
Wire.beginTransmission(devAddr);
Wire.write(regAddr); Serial.println("wrote");
Wire.endTransmission(); Serial.println("ended");
// Wire.beginTransmission(devAddr); //THIS OUT
Wire.requestFrom(devAddr, (uint8_t)min(length - k, BUFFER_LENGTH)); Serial.println("requested");
for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) {
data[count] = Wire.read();
#ifdef I2CDEV_SERIAL_DEBUG
Serial.print(data[count], HEX);
if (count + 1 < length) Serial.print(" ");
#endif
}
// Wire.endTransmission(); //THIS OUT
}
From what I got from your site, startTransmission is prepping to write, and requestFrom blocks it to read. Between the Wire.startTransmission and Wire.endTransmission there is no Wire.write, so as far as I can tell, it's not doing anything at all and taking them out shouldn't do anything.
Now however it freezes with the Wire.requestFrom() call.
(note, it will running for a while without problems before freezing, but it always freezes there).
Ok, from what I can tell, that loop is to avoid an infinite loop.
By default timeout is set to 1000 ms. t1 is the time taken with millis() at the beginning of the method. count is initialized as 0 at the beginning of the method.
instead of that for loop. That's what you meant right?
However this way doesn't work: the sensor doesn't even initialize. Sorry, not too familiar with this... I'll update if I get something working in the meantime.
I don't understand this. You want some data from the thing you are talking to. That thing should have some way of determining how much data it will return per request. You seem to be trying to get just enough not to overflow some buffer. Why?
// I2C/TWI subsystem uses internal buffer that breaks with large data requests
// so if user requests more than BUFFER_LENGTH bytes, we have to do it in
// smaller chunks instead of all at once
Well, what is BUFFER_LENGTH? Pity the whole sketch isn't there. The I2C buffer is 32 bytes. It's hard to imagine getting data from an accelerometer needing more than 32 bytes in one hit.
Assuming for a moment BUFFER_LENGTH is the I2C buffer length (32), why are you requesting 32 bytes? You should be requesting the number of bytes you are expecting. Then requestFrom returns when they are in the buffer, or a NAK occurs in advance of that.
Hi,
Yup, I'm a bit out of my depth here. I didn't post the entire code because it would include sketch+2 libraries, but their all in the link. Here they are:
is doing: Every time it does Wire.read(), Wire.available will be reduced by one, until it returns 0 (everything has been read), and so it exits the loop.