0

I have Arduino Code that utilizes the I2CDev library to control an MPU-6050. I am pretty new to coding and copied and pasted most of the code from examples I have found around. I am starting to run out of programming space on my Arduino, and I have found that one line of the code takes up 21%, or 6000 bytes of the programming memory. I found the function that the line related to and I have it shown below.

The link to the I2CDev libarary can be found on Github here as well: https://github.com/jrowberg/i2cdevlib

Is there a way to decrease it? Ot can someone explain to me why it is taking up so much space? Thanks!

uint8_t MPU6050::dmpInitialize() {
// reset device
DEBUG_PRINTLN(F("\n\nResetting MPU6050..."));
reset();
delay(30); // wait after reset

// enable sleep mode and wake cycle
/*Serial.println(F("Enabling sleep mode..."));
setSleepEnabled(true);
Serial.println(F("Enabling wake cycle..."));
setWakeCycleEnabled(true);*/

// disable sleep mode
DEBUG_PRINTLN(F("Disabling sleep mode..."));
setSleepEnabled(false);

// get MPU hardware revision
DEBUG_PRINTLN(F("Selecting user bank 16..."));
setMemoryBank(0x10, true, true);
DEBUG_PRINTLN(F("Selecting memory byte 6..."));
setMemoryStartAddress(0x06);
DEBUG_PRINTLN(F("Checking hardware revision..."));
DEBUG_PRINT(F("Revision @ user[16][6] = "));
DEBUG_PRINTLNF(readMemoryByte(), HEX);
DEBUG_PRINTLN(F("Resetting memory bank selection to 0..."));
setMemoryBank(0, false, false);

// check OTP bank valid
DEBUG_PRINTLN(F("Reading OTP bank valid flag..."));
DEBUG_PRINT(F("OTP bank is "));
DEBUG_PRINTLN(getOTPBankValid() ? F("valid!") : F("invalid!"));

// get X/Y/Z gyro offsets
DEBUG_PRINTLN(F("Reading gyro offset TC values..."));
int8_t xgOffsetTC = getXGyroOffsetTC();
int8_t ygOffsetTC = getYGyroOffsetTC();
int8_t zgOffsetTC = getZGyroOffsetTC();
DEBUG_PRINT(F("X gyro offset = "));
DEBUG_PRINTLN(xgOffsetTC);
DEBUG_PRINT(F("Y gyro offset = "));
DEBUG_PRINTLN(ygOffsetTC);
DEBUG_PRINT(F("Z gyro offset = "));
DEBUG_PRINTLN(zgOffsetTC);

// setup weird slave stuff (?)
DEBUG_PRINTLN(F("Setting slave 0 address to 0x7F..."));
setSlaveAddress(0, 0x7F);
DEBUG_PRINTLN(F("Disabling I2C Master mode..."));
setI2CMasterModeEnabled(false);
DEBUG_PRINTLN(F("Setting slave 0 address to 0x68 (self)..."));
setSlaveAddress(0, 0x68);
DEBUG_PRINTLN(F("Resetting I2C Master control..."));
resetI2CMaster();
delay(20);

// load DMP code into memory banks
DEBUG_PRINT(F("Writing DMP code to MPU memory banks ("));
DEBUG_PRINT(MPU6050_DMP_CODE_SIZE);
DEBUG_PRINTLN(F(" bytes)"));
if (writeProgMemoryBlock(dmpMemory, MPU6050_DMP_CODE_SIZE)) {
    DEBUG_PRINTLN(F("Success! DMP code written and verified."));

    // write DMP configuration
    DEBUG_PRINT(F("Writing DMP configuration to MPU memory banks ("));
    DEBUG_PRINT(MPU6050_DMP_CONFIG_SIZE);
    DEBUG_PRINTLN(F(" bytes in config def)"));
    if (writeProgDMPConfigurationSet(dmpConfig, MPU6050_DMP_CONFIG_SIZE)) {
        DEBUG_PRINTLN(F("Success! DMP configuration written and verified."));

        DEBUG_PRINTLN(F("Setting clock source to Z Gyro..."));
        setClockSource(MPU6050_CLOCK_PLL_ZGYRO);

        DEBUG_PRINTLN(F("Setting DMP and FIFO_OFLOW interrupts enabled..."));
        setIntEnabled(0x12);

        DEBUG_PRINTLN(F("Setting sample rate to 200Hz..."));
        setRate(4); // 1khz / (1 + 4) = 200 Hz

        DEBUG_PRINTLN(F("Setting external frame sync to TEMP_OUT_L[0]..."));
        setExternalFrameSync(MPU6050_EXT_SYNC_TEMP_OUT_L);

        DEBUG_PRINTLN(F("Setting DLPF bandwidth to 42Hz..."));
        setDLPFMode(MPU6050_DLPF_BW_42);

        DEBUG_PRINTLN(F("Setting gyro sensitivity to +/- 2000 deg/sec..."));
        setFullScaleGyroRange(MPU6050_GYRO_FS_2000);

        DEBUG_PRINTLN(F("Setting DMP programm start address"));
        //write start address MSB into register
        setDMPConfig1(0x03);
        //write start address LSB into register
        setDMPConfig2(0x00);

        DEBUG_PRINTLN(F("Clearing OTP Bank flag..."));
        setOTPBankValid(false);

        DEBUG_PRINTLN(F("Setting X/Y/Z gyro offset TCs to previous values..."));
        setXGyroOffsetTC(xgOffsetTC);
        setYGyroOffsetTC(ygOffsetTC);
        setZGyroOffsetTC(zgOffsetTC);

        DEBUG_PRINTLN(F("Setting X/Y/Z gyro user offsets to zero..."));
        //setXGyroOffset(0);
        //setYGyroOffset(0);
        //setZGyroOffset(0);

        DEBUG_PRINTLN(F("Writing final memory update 1/7 (function unknown)..."));
        uint8_t dmpUpdate[16], j;
        uint16_t pos = 0;
        for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
        writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

        DEBUG_PRINTLN(F("Writing final memory update 2/7 (function unknown)..."));
        for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
        writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

        DEBUG_PRINTLN(F("Resetting FIFO..."));
        resetFIFO();

        DEBUG_PRINTLN(F("Reading FIFO count..."));
        uint16_t fifoCount = getFIFOCount();
        uint8_t fifoBuffer[128];

        DEBUG_PRINT(F("Current FIFO count="));
        DEBUG_PRINTLN(fifoCount);
        getFIFOBytes(fifoBuffer, fifoCount);

        DEBUG_PRINTLN(F("Setting motion detection threshold to 2..."));
        setMotionDetectionThreshold(2);

        DEBUG_PRINTLN(F("Setting zero-motion detection threshold to 156..."));
        setZeroMotionDetectionThreshold(156);

        DEBUG_PRINTLN(F("Setting motion detection duration to 80..."));
        setMotionDetectionDuration(80);

        DEBUG_PRINTLN(F("Setting zero-motion detection duration to 0..."));
        setZeroMotionDetectionDuration(0);

        DEBUG_PRINTLN(F("Resetting FIFO..."));
        resetFIFO();

        DEBUG_PRINTLN(F("Enabling FIFO..."));
        setFIFOEnabled(true);

        DEBUG_PRINTLN(F("Enabling DMP..."));
        setDMPEnabled(true);

        DEBUG_PRINTLN(F("Resetting DMP..."));
        resetDMP();

        DEBUG_PRINTLN(F("Writing final memory update 3/7 (function unknown)..."));
        for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
        writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

        DEBUG_PRINTLN(F("Writing final memory update 4/7 (function unknown)..."));
        for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
        writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

        DEBUG_PRINTLN(F("Writing final memory update 5/7 (function unknown)..."));
        for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
        writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

        DEBUG_PRINTLN(F("Waiting for FIFO count > 2..."));
        while ((fifoCount = getFIFOCount()) < 3);

        DEBUG_PRINT(F("Current FIFO count="));
        DEBUG_PRINTLN(fifoCount);
        DEBUG_PRINTLN(F("Reading FIFO data..."));
        getFIFOBytes(fifoBuffer, fifoCount);

        DEBUG_PRINTLN(F("Reading interrupt status..."));

        DEBUG_PRINT(F("Current interrupt status="));
        DEBUG_PRINTLNF(getIntStatus(), HEX);

        DEBUG_PRINTLN(F("Reading final memory update 6/7 (function unknown)..."));
        for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
        readMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

        DEBUG_PRINTLN(F("Waiting for FIFO count > 2..."));
        while ((fifoCount = getFIFOCount()) < 3);

        DEBUG_PRINT(F("Current FIFO count="));
        DEBUG_PRINTLN(fifoCount);

        DEBUG_PRINTLN(F("Reading FIFO data..."));
        getFIFOBytes(fifoBuffer, fifoCount);

        DEBUG_PRINTLN(F("Reading interrupt status..."));

        DEBUG_PRINT(F("Current interrupt status="));
        DEBUG_PRINTLNF(getIntStatus(), HEX);

        DEBUG_PRINTLN(F("Writing final memory update 7/7 (function unknown)..."));
        for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
        writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

        DEBUG_PRINTLN(F("DMP is good to go! Finally."));

        DEBUG_PRINTLN(F("Disabling DMP (you turn it on later)..."));
        setDMPEnabled(false);

        DEBUG_PRINTLN(F("Setting up internal 42-byte (default) DMP packet buffer..."));
        dmpPacketSize = 42;
        /*if ((dmpPacketBuffer = (uint8_t *)malloc(42)) == 0) {
            return 3; // TODO: proper error code for no memory
        }*/

        DEBUG_PRINTLN(F("Resetting FIFO and clearing INT status one last time..."));
        resetFIFO();
        getIntStatus();
    } else {
        DEBUG_PRINTLN(F("ERROR! DMP configuration verification failed."));
        return 2; // configuration block loading failed
    }
} else {
    DEBUG_PRINTLN(F("ERROR! DMP code verification failed."));
    return 1; // main binary block loading failed
}
return 0; // success

}

