How to Setup the MPU-9250 on a Raspberry Pi

Step 1: Get the Right Gear

You'll need to get the associated wires, jumper cables, solder, what-have you, in order to properly connect the MPU-9250 to the Raspberry Pi. Keep in mind, I'm using i2c, and those cables can't be too long otherwise the signal gets corrupted (No longer than a foot or so).

Not only that, but you'll have to mount the sensor correctly. I had some leftover redwood lumber that I fashioned into a housing for the sensor, which makes it easier to work with at home, and then easy to install on the boat. The housing is goofy shaped because I'll be installing it inside a cabinet, but the bottom is at a 13 degree angle from level (hence the sloped housing).

Do not use any ferrous metal (or any metal, really... maybe brass would be okay) to construct the housing. I waved a stainless steel screw over the sensor and it swiftly changed the heading by 30 degrees. So I used some old fashioned wood glue to hold it together.

Step 2: Download and Install the Right Programs

For my system, I keep all scripts and files in its own folder in the /home/pi directory called "kts".

mkdir kts
cd kts

Next, get yourself the right i2c programs.

sudo apt-get install i2c-tools

and connect your MPU-9250 (remember to attach it to the 3.3V pin, not the 5V pin). Here's a pinout diagram, with the top of the image representing the side away from the USB ports. See my previous post for help if you get stuck.


  • One thing you must do: Click the Menu in the top Left Corner, go to Prefrences->Raspberry Pi Configuration->Interfaces and enable i2c (this will require a reboot).
  • Go ahead and restart now.

To make sure it's connected, type in

sudo i2cdetect -y 1

and you should see the number 68 in the grid that displays. 68 is the sensor's default address.

Next, download and install cmake, which is used to build the sensor's library:

sudo apt-get install cmake

(and enter "y" went prompted). You'll also have to install some python tools, since that is the language of the scripts we use:

sudo apt-get install python-dev

If you want to want to do the Ellipsoid Fit Calibration (strongly recommended), then you'll also need the octave program:

sudo apt-get install octave

Next, get the RTIMULib Library from Github (website here):

git clone https://github.com/richards-tech/RTIMULib2.git

All we really need is the RTIMULibCal program, and the Linux/python scripts. So if you want all the demo programs and whatnot, follow the instructions here at the github page. Otherwise, proceed as follows:

cd RTIMULib2/Linux/RTIMULibCal
make -j4
sudo make install

The last thing we have to do before we run the program is setup our working directory, which I have creatively called "scripts" and copy the RTEllipsoidFit folder into folder just above this directory:

cp -r /home/pi/kts/RTIMULib2/RTEllipsoidFit/ /home/pi/kts/
cd /home/pi/kts/RTEllipsoidFit/

It's important to navigate to inside RTEllipsoidFit folder before proceeding, otherwise the calibration won't work. 

These next few edits I believe are optional, but are dictated on the RTIMULib's github page, so here we go. First, enter

sudo nano /etc/modules

and make sure that both these lines are uncommented in this file:

i2c-dev
i2c-bcm2708

Hit control+x, then y, then enter to save the changes.

Then:

sudo nano /etc/udev/rules.d/90-i2c.rules

and add:

KERNEL=="i2c-[0-7]",MODE="0666"

And one more:

sudo nano /boot/config.txt

and add at the bottom:

dtparam=i2c1_baudrate=400000

then

sudo reboot

Step 3: Calibrating the MPU-9250 on the Raspberry Pi

In the RTEllipsoidFit folder, run this in the terminal:

RTIMULibCal

Just type that in and hit enter. The instructions that display are pretty straight forward. Hit m to begin calibrating the magnometer's min/max values (rotate the sensor along all axis), then hit "s" to save it. Next, hit "e" to do the ellipsoid fit. You basically imagine the sensor sitting on a globe--and then you move the sensor all over the surface of the globe, as if it were a ship sailing along the ocean, keeping the bottom of the sensor pointed towards the center as you traverse all quadrants. This might take a while, and it will automatically stop when it gets enough data. If you get the following error:

error: ellipsoide fit returned 32512 - aborting

then that means you aren't inside the RTEllipsoidFit directory. Navigate back into first and then try again. If you get this error:

error /bin/sh: 1: octave: not found

that means you haven't installed octave (see above, or just quick run sudo apt-get install octave). If you get this error:

