jrowberg / i2cdevlib

I2C device library collection for AVR/Arduino or other C++-based MCUs
http://www.i2cdevlib.com
3.94k stars 7.51k forks source link

Resetting the DMP code in MPU6050 doesn't work #372

Open echoGee opened 6 years ago

echoGee commented 6 years ago

SOFTWARE modification

Code https://github.com/jrowberg/i2cdevlib/blob/3dc9538074b88393a125d6ef8a198e2b7870ddb8/Arduino/MPU6050/MPU6050_6Axis_MotionApps20.h#L325-L332 changed to

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

    DEBUG_PRINTLN(F("Resetting DMP..."));
    resetDMP();
    // enable sleep mode and wake cycle
    /*Serial.println(F("Enabling sleep mode..."));

HARDWARE

Connect as follows ESP32 DoIT devkit connected to GY 521 ESP32 GY-521 VIN <=> VCC 22 <=> SCL 21 <=> SDA GND <=> AD0 INT <=> VP

STEPS TO REPRODUCE

I am using the MPU6050_DMP6.ino file and following these steps to reproduce the problem.

  1. Run the code. See serial.print of whichever data requested
  2. Reset the ESP32 using reset button (EN) on the DoIT devkit
  3. The code reruns again, but with the following error (indicating that DMP was inaccessible?). Ideally, the DMP should have been reset to a fresh state. Only a power cycle of the MPU6050 solves this problem.

Initializing I2C devices... Testing device connections... MPU6050 connection successful Send any character to begin DMP programming and demo: Initializing DMP... Resetting MPU6050... Resetting DMP... Disabling sleep mode... Selecting user bank 16... Selecting memory byte 6... Checking hardware revision... Revision @ user[16][6] = 4D Resetting memory bank selection to 0... Reading OTP bank valid flag... OTP bank is invalid! Reading gyro offset TC values... X gyro offset = 63 Y gyro offset = 0 Z gyro offset = 0 Setting slave 0 address to 0x7F... Disabling I2C Master mode... Setting slave 0 address to 0x68 (self)... Resetting I2C Master control... Writing DMP code to MPU memory banks (1929 bytes) ERROR! DMP code verification failed. DMP Initialization failed (code 1)

ahmadSum1 commented 6 years ago

facing the same problem with esp8266(NodeMCU1.0 esp-12e ). I have tested with a GY88 and a GY521, same problem. Like you mentioned, only a power cycle solves it once I start getting the "DMP Initialization failed (code 1)"

cocoakang commented 4 years ago

I encountered this problem also, and I found a way to solve that. As the example code says, first we call mpu.initialize(); Then dmpInitialize() is called with NO DELAY. If you add some delay between these two lines, all goes well. I think that because internal initialization hasn't been finished, i2c has no right to write anything to mpu6050. The duration is about 3e-3~1s. Later I will figure that more.

Hope this can help you. @ahmadSum1 @echoGee

abrahmx commented 3 years ago

I encountered this problem also, and I found a way to solve that. As the example code says, first we call mpu.initialize(); Then dmpInitialize() is called with NO DELAY. If you add some delay between these two lines, all goes well. I think that because internal initialization hasn't been finished, i2c has no right to write anything to mpu6050. The duration is about 3e-3~1s. Later I will figure that more.

Hope this can help you. @ahmadSum1 @echoGee

Thank you! This helped me to solve my issue!! Just put a 2s delay before "mpu.dmpInitialize();"

cocoakang commented 3 years ago

I encountered this problem also, and I found a way to solve that. As the example code says, first we call mpu.initialize(); Then dmpInitialize() is called with NO DELAY. If you add some delay between these two lines, all goes well. I think that because internal initialization hasn't been finished, i2c has no right to write anything to mpu6050. The duration is about 3e-3~1s. Later I will figure that more. Hope this can help you. @ahmadSum1 @echoGee

Thank you! This helped me to solve my issue!! Just put a 2s delay before "mpu.dmpInitialize();"

HaHa. Glad to hear it helps!

stanislawix commented 2 years ago

I encountered this problem also, and I found a way to solve that. As the example code says, first we call mpu.initialize(); Then dmpInitialize() is called with NO DELAY. If you add some delay between these two lines, all goes well. I think that because internal initialization hasn't been finished, i2c has no right to write anything to mpu6050. The duration is about 3e-3~1s. Later I will figure that more.

Hope this can help you. @ahmadSum1 @echoGee

who the fuck tells a range in such an illegible way

cocoakang commented 2 years ago

I encountered this problem also, and I found a way to solve that. As the example code says, first we call mpu.initialize(); Then dmpInitialize() is called with NO DELAY. If you add some delay between these two lines, all goes well. I think that because internal initialization hasn't been finished, i2c has no right to write anything to mpu6050. The duration is about 3e-3~1s. Later I will figure that more. Hope this can help you. @ahmadSum1 @echoGee

who the fuck tells a range in such an illegible way

Be polite.

ZHomeSlice commented 2 years ago

@cocoakang @ahmadSum1 @echoGee Yes, a delay is required.

Per MPU-6000/MPU-6050 Register Map and Descriptions page 41 The proper reset sequence is Reset Device wait 100ms Reset gyro, accel, temp signal paths wait 100ms This is the Macro I use with Simple_MPU6050

#define PWR_MGMT_1_WRITE_DEVICE_RESET(...) MPUi2cWrite(0x6B, 1, 7, (uint8_t)1);delay(100);MPUi2cWrite(0x6A, 3, 2, (uint8_t)0b111);delay(100);

Convert it to Jeffs Library

writeBits(devAddr,0x6B,7,1, (uint8_t)1); // Bit 7 : PWR_MGMT_1  --> Device Reset
delay(100);
writeBits(devAddr,0x6A,2,3, (uint8_t)0b111); // Bits 2,1,0 : FIFO Reset , USER_CTRL --> I2C_MST Reset , SIG_COND Reset  
delay(100);  

Some cleanup will be necessary to directly use this. as it is just a quick example Hope this helps :)

ZHomeSlice

stanislawix commented 2 years ago

@cocoakang @ahmadSum1 @echoGee Yes, a delay is required.

Per MPU-6000/MPU-6050 Register Map and Descriptions page 41 The proper reset sequence is Reset Device wait 100ms Reset gyro, accel, temp signal paths wait 100ms This is the Macro I use with Simple_MPU6050

#define PWR_MGMT_1_WRITE_DEVICE_RESET(...) MPUi2cWrite(0x6B, 1, 7, (uint8_t)1);delay(100);MPUi2cWrite(0x6A, 3, 2, (uint8_t)0b111);delay(100);

Convert it to Jeffs Library

writeBits(devAddr,0x6B,7,1, (uint8_t)1); // Bit 7 : PWR_MGMT_1  --> Device Reset
delay(100);
writeBits(devAddr,0x6A,2,3, (uint8_t)0b111); // Bits 2,1,0 : FIFO Reset , USER_CTRL --> I2C_MST Reset , SIG_COND Reset  
delay(100);  

Some cleanup will be necessary to directly use this. as it is just a quick example Hope this helps :)

ZHomeSlice

Thanks for your contribution!