MPU 9250 (not working)

Status
Not open for further replies.
Hello,

I am trying to read data coming out of an MPU9250 imu. I download Brian R Taylor library but it doesn't seem to work in my case. Whenever I run the code below I get the following:

IMU initialization unsuccessful
Check IMU wiring or try cycling power
Status -1

So I assumed that something is wrong with the library and I checked the following with an oscilloscope. ss pin of the IMU was High instead of Low to enable slave. I also checked the SCK clock signal and MISO chanel there are both always high I am not receiving any kind of square wave signal. However, if I use SPI library to generate a SCK signal and make SS pin low. It seems that I am receiving data out of MISO (checked with an oscilloscope). So I guess hardware is fine.

The IMU MISO= PIN 12
MOSI=11
SSIMU=10
SCK=13

I am sharing SCK bus and MISO with other slave devices and this is why I added some additional lines to the example of Brian R Taylor that you can see in the link below:

https://github.com/bolderflight/MPU9250/blob/master/examples/Basic_SPI/Basic_SPI.ino


Any ideas?

Code:
#include "MPU9250.h"
const int ssimu = 10; // slave selection enable is low
const int sshand = 24; 
const int ssfork = 25; 
const int pwrencoders = 26; // making high enable power to encoders
// an MPU9250 object with the MPU-9250 sensor on SPI bus 0 and chip select pin 10
MPU9250 IMU(SPI,10);
int status;
void setup() {
  pinMode (ssimu,OUTPUT); // setting HIGH slave selection pin to disable IMU
  pinMode (sshand, OUTPUT);
  pinMode (ssfork, OUTPUT);
  pinMode (pwrencoders, OUTPUT);
  pinMode (ssimu, OUTPUT);
  // 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) {}
  }
}

void loop() {
digitalWrite(sshand,HIGH);  // setting LOW slave selection pin to enable handlebar encoder
    digitalWrite(pwrencoders,LOW); // setting HIGH PA10 pin of external pcb connected to pin 26 of teensie to enable power to my encoders
    digitalWrite(ssfork,HIGH); // setting HIGH slave selection pin to disable fork encoder
    digitalWrite(ssimu,LOW); // setting HIGH slave selection pin to disable IMU
  
  // read the sensor
  IMU.readSensor();
  // display the data
  Serial.print(IMU.getAccelX_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getAccelY_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getAccelZ_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroX_rads(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroY_rads(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroZ_rads(),6);
  Serial.print("\t");
  Serial.print(IMU.getMagX_uT(),6);
  Serial.print("\t");
  Serial.print(IMU.getMagY_uT(),6);
  Serial.print("\t");
  Serial.print(IMU.getMagZ_uT(),6);
  Serial.print("\t");
  Serial.println(IMU.getTemperature_C(),6);
  delay(100);
}
 
Systematic and scientific procedure for diagnose would be trying to get the IMU working in a first step with unmodified code and without other peripherals connected. And then re-add additional peripherals one by one, adapting the code step by step, until the whole thing turns round, assisted by a logic analyzer if needed.
 
Your comments in the code aren't really matching what's coded. But your code, as is, runs fine for me with just the MPU-9250 attached. I think what's going on is that you're forgetting to set all of the slave select pins high before calling IMU.begin() so some other device is stepping on the IMU and not allowing it to initialize. I would suggest the following code for setup (haven't looked at the logic for loop yet, but setup needs to be debugged first):

Code:
#include "MPU9250.h"
const int ssimu = 10; // slave selection enable is low
const int sshand = 24; 
const int ssfork = 25; 
const int pwrencoders = 26; // making high enable power to encoders
// an MPU9250 object with the MPU-9250 sensor on SPI bus 0 and chip select pin 10
MPU9250 IMU(SPI,10);
int status;
void setup() {
  pinMode (ssimu,OUTPUT); // setting HIGH slave selection pin to disable all SPI devices
  pinMode (sshand, OUTPUT);
  pinMode (ssfork, OUTPUT);
  pinMode (pwrencoders, OUTPUT);
  digitalWrite(ssimu,HIGH);
  digitalWrite(sshand,HIGH);
  digitalWrite(ssfork,HIGH);

  // 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) {}
  }
}
 
Logic analyzer.jpgUntitled.jpg

Hi Brian,

Thank you for your feedback regarding the code however I think this is not the cause of problem. Today I tried your basic SPI example without any other slave device connected to teensie.
I connected teensie to sparkfun IMU breakout: https://learn.sparkfun.com/tutorials/mpu-9250-hookup-guide" all other slave devices have been disconnected. SJ2 Jumper is connected to SDO/MISO line and not ground. SJ1 short VDD and VDDIO.

3,3 V is connected to VDD
gnd of teensie = GND
MOSI/SDA connected to pin 11
MISO/SD0 connected to pin 12
SCK=13
CS=10

It compiles but I still get the same:

IMU initialization unsuccessful
Check IMU wiring or try cycling power
Status -1

Attach you can see a screen shot of the logic analyzer SCK remains HIGH, LED OF board is on. what is the SCK set frequency? I tried to sample the data from all channels at all possible frequencies however I did not get any pulse. MOSI=HIGH and MISO LOW, SS select is not enabled.

Code:
#include "MPU9250.h"

// an MPU9250 object with the MPU-9250 sensor on SPI bus 0 and chip select pin 10
MPU9250 IMU(SPI,10);
int status;

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) {}
  }
}