I2C read error from 104, 114 - Failed to read fifo count

then one of your cords probably became unplugged :/ (it happened to me).

Finally, we calibrate the accelerometers by pressing a, then holding the sensor along the x axis (so x is pointed straight up). Begin, hit 'e' to activate the axis, wiggle it around gently, hit 'd' to disable it, rotate it so the other end of that axis is pointed down, then hit 'e' to reactivate it, then hit 'd' and space to change to the next axis. Then repeat this for y, and z, and then his s to save it all, and finally x to exit.

Now we have the calibration data. The important thing is to make sure the RTEllipsoidFit folder is one folder above our working directory. And just copy the "RTIMULib.ini" file to the working directory, otherwise none of it will work. To copy it over, do this:

cp RTIMULib.ini /home/pi/kts/scripts/

See the next step for more.

The MPU-9250 Python Script

As opposed to my previous endeavors, I only want true heading, and roll, pitch, rate of roll, rate of pitch, and rate of yaw (those last three are strictly for gee-whiz data logging, so I can go back and say "Wow, I was rolling really fast right there!").

This script extracts that information and runs as fast as it possibly can. Mine clocks in around 4 milliseconds, or 250 times per second. But I don't need a new NMEA sentence printed that quickly. So I only print it once per second. But for some reason, whenever I change the sample rate (poll_interval), it works really goofy. Sometimes it delays up to 5 seconds. Strange. Anyway, I wrote in the code to run at its normal rate, take a reading 10 times per second, dampen out the heading over three seconds, dampen out roll for one second, and then print it once per second.

It prints it out pretty much only for debugging purposes. But it also sends it to a UDP port, which goes to another script for more fun and filtering of other data inputs. Make a file called "imu.py" in the scripts folder, and run it from the terminal by typing "python imu.py" (if you run it like this, be sure to uncomment the "print imu_sentence" line to you actually see the output).

Or to make it easy, just mosey on over to this github page right here: https://github.com/OldCC/kts and download the imu.py script. I've copy and pasted it here for ease, but I won't be updating the code below (you'll have to go to github for that).

Be sure that the RTIMULib.ini calibration file generated in the previous step is in the same directory as this script, and that the RTEllipsoidFit folder is in the directory above this script. For example, the RTEllipsoidFit folder is located here:

/home/pi/kts/

and this script (imu.py) as well as the calibration file (RTIMULib.ini) are both located in:

/home/pi/kts/scripts/

Something worth noting: If it fails to initialize, it sends an NMEA sentence saying that. If it fails after it's been working, it sends an NMEA sentence that will go all the way through to my chartplotter or phone that lets me know its failed, and for how long it has been failed.

Example sentence:

$IIXDR,IMU_FAIL,1.2*6F


that lets me know it failed 1.2 minutes ago, and something's wrong. Usually it would mean one of the wires came loose.

