Code stops after 1129 iterations

04 Mar 2013

Hi there,

I am trying to use a Sparkfun MPU6050 breakout board and using the following code:

#include "mbed.h"
#include "MPU6050.h"

DigitalOut myled(LED1);
Serial pc(USBTX, USBRX);
MPU6050 mpu;

int16_t ax, ay, az;
int16_t gx, gy, gz;

int main()
{
    pc.printf("MPU6050 test\n\n");
    pc.printf("MPU6050 initialize \n");

    mpu.initialize();
    pc.printf("MPU6050 testConnection \n");

    bool mpu6050TestResult = mpu.testConnection();
    if(mpu6050TestResult) {
        pc.printf("MPU6050 test passed \n");
    } else {
        pc.printf("MPU6050 test failed \n");
    }
   
    while(1) {
        //wait(1);
        mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
        //writing current accelerometer and gyro position 
        pc.printf("%d;%d;%d;%d;%d;%d\n",ax,ay,az,gx,gy,gz);
    }
}

Along with this, using the libraries found here:

http://mbed.org/users/garfieldsg/code/mpu6050_test/

Unfortunatley, this code stops running after 1129 I2C reads. As far as I could tell, the code stops in the I2Cdev.cpp file at line 140,

i2c.read(devAddr<<1, redData, length);

Does anyone know a fix for this? I think it has something to do with the mbed's memory, but I'm relatively new to the mbed so I'm not exactly sure.

The board is wired correctly, all pull up resistors etc are in place.

Any help would be greatly appreciated!

05 Mar 2013

It does looks like I2Cdev::readBytes is leaking memory that it mallocs.

int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout)
{
    char command[1];
    command[0] = regAddr;
    char *redData = (char*)malloc(length);
    i2c.write(devAddr<<1, command, 1, true);
    i2c.read(devAddr<<1, redData, length);
    for(int i =0; i < length; i++) {
        data[i] = redData[i];
    }
    return length;
}

I don't even know why it needs to allocate and use this redData buffer. Can the code be refactored to look like this?

int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout)
{
    i2c.write(devAddr<<1, &regAddr, sizeof(regAddr), true);
    i2c.read(devAddr<<1, data, length);
    return length;
}
25 Apr 2013

I have the same problem as Stephen.I tried to make a new method and keep the old one. I tried Adam's solution and i got the following error:

Quote:

"no instance of overloaded function "mbed::I2C::read" matches the argument list" in file "MPU6050I2Cdev.cpp", Line: 145, Col: 34

Header declaration

int8_t readBytes2(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout());

Cpp definition

int8_t I2Cdev::readBytes2(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout)
{
    i2c.write(devAddr<<1, &regAddr, sizeof(regAddr), true);
    i2c.read(devAddr<<1, data, length);
    return length;
}
25 Apr 2013

Try adding (char*) in front of data. That explicitly converts it from uint8_t pointer to a char pointer. Effectively the same, but then it should recognize it.

25 Apr 2013

Thanks Erick, it worked for i2c.read :)

I also have the same error on i2c.write line. Probably from the same reason. I tried there also a cast to (char*). Now the code is compiling and I manage to get continuous data from sensor on accelerometer. From the Gyro all I get is 0 0 0 now. Before this 2 modifications I managed to get data from both, gyro and accelerometer.

The data I get with a 0.01s delay in main loop :

after_editing wrote:

11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -11600;10040;3128;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0 -10400;9660;5012;0;0;0

before_editing': wrote:

8136;2232;13428;-228;10;-367 8232;2320;13448;-272;47;-385 8244;2188;13388;-289;28;-373 8368;2256;13444;-272;49;-364 8276;2252;13364;-248;22;-341 8344;2224;13220;-240;0;-384 8196;2244;13412;-254;-14;-341 8244;2224;13436;-271;61;-334 8216;2240;13456;-241;-1;-345 8260;2204;13328;-261;-8;-369 8248;2240;13404;-220;22;-373 8308;2228;13328;-248;-7;-358 8268;2240;13432;-238;18;-355 8184;2252;13256;-254;30;-353 8252;2152;13384;-232;41;-353 8304;2228;13244;-257;-12;-335 8260;2244;13480;-249;18;-357 8260;2272;13364;-245;26;-352 8184;2220;13412;-250;-11;-334 8284;2248;13396;-247;12;-331 8288;2156;13284;-237;3;-340 8232;2280;13432;-247;-4;-347 8328;2180;13316;-249;4;-345 8192;2232;13360;-234;8;-355 8176;2316;13400;-241;10;-356 8212;2264;13428;-226;9;-360 8240;2256;13464;-230;6;-325

readByets Definition

int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout)
{
    i2c.write(devAddr<<1, (char*)&regAddr, sizeof(regAddr), true);
    i2c.read(devAddr<<1, (char*)data, length);
    return length;
}

I think it's somthing wrong in i2c.write line, can you help me pls? :D

25 Apr 2013

Your data from your accelerometer seems kinda constant also (it changes, but not as much as you would think). Wouldn't know exactly what is going wrong with that. Maybe I check later with my MPU6050, but no promises there ;). For sure I don't understand why they would use the sizeof command there, why not just put it on one? Although it should also work.

What you could also use is library I once made: http://mbed.org/users/Sissors/code/MPU6050/. Yeah it kinda lacks an example program (although it should be quite simple to use), and it was pretty much the first library I ever made, but it does support the basic stuff you probably will need: testing connection, getting data, setting bandwidth/range, and I am fairly certain there is no memory leak in it :P.

26 Aug 2013

A bit late to this, but it may help someone else. Quick and dirty fix is to add before the return statement free(redData)

or just read straight into data and get rid of the redData stuff altogther.

or am I missing some obvious reason why thats not a good plan :-), if so please let me know.

26 Aug 2013

This solved the problem for me, works fine now. Thanks