void loop() {
   // read the sensor
  IMU.readSensor();
  // display the data
  Serial.print(IMU.getAccelX_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getAccelY_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getAccelZ_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroX_rads(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroY_rads(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroZ_rads(),6);
  Serial.print("\t");
  Serial.print(IMU.getMagX_uT(),6);
  Serial.print("\t");
  Serial.print(IMU.getMagY_uT(),6);
  Serial.print("\t");
  Serial.print(IMU.getMagZ_uT(),6);
  Serial.print("\t");
  Serial.println(IMU.getTemperature_C(),6);
  delay(100);
}

I was thinking using SPI ARDUINO library to initiate the clock signal and the write directly to MOSI bitwise commands to access the registers however I do not know exactly how to do it even when I read the manua.ls there any simple way to check without involving any library that the hardware is working properly.?(It is new but it will worth it to test it)
 
I don't know of a good way to check the hardware over SPI. It's returning -1, which means the code isn't talking to the board at all. Your listed pinout looks good. Looking at the schematic for the Sparkfun breakout, I wonder if the 3 10k pullup resistors on CS, SCL, and SDA are causing issues. SCK is set to 15 MHz for data reading; initial operations (register setting and reading) are performed with an SCK of 1 MHz.
 
If it were me, I would double check your wiring and make sure you have good contacts.
Also with your logic analyzer, I assume you have ground wire hooked up as well.

The reason I mention all of this, is that this code looks pretty basic to start off with. That is:
the call to begin should simply set your CS pin to output and set it's state to high and then call SPI.begin();

It then should call a few write register calls which again are pretty simple:
Code:
    _spi->beginTransaction(SPISettings(SPI_LS_CLOCK, MSBFIRST, SPI_MODE3)); // begin the transaction
    digitalWrite(_csPin,LOW); // select the MPU9250 chip
    _spi->transfer(subAddress); // write the register address
    _spi->transfer(data); // write the data
    digitalWrite(_csPin,HIGH); // deselect the MPU9250 chip
    _spi->endTransaction();
So you should see something happen on the different IO pins associated with SPI.
 
so are you using this breakout https://www.sparkfun.com/products/13762

that breakout is jumpered to run in I2C mode, AD0 (SPI SDO) is jumpered to GND, so SPI won't work until you desolder that jumper. yes?

there is a post somewhere in pjrc forum, where Kris notes PCB wiring for sparkfun breakout is not optimal and can interfere with magnetometer ....
 
(? for some reason Vbulletin is not letting me edit my previous post??) any how, on closer reading, I see that you have removed the AD0 jumper so SPI should work. On your analyzer you should see SPI clock and MOSI activity even with nothing connected. Try this little sketch with your analyzer and nothing connected to your Teensy except analyzer wires on CS MOSI MISO and clock

Code:
#include <SPI.h>
#define CS 10
#define SPICLOCK 10000000
#define SPI_BUFF_SIZE 1000

uint8_t tx_buffer[SPI_BUFF_SIZE];

void setup() {
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);
  SPI.begin();
  SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
}

void loop() {
  for (int i = 0; i < SPI_BUFF_SIZE; i++ ) tx_buffer[i] = i;
  digitalWrite(CS, LOW);
  SPI.transfer(tx_buffer, SPI_BUFF_SIZE);
  digitalWrite(CS, HIGH);
  delay(30);
}
you should see 10 mhz SPI clock. unconnected MISO should return 0's (you could jumper MOSI to MISO for the test if you wish)
 
Status
Not open for further replies.
Back
Top