The imu.py script:

 import sys, getopt  
   
 sys.path.append('.')  
 import RTIMU  
 import os.path  
 import time  
 import math  
 import operator  
 import socket  
   
 IMU_IP = "127.0.0.2"  
 IMU_PORT = 5005  
   
 SETTINGS_FILE = "RTIMULib"  
   
 s = RTIMU.Settings(SETTINGS_FILE)  
 imu = RTIMU.RTIMU(s)  
   
 # timers  
 t_print = time.time()  
 t_damp = time.time()  
 t_fail = time.time()  
 t_fail_timer = 0.0  
 t_shutdown = 0  
   
 if (not imu.IMUInit()):  
   hack = time.time()  
   imu_sentence = "$IIXDR,IMU_FAILED_TO_INITIALIZE*7C"  
   if (hack - t_print) > 1.0:  
     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  
     sock.sendto(imu_sentence, (IMU_IP, IMU_PORT))  
     t_print = hack  
     t_shutdown += 1  
     if t_shutdown > 9:  
       sys.exit(1)  
   
 imu.setSlerpPower(0.02)  
 imu.setGyroEnable(True)  
 imu.setAccelEnable(True)  
 imu.setCompassEnable(True)  
   
 poll_interval = imu.IMUGetPollInterval()  
   
 # data variables  
 roll = 0.0  
 pitch = 0.0  
 yaw = 0.0  
 heading = 0.0  
 rollrate = 0.0  
 pitchrate = 0.0  
 yawrate = 0.0  
 magnetic_deviation = -13.7  
   
   
 # dampening variables  
 t_one = 0  
 t_three = 0  
 roll_total = 0.0  
 roll_run = [0] * 10  
 heading_cos_total = 0.0  
 heading_sin_total = 0.0  
 heading_cos_run = [0] * 30  
 heading_sin_run = [0] * 30  
   
 # sentences produces by the imu  
 iihdt0 = "$IIHDT,,T*0C"  
 iixdr0 = "$IIXDR,A,,D,ROLL,A,,D,PTCH,A,,D,RLLR,A,,D,PTCR,A,,D,YAWR*51"  
 iihdt = iihdt0  
 iixdr = iixdr0  
 freq = 1  
   
 while True:  
  hack = time.time()  
   
  # if it's been longer than 5 seconds since last print  
  if (hack - t_damp) > 5.0:  
      
    if (hack - t_fail) > 1.0:  
      t_one = 0  
      t_three = 0  
      roll_total = 0.0  
      roll_run = [0] * 10  
      heading_cos_total = 0.0  
      heading_sin_total = 0.0  
      heading_cos_run = [0] * 30  
      heading_sin_run = [0] * 30  
      t_fail_timer += 1  
      imu_sentence = "IIXDR,IMU_FAIL," + str(round(t_fail_timer / 60, 1))  
      cs = format(reduce(operator.xor,map(ord,imu_sentence),0),'X')  
      if len(cs) == 1:  
         cs = "0" + cs  
      imu_sentence = "$" + imu_sentence + "*" + cs  
      sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  
      sock.sendto(imu_sentence, (IMU_IP, IMU_PORT))  
      t_fail = hack  
      t_shutdown += 1  
   
  if imu.IMURead():  
   data = imu.getIMUData()  
   fusionPose = data["fusionPose"]  
   Gyro = data["gyro"]  
   t_fail_timer = 0.0  
   
   if (hack - t_damp) > .1:  
     roll = round(math.degrees(fusionPose[0]), 1)  
     pitch = round(math.degrees(fusionPose[1]), 1)  
     yaw = round(math.degrees(fusionPose[2]), 1)  
     rollrate = round(math.degrees(Gyro[0]), 1)  
     pitchrate = round(math.degrees(Gyro[1]), 1)  
     yawrate = round(math.degrees(Gyro[2]), 1)  
     if yaw < 90.1:  
       heading = yaw + 270 - magnetic_deviation  
     else:  
       heading = yaw - 90 - magnetic_deviation  
     if heading > 360.0:  
       heading = heading - 360.0  
         
     # Dampening functions  
     roll_total = roll_total - roll_run[t_one]  
     roll_run[t_one] = roll  
     roll_total = roll_total + roll_run[t_one]  
     roll = roll_total / 10  
     heading_cos_total = heading_cos_total - heading_cos_run[t_three]  
     heading_sin_total = heading_sin_total - heading_sin_run[t_three]  
     heading_cos_run[t_three] = math.cos(math.radians(heading))  
     heading_sin_run[t_three] = math.sin(math.radians(heading))  
     heading_cos_total = heading_cos_total + heading_cos_run[t_three]  
     heading_sin_total = heading_sin_total + heading_sin_run[t_three]  
     heading = round(math.degrees(math.atan2(heading_sin_total/30,heading_cos_total/30)),1)  
     if heading < 0.1:  
       heading = heading + 360.0  
   
     t_damp = hack  
     t_one += 1  
     if t_one == 10:  
       t_one = 0  
     t_three += 1  
     if t_three == 30:  
       t_three = 0  
    
     if (hack - t_print) > 1:  
       hdt = "IIHDT," + str(round(heading))[:-2] + ",T"  
       hdtcs = format(reduce(operator.xor,map(ord,hdt),0),'X')  
       if len(hdtcs) == 1:  
         hdtcs = "0" + hdtcs  
       iihdt = "$" + hdt + "*" + hdtcs  
       
       xdr = "IIXDR,A," + str(int(round(roll))) + ",D,ROLL,A," + str(int(round(pitch))) + ",D,PTCH,A," + str(int(round(rollrate))) + ",D,RLLR,A," + str(int(round(pitchrate))) + ",D,PTCR,A," + str(int(round(yawrate))) + ",D,YAWR"  
       xdrcs = format(reduce(operator.xor,map(ord,xdr),0),'X')  
       if len(xdrcs) == 1:  
         xdrcs = "0" + xdrcs  
       iixdr = "$" + xdr + "*" + xdrcs  
   
       imu_sentence = iihdt + '\r\n' + iixdr  
   
       sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  
       sock.sendto(imu_sentence, (IMU_IP, IMU_PORT))  
   
       t_print = hack  
       
   time.sleep(poll_interval*1.0/1000.0)  

