MPU6050 MPU9250 "IMU initialization unsuccessful" when SD card logging

Hi,

I’ve been trying to log kinetic information to an SD card using an MPU9250 breakout and NodeMCU (have also tried with an Arduino Nano & level shifter).

I can get both the IMU and SD card to function separately but as soon as I try to add the SD functionality, I receive the error:

Soft WDT reset <------------

ctx: cont
sp: 3ffffda0 end: 3fffffd0 offset: 01b0

stack>>>
3fffff50: 3ffee87c 00000002 3ffeee68 40205ecc
3fffff60: 3ffee87c 3ffee880 3ffeee68 40206015
3fffff70: 3ffe8a34 ffffffff 3ffeee68 4020612c
3fffff80: 0000000a 00000001 3ffeee68 40206040
3fffff90: 3ffee87c 3ffee880 3ffeee68 40206160
3fffffa0: 3fffdad0 3ffee880 3ffeee68 40202c38
3fffffb0: 3fffdad0 00000000 3ffeee9c 40206664
3fffffc0: feefeffe feefeffe 3ffe85ec 40100739
<<<stack<<<

ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
vbb28d4a3
~ld
IMU initialization unsuccessful <------------
Check IMU wiring or try cycling power
Status: -1

So it looks like the NodeMCU has reset waiting for something.

Here’s the code (I’ve highlighted the SD elements in blue), the remainder is identical to the MPU code that functions when run alone. The SD code is directly re-purposed from the Arduino example.

/*
Advanced_I2C.ino
Brian R Taylor
brian.taylor@bolderflight.com

Copyright (c) 2017 Bolder Flight Systems

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the “Software”), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include "SD.h"
#include "SPI.h"
#include “MPU9250.h”

// an MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68
MPU9250 IMU(Wire,0x68);
int status;

int chipSelect = 4; //set sdcard chipSelect to pin 4 for node mcu, pin 10 for nano
File mySensorData; //variable for file object

void setup() {

// serial to display data
Serial.begin(115200);
while(!Serial) {}

// start communication with IMU
status = IMU.begin();
if (status < 0) {
Serial.println(“IMU initialization unsuccessful”);
Serial.println(“Check IMU wiring or try cycling power”);
Serial.print("Status: ");
Serial.println(status);
while(1) {}
}
// setting the accelerometer full scale range to +/-8G
IMU.setAccelRange(MPU9250::ACCEL_RANGE_8G);
// setting the gyroscope full scale range to +/-250 deg/s
IMU.setGyroRange(MPU9250::GYRO_RANGE_250DPS);
// setting DLPF bandwidth to 20 Hz
IMU.setDlpfBandwidth(MPU9250::DLPF_BANDWIDTH_20HZ);
// setting SRD to 19 for a 50 Hz update rate
IMU.setSrd(19);
}

void loop() {

mySensorData = SD.open(“log.txt”, FILE_WRITE); // create log file

// read the sensor
IMU.readSensor();

if (mySensorData){

// display the data
Serial.print(“AccelX: “);
Serial.print(IMU.getAccelX_mss(),6);
// Serial.print(”\t”);
Serial.print(" AccelY: “);
Serial.print(IMU.getAccelY_mss(),6);
// Serial.print(”\t");
Serial.print(" AccelZ:");
Serial.print(IMU.getAccelZ_mss(),6);
// Serial.print("\t");
Serial.print(" GryoX: “);
Serial.print(IMU.getGyroX_rads(),6);
// Serial.print(”\t");
Serial.print(" GryoY: “);
Serial.print(IMU.getGyroY_rads(),6);
// Serial.print(”\t");
Serial.print(" GryoZ: “);
Serial.print(IMU.getGyroZ_rads(),6);
// Serial.print(”\t");
Serial.print(" MagX: “);
Serial.print(IMU.getMagX_uT(),6);
// Serial.print(”\t");
Serial.print(" MagY: “);
Serial.print(IMU.getMagY_uT(),6);
// Serial.print(”\t");
Serial.print(" MagZ: “);
Serial.print(IMU.getMagZ_uT(),6);
// Serial.print(”\t");
Serial.print(" Temp: ");
Serial.println(IMU.getTemperature_C(),6);

** mySensorData.print(IMU.getAccelX_mss(),6);**
** mySensorData.print(",");**
** mySensorData.print(IMU.getAccelY_mss(),6);**
** mySensorData.print(",");**
** mySensorData.print(IMU.getAccelZ_mss(),6);**
** mySensorData.print(",");**
** mySensorData.print(IMU.getGyroX_rads(),6);**
** mySensorData.print(",");**
** mySensorData.print(IMU.getGyroY_rads(),6);**
** mySensorData.print(",");**
** mySensorData.print(IMU.getGyroZ_rads(),6);**
** mySensorData.print(",");**
** mySensorData.print(IMU.getMagX_uT(),6);**
** mySensorData.print(",");**
** mySensorData.print(IMU.getMagY_uT(),6);**
** mySensorData.print(",");**
** mySensorData.print(IMU.getMagZ_uT(),6);**
** mySensorData.print(",");**
** mySensorData.println(IMU.getTemperature_C(),6);**
** mySensorData.close(); // close the file**
delay(250);

}
}

I was expecting this to be fairly simple but I’ve been trying to fix it for a couple of months on and off and have gotten no where; e.g. tried it on an Arduino Nano w/ level shift, tried a USB battery pack + 1.5A phone charger to rule out insufficient supply, tried multiple different MPU implementations in Arduino, tried re-wiring it + swapping out leads, tried different SD cards. Constantly get the same error; works separately, won’t work when combined.

Was wondering if I might be missing something obvious and thought I’d finally post it up as I’m unsure where to go with it.

Thanks for reading,
John

I use an Arduino Uno and a level shifter and ran into the same problem.

They work with independent sketches but not when the code of both is in the same sketch. Then the initialization fails.

Have you been able to figure anything out, regarding this issue?

Are you using SPI or I2C? I ask because you included the SPI lib before initializing the IMU with Wire:

#include "SPI.h"

// an MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68
MPU9250 IMU(Wire,0x68);

As you said that it works independently, I guess you use I2C and have it wired correctly. Are you also using I2C for the SD card?

I am trying to use SPI for both and I thought that it must be an SPI problem ... switching modes or something. I thought about rewiring it to use I2C as most people seem to use that, but when this stuff also happens when using I2C ...

I hope you still see this. Two people poking at it would be more fun. :)

Best, astro

Some SD card modules will not play well with other devices on the SPI bus. The problem is with the way the level shifter on the SD module is wired. The ones that do not work well have the MISO signal running through the level shifter. That causes the MISO signal to not be released so that the other devices can control it. The modules made by Adafruit (and some others) have the MISO signal going from the SD card straight to the MISO, bypassing the level shifter. Look at the schematic for the Adafruit module to see what to look for. DO (data out) is the MISO signal.

That is a very important detail, groundFungus. But I already took care of that when I tried to log the data of some thermocouples.

The level shifter on my unit (CATALEX Micro SD Card Module) uses tri-state buffers (I think that is what they are) but all their enable pins were grounded so they it never entered the high impedance state.

I unsoldered it, lifted one of the pins and connected it to the chip select line. After that it worked fine with the thermocouple amplifiers (MAX31855).

And it does work with all the hardware connected at the same time. The difference is the sketches I upload.