M.Schindler
  • 221
  • 1
  • 6

1 Answers1

0

One line of code doesn't use 6000 bytes of memory. However if it calls a function, which otherwise would not be called, then the compiler has to include the function.

So, for example, if you have a function that takes 6000 bytes, but don't call it, then the compiler can omit the function itself.


Assuming DEBUG_PRINTLN does something, then I count 2480 bytes of string literals there. Therefore your function would at the very least take up 2480 bytes. And that is called 71 times, so if DEBUG_PRINTLN takes (say) 10 bytes to call each time, that is another 710 bytes. We are already up to 3190 bytes. Other stuff (unrelated to debugging) also probably takes quite a few bytes.


I am starting to run out of programming space on my Arduino

That's not a problem until you actually run out of space. Who cares if you use 99% of available memory?


The fact that something causes a jump in memory usage is not, in itself, cause for worry. For example this sketch:

void setup() {
  Serial.begin(115200);
  int a;
  Serial.println (a);
}

void loop() {  }

Compiled for a Uno using IDE 1.6.9 I get:

Sketch uses 2,122 bytes (6%) of program storage space. Maximum is 32,256 bytes.

So, 2,122 bytes. Now change a to be float:

void setup() {
  Serial.begin(115200);
  float a;
  Serial.println (a);
}

void loop() {  }

Now it uses 3,668 bytes:

Sketch uses 3,668 bytes (11%) of program storage space. Maximum is 32,256 bytes. That's another 1,546 bytes just by changing one variable's type.

However it doesn't take another 1,546 bytes if you add a second such variable.

void setup() {
  Serial.begin(115200);
  float a;
  float b;
  Serial.println (a);
  Serial.println (b);
}

void loop() {  }

That only uses another 18 bytes:

Sketch uses 3,686 bytes (11%) of program storage space. Maximum is 32,256 bytes.

In other words, the floating-point library has now been included by the compiler. This is a once-off jump in usage. Of course, if I now do something with I2C there will be another jump as that additional library is loaded.

Nick Gammon
  • 38,901
  • 13
  • 69
  • 125