Comments

  1. Conner, what do you think of this one? Is it a minor upgrade, significant improvement, overkill for the purpose, or worthwhile?
    9255-2
    http://www.invensense.com/products/motion-tracking/9-axis/mpu-9255-2/

    Thanks for having such a useful blog, and dovetailing with OpenCPN.

    ReplyDelete
  2. I think that might be a bit of an overkill, at least for nautical purposes. From the sound of it, the only difference from the 9250 is that it uses an additional library to detect motion (steps, sleep activity, etc...). That isn't very useful in a sailboat.

    I spent a month coming up with the code to detect the ocean swell/boat heave (the height of the waves, and the boat's vertical position on the wave, as well as the period of the wave), and while the math checks out, the sensor does not. Why? Mainly because the motion detector (accelerometer) is really only good for just that--accelerations. When you integrate it into velocity, it loses a lot of accuracy, and then when you integrate it again for distance, it's pretty much useless (the writer of the library I use has a good write up here: https://richardstechnotes.wordpress.com/imu-stuff/).

    So, the way I understand it, the sensor in a boat is really only good for three things: magnetometer for compass headings, and gyroscopes for roll/pitch and also for rate of roll/pitch/yaw. And the MPU-9250 (which has a slightly better gyro than the 9150, although I can't notice the difference) does that plenty fine. Then again, I'm not using it for any scientific or commercial applications. It's just gee-whiz proof of concept that you can make a $500 marine instrument for about 10% of the price.

    ReplyDelete
  3. Brilliant, thanks for the great write up. I got the 9250 configured and have readings!

    ReplyDelete
    Replies
    1. Excellent, it's always good to hear success. It gave me an absolute headache to figure it out because I'm not very tech orientated, so I'm glad to hear I'm helping a bro out!

      Delete
  4. Replies
    1. check this script out here:

      https://github.com/richardstechnotes/RTIMULib2/blob/master/Linux/python/tests/Fusion10.py

      It will print out your altitude above sea level, but keep in mind that won't be 100% exact due to the nature of the pressure sensor.

      Delete
  5. Hi, Thank you so much for your post.
    I am having difficulty and hope you can help me?
    I have followed your instructions over and over but when I navigate to "cd /home/pi/kts/RTEllipsoidFit/ and then run RTIMULibCal, I get the following:

    RTIMULibCal - using RTIMULib.ini
    Settings file not found. Using defaults and creating settings file
    Failed to open settings file for saveFailed to open SPI bus 0, select 0
    Failed to open SPI bus 0, select 1
    No IMU detected
    Using fusion algorithm RTQF
    No IMU found
    ----

    When I run sudo i2cdetect -y 1 then I see the address 68. When I run any of the demo programs none of them will recognise the MPU9250.

    What do you think?

    Thanks in advance.
    Raspberry Pi 3 Model B, Jessie.

    ReplyDelete
    Replies
    1. Yes, I believe I've gotten that error before. I don't have the Pi with me at the moment, but I believe the fix was that I had to go into a file within the RTEllipsoidFit folder and I had to change a few things, but I can't remember what they were at the moment... let me get back to you

      Delete
    2. Okay, try this solution. Navigate back to the original RTIMU folder that you downloaded (RTIMULib2/Linux/RTIMULibCal/) and try running RTIMULibCal there. If that works, it will create a file there called RTIMULib.ini which is the configuration file. Then copy that over to your working directory (kts/RTEllipsoidFit) and try running RTIMULibCal again there and it should work.

      Let me know if that doesn't work, I am suspicious because your error message mentions SPI, which, if you've followed my guide, shouldn't come up because we're using i2c and not SPI (I think, my knowledge is a little hazy here).

      Delete
    3. Hi, thank you for your reply. I have spent a while poking around and reading up. We are using i2c so I too was suspicious about the SPI but thought perhaps that was due to the Pi searching i2c not finding the IMU so searching SPI.
      Nevertheless, I have made progress and now when I run RTMULibCal I get:

      RTIMULibCal - using RTIMULib.ini
      Settings file RTIMULib.ini loaded
      Using fusion algorithm Kalman STATE4
      Error in compass calibration data
      Failed to open I2C bus 0
      ---

      The last line seems that everything sets up okay but the MPU9250 isn't on i2c bus 0, it's on bus 1? (if I understand bus 1 being the '1' in "sudo i2cdetect -y 1").

      But if I go into RTIMULib.ini I can see that 'bus 1' is selected:
      ...
      # Is bus I2C: 'true' for I2C, 'false' for SPI
      BusIsI2C=true

      #
      # I2C Bus (between 0 and 7)
      I2CBus=1
      -----

      I think that all I have done here is muddied the water...

      Following your instructions (appreciated, thanks) renders the following:
      RTIMULibCal - using RTIMULib.ini
      Settings file RTIMULib.ini loaded
      Failed to open SPI bus 0, select 0
      Failed to open SPI bus 0, select 1
      No IMU detected
      Using fusion algorithm RTQF
      No IMU found
      ----

      Progress has been made in linking to the Settings file.

      Sorry to keep you!

      Delete
    4. Okay, a few suggestions:

      1. I believe there is a "thing" on the MPU sensor that let's you decide between 68 and 69 or something like that. Some sort of physical switch, or like a little piece of cutaway circuitry. Make sure that's where it should be (I believe 68 is the default--however, I believe that you already have it there due to the check you mentioned above returning 68).

      2. Reformat the Raspberry Pi card, and start over from square one. When you redo this, ensure that you install everything first (octave, etc...) BEFORE you download any of the RTIMULib files. Then run the program in its own directory (like in my previous comment) and go from there.

      3. Do the above step (reformat the entire card and start over, or possibly you could just delete the RTIMULib directory and re download that) but this time, follow Richard's tutorial on his GitHub page (https://github.com/richardstechnotes/RTIMULib2/tree/master/Linux/python) for tests/fusion.py or tests/fusion10.py (basically, forget my tutorial, follow his stuff to make sure that it works as advertised). You'll follow his instructions to install everything, and run the Fusion python program which just prints out all the raw data. If THAT works, then you know you're in a good spot because at least the sensor isn't broke.

      Let me know how that turns out and I'll see if I can wrack my memory for other ideas.

      Delete
    5. I should also add a few others of course: Make sure the wires are good and properly soldered (mine weren't the first time), and it may be possible that you have to get a new MPU (I had an MPU 9150 originally but it was broke and had to get the 9250).

      Delete
    6. Oh and with the wires, I'd just go ahead and replace them if nothing else works, another guy in another post mentioned that his had frayed inside the casing.

      Delete
  6. Thanks, I will work through suggestions over the week.
    I spent some time going through many files to try and instruct the Pi exactly where to look for the MPU9250. Hasn't worked but now when I go into the GUI calibrator (RTIMULibDemoGL) and change the SPI Bus to 1 (which previously did nothing) I now get a different final line after RTIMULibCal: "Incorrect MPU-9250 id 115". Whilst RTIMULibDemoGL is running the Terminal prints something about an incorrect FIFO Count.

    The Datasheet confirms that id 115 and FIFO counts are linked so after doing your suggestions, the answer may lie within there (wherever 'there' is!).

    Thanks for your help

    ReplyDelete
  7. Hi,

    I also been struggling with the same problems and couldn't get past the "Incorrect MPU-9250 id 115" issue.

    But after a bit of trial and error, I seem to have got it working. What I did was this.
    1. Find the RTIMUDefs.h file that is located in the IMUDrivers directory.
    2. Edit this file and look for the line that starts with #define MPU9250_ID
    3. By default, this is defined to be 0x71. Change it to 0x73. This updated value same as decimal 115
    4. re-make/install the Linux stuff
    5. re-build/install the python stuff.

    good luck !

    ReplyDelete
  8. Mr Sanders,
    Where is the IMUDrivers dir?
    Thanks for any insight!

    ReplyDelete
  9. Yeah !!
    Thanks for your solution alex chalkin & Michael Sanders !

    -> 3. By default, this is defined to be 0x71. Change it to 0x73. This updated value same as decimal 115

    It work for me :-)

    Thanks a lot ...

    ReplyDelete
  10. Hi,
    I can calibrate the 9250, but when i run the "python imu.py" -> i see nothing in output ?
    It's the same whith kplex, whith : "sudo kplex file:direction=out"

    with tcpdump i can see : sudo tcpdump -ni lo udp
    00:46:23.363093 IP 127.0.0.1.41178 > 127.0.0.2.5005: UDP, length 22
    00:46:24.363221 IP 127.0.0.1.38415 > 127.0.0.2.5005: UDP, length 22

    But that's all, can you tell me if it's possible to log the output of imu.py ?
    I use a RaspberryPi 3 and Ubuntu Mate 16.04

    Thank you for your work and these detailed documentation ! :-)

    ReplyDelete
  11. hi

    I try to check where iam forget one things :
    1) i remove directory : kts/RTIMULib2 kts/RTEllipsoidFit/
    2) cd kts & git clone https://github.com/richards-tech/RTIMULib2.git
    3) i change the 0x71. Change it to 0x73 like Michael Sanders tell us
    4) I compile it :
    cd RTIMULib2/Linux/RTIMULibCal
    make -j4
    sudo make install

    5) I run 3 step of calibration and copy file into script : cp RTIMULib.ini /home/pi/kts/scripts/

    But when i run the "python imu.py" noting... in kplex log
    When i change in RTIMULib.ini :
    IMUType=7 to IMUType=0

    I have in kplex.log:
    $IIXDR,A,0,D,ROLL,A,0,D,PTCH,A*31
    $TIROT,0.0,A*3B
    $IIHDM,360,M*39
    $IIHDT,0,T*3C

    And in OpenCPN : compas 360

    So the link imy.py -> kplex -> opencpn is ok :) but why I can't read the correct value from the 9250 ?

    Some one could help me ?
    Thanks for your script :-)

    ReplyDelete
    Replies
    1. Does the HDM change when you move the compass?

      Delete
    2. thanks for your reply,

      but no, when i move compass, the sequence is always the same and it runs in a loop :
      ----------------
      $IIXDR,A,0,D,ROLL,A,0,D,PTCH,A*31
      $TIROT,0.0,A*3B
      $IIHDM,360,M*39
      $IIHDT,14,T*09
      ----------------

      Tonight I try another system on another key, whith a Raspbian Pixel, but the result is the same...

      thanks for your help !

      Delete
    3. Here's what's happening: those sentences that OpenCPN is getting are the default sentences I defined in the script above. When the script runs, it makes a "blank" sentence, which reduces the chances of the script crashing.

      So that tells me that your sensor is not sending data to the script. However, the script is still detecting that the IMU is working, otherwise you'd get the $IIXDR,IMU_FAILED_TO_INITIALIZE*7C sentence.

      This is very curious, because the IMU tells the script that it's connected and initialized, but it is not sending any AHRS data.

      When you run the calibration, and you move the compass, the values change, correct? You can run all three steps of the calibration, correct? That means that your sensor is working.

      Try this to help identify the problem.

      Find this part of the script:

      if imu.IMURead():
      data = imu.getIMUData()
      fusionPose = data["fusionPose"]
      Gyro = data["gyro"]
      t_fail_timer = 0.0

      and add this line under fusionPose:

      print fusionPose

      so now the whole thing should look like this:

      if imu.IMURead():
      data = imu.getIMUData()
      fusionPose = data["fusionPose"]
      print fusionPose
      Gyro = data["gyro"]
      t_fail_timer = 0.0

      Now, get everything set up like you did before, and this time, open up the terminal and run the script from there like so:

      python imu.py

      Let me know what you see displayed in the terminal. If it's working, you will see all the fusion data, and the fix will be simple. If it's not, nothing will display in the terminal, and the solution will not be so simple.

      Delete
    4. hi !
      Thank you for your detailed answer

      Ok, i understand it's curious... because after modify the MPU9250_ID from RTIMUDefs.h : 0x71 to 0x73 i can run the RTIMULibCal without problem..., it detect the 9250.

      I can calibrate and when I run it, and move the compass, the values change... and yes I can run the 3 steps... if you whant i can send you the RTIMULib.ini if you whant to read the value are set...

      I add the line 'print fusionPose' in imu.py
      When i run, (whith IMUType=7 in RTIMULib.ini) i dont see anything in output :-(

      I put (IMUType=0 in RTIMULib.ini)
      pi@raspberrypi:~/kts/scripts $ sudo python imu.py
      (0.0, -0.0, -0.0)
      (0.0, -0.0, -0.0)
      (0.0, -0.0, -0.0)
      (0.0, -0.0, -0.0)

      A bit disappointed, i move the sensor in all position and suddenly i see an trace... I suspected a false contact. I then removed the ground and returned the ground

      (with IMUType=7 in RTIMULib.ini ) I see :
      (-0.05568811297416687, -0.1369699388742447, 3.020327091217041)
      (-0.05867129564285278, -0.13919031620025635, 3.0229928493499756)
      (-0.061601679772138596, -0.14135867357254028, 3.0256123542785645)
      (-0.06448002904653549, -0.14347624778747559, 3.028186082839966)
      (-0.06730718165636063, -0.14554433524608612, 3.030715227127075)
      (-0.07008390873670578, -0.14756423234939575, 3.0331997871398926)
      (-0.07281096279621124, -0.1495371013879776, 3.0356409549713135)
      (-0.0754891112446785, -0.1514640748500824, 3.038038969039917)
      (-0.07811914384365082, -0.15334632992744446, 3.0403945446014404)
      (-0.0807018131017685, -0.1551850438117981, 3.042708396911621)
      (-0.08323786407709122, -0.1569812148809433, 3.044981002807617)
      (-0.08572802692651749, -0.15873590111732483, 3.047213315963745)
      (-0.088173046708107, -0.16045019030570984, 3.049405574798584)
      (-0.09057363122701645, -0.16212505102157593, 3.051558494567871)
      (-0.09293054044246674, -0.16376149654388428, 3.053673028945923)
      (-0.09524446725845337, -0.1653604656457901, 3.0557491779327393)

      juste one time, and every time i disconnect and reconnect ground.
      In kplex, i see :
      $IIHDM,173,M*39
      $IIHDT,174,T*3E
      $IIXDR,A,0,D,ROLL,A,-8,D,PTCH,A*14
      $TIROT,90.0,A*02

      But nothing after....

      May be the sensor as a problem, I will try to buy another one ...
      Thank you for your time, And do not hesitate if you want me to try other tip ;-)


      Delete
  12. Okay, I followed all the steps and like others the SPI thing kept popping up even when I was clearly using the I2C. I looked at the RTIMUlib.ini file and changed the IMUType to 7. The IMU gets detected and then asks me to calibrate but as I start the calibration, I always get the "I2C read error from 0, 114 - Failed to read fifo count" can anyone help me with this?

    ReplyDelete
    Replies
    1. I would suggest replacing all your cables and re soldering any connections, then try again. Also if you're using i2c make sure the cables aren't too long (6 inches max, the shorter the better).

      Delete
    2. Hello, we check the cable with multimeter, and it works fine. We also were able to get raw data using a different I2C method, but we need this particular package to work. Do you have anything other suggestion?

      Delete
    3. One question: does RTIMULib only work in Raspbian? or can it also operate in Ubuntu?

      Delete
    4. It should work fine on almost any Linux, especially Ubuntu. I will have to refer you to the library's website for more instructions, and recommend you follow their tutorials to help troubleshoot , all located here: https://github.com/RTIMULib/RTIMULib2

      If you can get his Python programs working, then

      Delete
  13. When I run sudo i2cdetect -y 1 then I see the address 69. What changes to the steps should i make for this?

    When i follow the steps and change 0x71 to 0x73 it shows No Imu Detected.

    Much Thanks!

    ReplyDelete
  14. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Do you have a git hub account? Try putting in your credentials. If that doesn't work, then your best option is just to go to git hub, copy and paste each file into a new text file and name it appropriately with a ".py" suffix

      Delete
  15. when I try to run imu.py after the calibration I have an error at line 63, the "mag" file isn't there, where can he be?

    ReplyDelete
  16. RTIMULib2 use DMP processor of IMU9250 or it apply own filter at runtime such as Kalman or other? Thanks!

    ReplyDelete
  17. I can't get my MPU9250 working. Step 1 and 2 of the instructions above work fine, but when I run RTIMULibCal I get a "No IMU Detected" and "No IMU Found" error. I can see the device address as 68 when I run i2cdetect. I've tried the suggestions for Alex's problem above, but that hasn't helped.
    Just to be sure I've connected it up correctly (incase the address isn't enough), I've got the VCC pin going to Raspi pin 1, GND going to pin6, SDA going to pin 3 and SLC going to pin 5. All other pins are unconnected.
    Keen to know if there's something else I should be trying.

    Thanks in advance.

    ReplyDelete
  18. Thought I would drop in, following your (very kind) recommendations I have been unable to spend time on this, but hope to again soon!

    Best,

    ReplyDelete
  19. Great article! I'm working on this project where I have to calculate number of steps of a person walking, i'm using the MPU9250, any suggestion would be appreciated. Thank you

    ReplyDelete
    Replies
    1. I tried something similar with this trying to measure the wave height around the boat, just measuring the acceleration. Then I integrated that twice to get position, and it worked out mathematically, but not in any practical sense.

      Check this out for some background info (particularly the section This is why trying to measure position with a MEMS 9-dof IMU is doomed to failure): https://richardstechnotes.wordpress.com/imu-stuff/

      But it sounds like you only need the acceleration, so there's no integration on your part, so there shouldn't be any issue. However, I think you'll run into the same issue I did.

      If you run the code to print out the acceleration in the z-axis, it'll print out negative values (-1.0 for Earth's gravity). If you add 1 to the variable, you'll cancel out the gravity and now it should read zero, but it won't--it'll fluctuate up and down by some "noise." The only way to make this work, you'll have to do some very good calibration for all three degrees of freedom. And even then, you'll need to round out gravity to something like just 2 decimal places.

      Okay, so now it's calibrated, it's rounding out the readout, and now you should be seeing basically 0.0g in the z-axis. Now let’s simulate a step assuming the MPU is a pedometer on the foot. As you left it up, it’ll show a positive value, then halfway up the step (as you start to slow the upward movement in preparation of the downward movement), it’ll show zero and then switch to a negative value. Halfway down this downward arc, as you slow down to set it back on the table, it’ll switch from negative to zero to positive. Then it’ll get real messy as you set it down on the table because it’s so sensitive.


      So how can you measure that string of zero->positive numbers->zero->negative numbers->zero->positive numbers->zero and count that as one step? It isn't as simple as seeing if the current acceleration is different than the previous one (as in, you can't just do a check to see if the current value is negative, zero, or positive relative to the previous value). The reason is that there's just too much noise and it would measure multiple steps just by lifting it up and holding it in the air.

      I never found a solution to this problem. Perhaps you could make an array of, say, a thousand values, and see if the average value of the array is positive or negative, and anytime it switches to/from positive from/to negative, it's equal to zero. So now you have a variable that represents the last 1000 values from the present moment, and any time that variable goes from negative to positive to zero, that's one step.

      Or you could measure a spike in positive acceleration as the heel hits the ground. I don’t know. If someone has a solution to this, I’d love to find out for future projects.

      I do have some good news for you though. In the previous example, as the MPU moves up and down, it’s only in the z-axis. But if it’s on a foot, the positive acceleration will shift all over as the foot moves and twists and turns. So it isn’t just the z-axis, it’s all of them. So now you have to find the acceleration vector from all three axis *orthogonal* to the surface of earth, regardless of the MPU’s orientation.

      I still have my notes from my failed project, so I already did all that math for you, but I’m unfortunately away from home for another month so I won’t be able to get that to you for a while.

      Do you have a picture of your prototype or device? I'm curious how that'll look.

      Delete
  20. Thanks very much for your suggestions. I've been able to build a combination IMU/GPS data logger that is giving me 10hz updates and appears highly accurate.

    I have a question though on the sampling frequency of the IMU - can you speak to any impact slowing the 9250 sampling rate down? I'm currently doing it 100 hz accelerometer and 50 hz for the magnetometer. Was wondering if I could take it down to the same sample rate as the GPS - 10 hz

    ReplyDelete
    Replies
    1. Yes, I found that if you reduce the sample rate per RTIMU's instructions, it would lock up after a few seconds. Essentially, anything other than the maximum sample rate didn't work for me. You change this with the "poll_interval" variable, but I don't remember exactly how.

      So in one of my projects, I simply had it sampling at its maximum rate as it does above, and then my python script just read the reading once very 100ms (so 10hz), then printing the average out once per second. But it would be really easy to just print it out at 10hz too, depending on your application.

      Let me know if that doesn't make sense or if I totally missed your question.

      Delete

Post a Comment

Popular Posts