MPU9250 configuration

I’m looking to cut down on some of the accelerometer and gyroscope noise using the the MPU9250’s built in low pass filters. I’m trying to set both LPFs to a 40Hz cutoff but had some questions on the procedure.

The register that sets the accelerometer LPF is register 29, the value currently set is 0x09. Converting this to binary I get 1001. Based on the data sheet for the device, bit 3 turns on and off the filter and bits 2:0 set the filter value. The confusing part for me is that the data sheet states for the accel_fchoice_b “This register contains accel_fchoice_b (the inverted version of accel_fchoice as described in the table below).” The table shows that accel_fchoice needs to be 1 in order for the filter to be on and the current setting has bit 3 (access_fchoice_b) also equal to 1. How is this the inverted version of itself? What exactly does “inverted version” mean? Would changing the register value to 0x0B set a 40Hz filter?

For the gyroscope, it appears that the filter can be set in the initialization function

bool MPU9250::initialize(int sample_rate_div, int low_pass_filter)

I’m guessing all I would need to set the filer is (based on the MPU9250.cpp file)

MPU9250 imu;

Is this correct? Does the sample_rate_div need to be set?

Looks like sample_rate_div is unused, the low_pass_filter parameter is for the gyro filter. I’m not sure if its enabled.
The accelerometer filter is set in the initialize function with
{0x09, MPUREG_ACCEL_CONFIG_2}, // Set Acc Data Rates, Enable Acc LPF , Bandwidth 184Hz

You might be interested in trying the DMP conversion I made from the arduino.

I understand that the low_pass_filter parameter sets the gyro filter and the MPUREG_ACCEL_CONFIG_2 sees the accelerometer filter, I’m just having a hard time working through the register map since data sheet talks about “inverted version” and I’m not sure what that means. Also the default input for imu initialization is (empty), which I assume means equal to zero. This sets all bits in register 26 to zero which means the LPF is turned off, yet the MPU9250.cpp files says the 184Hz filter is active.

in MPU9250.h

        bool initialize(int sample_rate_div = 1, int low_pass_filter = 0x01);

if you call it like initialize() it will default to 1 and 0x01
But I agree the pdf seems a little confusing as far as fchoice_b is concerned.

Didn’t catch that part when looking through the .h file. Thanks! Based on this

MPU9250 imu;

should set the correct gyro LPF … although like you said, it appears sample_rate_div is unused. I’ll try that for the gyro and 0x0B for the accelerometer config 2 register. Although without doing a frequency response analysis, it will be hard to tell if the filters are set correctly.

Had a flight test this week using the accelerometer and gyro LPF settings given in the previous post. The recorded IMU data was pretty much useless. Anyone else having problems with IMU noise?

I’ve attached plots of the raw output for one data run to illustrate the noise (Accel_x, Gyro_y, aircraft body axis coord system). I also ran a PSD on the data to see what frequencies are contained with in the noise (plots also attached) to check if the source could be vibration.

The x-acceleration PSD plot pretty much shows constant power noise with the possible exception of two peaks. The 4.26Hz peak is most like a subharmonic of the RPM (~123.5Hz during the run) but not sure on the other one. Since the relative power of is pretty low, I don’t think vibration is the cause.

The y-gyro PSD is also relatively flat with the exception of the peak at 0.228Hz which is the frequency of the maneuver performed during the data run. The 4.26Hz peak was also present, but again with relatively low power.

The RPi+NAVIO is vibration isolated from the plane so I wouldn’t think that vibration would be the issue. The one thing that is suspicious though is that the noise appears to be related to throttle. At both the beginning and end of both plots, the noise is much less. The maneuver began with throttle at about 20%, then immediately moved to 100% until the end of the maneuver at which point it was moved back down to 20%. This makes me think it could be vibration or possibly even electrical noise since the the battery cables run about 1.5in below the RPi+NAVIO. The magnetometer data however, appears to be unaffected by either the motor current draw or RPM.

Any ideas?

@larssoltmann those are some complicated questions.

It would probably be good for analysis to turn off any LPFs in MPU, this way we would have pure data to play with. If you are suspecting electrical noise, please try to reproduce this issue with RPi and Navio+ mechanically separated from the vehicle.

Why do you think that this data is not usable? For example ±3G vibration is considered acceptable for APM.

We need to conduct more isolated experiment than a flight, there are just too many factors inolved right now.

It appears the issue is vibration related and I think I have narrowed it down to the way the RPi model B is mounted. Since it only has two mounting holes, the board is able to deflect easily when light pressure is applied to any corner, especially on the corners opposite the mount points.

As far as the data goes, the maneuver performed was estimated to have an Ax value between 0 and 0.2g and with all that noise, its impossible to distinguish the vibration from the actual dynamics. Also, the variance is so high that parameter estimates can not be made with any degree of confidence.

Oh, that explains high vibration. You can get B+ for less than 35$ now and A+ is even cheaper…

What kind of vibration dampening are you using? It’s very possible that your mount has a resonance frequency of around 4Hz and it converts any higher frequency vibration into 4Hz and harmonics. Some time ago I experimented with rubber dampers and while they reduced the motor vibration a lot, they also introduced lower frequency vibrations that were impossible to filter in software because they fell right in the useful bandwidth (<20-30Hz). To fix this I simply placed some earplugs in their center to change their resonance freq.

Anyway, to get better filtering in software - and since the Raspi has enough CPU to do this - I recommend that you disable the LPF in the IMU (184Hz for the gyro and 460Hz for the accel) and create some Butterworth filters with this tool:
I recommend a 15Hz cutoff, 2 or 4 poles.

[edit] The page seems to be broken now. You can use this library to build the filter at runtime: [/edit]

The vibration dampers I am using are these

(it was what was readily available in the lab). For disabling the LPF, are you saying to set them to 184 and 460Hz, or actually set ‘fchoice_b’ in registers 27 and 29 equal to zero to disable them completely?
Since the first flight test I have been filtering the data from all sensors post flight in MATLAB because of the excessive noise, I was just hoping that the built in LPF’s would work better. Thanks for the input!

Don’t disable them completely as that changes the sample rate to 8Khz. Just set them to their maximum values.
Does post-filtering in MATLAB show any promising results? Can you eliminate the noise?

If you use those dampers with only 2 mount points the raspi will most probably resonate. Can you add some earplugs, one under each corner of the raspberry pi and test?

There is a nice writeup of mechanical vibration damping techniques for multirotors in the Arducopter wiki. As the mass is about the same these tricks should also apply to a raspberry pi + Navio combination.

Originally I had the Pi mounted with the vibration mounts at the two mount points on the board but the mounts were soft enough that the Pi would slowly start to list to one side or the other depending on its orientation in space. To counter that problem I laser cut a plywood base that the Pi was firmly mounted to and the base had a vibration mount in each corner (see photo). Even in this configuration, you can still apply light pressure to the Pi and cause the PCB to deflect. I’m fairly certain that this is probably the main cause of vibration. I plan on manufacturing some brackets or something to add some additional mount points between the Pi and the plywood base. Based on the Arducopter wiki link that mfm sent out, I may try and 3D print a custom mount that the Pi would snap into and then mount that to the plane with the vibration mounts. Any design feedback and or input is appreciated.

Filtering the data in MATLAB post flight has been very promising. The Butterworth filter works well and I have also been having success with a moving average filter as the maneuvers performed have very slow dynamics.

You could sandwich some thick foam between the plywood and the PCB.