MPU9250 Add-On for Teensy 3.6

Status
Not open for further replies.
Well, I've been struggling with how best (most efficiently) to read the mag data and on this iteration (I guess I should have posted the entire sketch) I removed the data ready test from the mag data read function (I still check for overlfow) and I am relying only on the data ready read in the main loop. I am trying to minimize reads of mag registers while getting the proper data when ready. This would be so much easier with a proper AK8963C interrupt exposed.

I thought about having a counter and reading the mag data automatically every other MPU6500 data ready interrupt. But probably the best way and the way Invensense intended is to treat the AK8963C as a slave 0 device, have the MPU9250 ASIC read all of the data into the FIFO and then when the mag data is ready read all of the sensors in a single burst read. This is what their DMP does, but this is also why the DMP is limited to 100 Hz quaternion update rates. So there is no perfect solution (except a mag interrupt!).

The other thing I used to do and probably still should is burst read the accel and gyro (and temperature, tucked between them) data and parse the single array into accelerations and rotations. This would save a fair amount of time in I2C transactions for both MCUs and is the righter way to do it without the 100 Hz limitation on the data rate a la Invensense.

Hey Kris, sorry I just saw this - was on holiday for the past couple weeks. My understanding, and the way I think the MPU-9250 was intended to work, is to have the MPU-9250 read the AK8963C at regular intervals. As you point out, you could do this into the FIFO, but it also can dump to the EXT_SENS_DATA_00. Conveniently, this is right next to the accel and gyro data (with temperature in the middle), so you can just do a multi-byte read through all of the sources instead of needing to poll the magnetometer separately. Obviously, the AK8963C data will only be updated at 100 Hz, or 8 Hz if you configure for that, but that's the case no matter what approach is used. At least with this approach you don't have to do any explicit register interaction with the AK8963C after it's all set up - you simply read 21 bytes starting at the ACCEL_XOUT_H register each frame.

Here's a link to my library if that helps:
https://github.com/bolderflight/MPU9250

Brian
 
Thanks for the link, I'll give it a try.

I realized yesterday I am also doing something else not quite right. I am setting the internal sensor rate at 1 kHz, and then setting the DLPF to 41/42 Hz for the accel/gyro. This is all fine. But then I have used a sample rate divider (1 + sampledivider = 1 + 4) to bring the output sample rate to the host to 200 Hz for both accel and gyro, and I think this is wrong. The DLPF of 41/42 Hz requires 5.9 ms delay time for the ASIC to do the averaging. The maximum host read rate therefore should be 170 Hz, so a smaple divide of 1 + 5 would be more appropriate to read the data at 167 Hz. If I use a 91/92 Hz DLPF filter bandwidth instead this brings the delay time down to 3.9 ms which will support a sampledivide of 1 + 3 and a corresponding 250 Hz host sample read rate. The downside to the flexible configurability of the MPU9250 accel/gyro is the complication of it all.
 
Thanks for the link, I'll give it a try.

I realized yesterday I am also doing something else not quite right. I am setting the internal sensor rate at 1 kHz, and then setting the DLPF to 41/42 Hz for the accel/gyro. This is all fine. But then I have used a sample rate divider (1 + sampledivider = 1 + 4) to bring the output sample rate to the host to 200 Hz for both accel and gyro, and I think this is wrong. The DLPF of 41/42 Hz requires 5.9 ms delay time for the ASIC to do the averaging. The maximum host read rate therefore should be 170 Hz, so a smaple divide of 1 + 5 would be more appropriate to read the data at 167 Hz. If I use a 91/92 Hz DLPF filter bandwidth instead this brings the delay time down to 3.9 ms which will support a sampledivide of 1 + 3 and a corresponding 250 Hz host sample read rate. The downside to the flexible configurability of the MPU9250 accel/gyro is the complication of it all.

I think that's actually fine. I'm not sure what type of DLPF they're using, but I would guess something along the lines of an approximate moving average:
x + CM * (N - 1)/N

Where x is the current value, CM is the previous average, and N is the number of samples in the window. In this case, if you're sampling the sensor at 200 Hz, then the moving average is updated every 5 ms, but there is some delay (roughly equal to half the window size) that needs to be taken into account if you're considering gain and phase margins of a controller, for instance. If they are using a moving average filter, the delay would be (N-1)/2 samples. In other words, you'll get new data every 5 ms, but the new data is inherently delayed due to the filter, which might be a concern for stability of a controller using the data from the MPU-9250. I don't think it would be a concern for most applications though, I would expect most dynamics (i.e. cars, aircraft, people walking or moving) to be in the 1 - 10 Hz range. Really, as a general recommendation, I would set the frame rate of the host first and then just make sure the MPU-9250 DLPF bandwidth is 2 - 3 times slower to avoid aliasing.

Brian
 
I think you are right about being able to ignore this generally (I have so far). However, for flying robots respecting the DLPF delay limits is probably the wiser course.

I took a look at your repository and the functions are straightforward. One thing I don't like about having the MPU6500 manage the AK8963C is that the data is either limited to 100 Hz output rate (like the MPU6500 DMP) or mag data is read multiple times before refreshing. I'll stick to the polling I am doing now. It is simpler and seems to me to be no less efficient than making use of the SLV0 register. I would still prefer a dedicated mag sensor interrupt.
 
Hi Kris

first of all - thanks a lot for your answers and the coding you provided. It helped me a lot in putting forward my project, which is now alive and running. Serious testing needs to be done but for the time being it looks like it is working like a charm.



Missed this.

Units of deltat are seconds.

Generally 4 -5x the sample data rate should be sufficient. It depends somewhat on the application. Best is to try it at 5x and 10x for your application. There is a point of diminishing returns, since the algorithm will eventually asymptote to a solution for a given set of data.

>> I tested 5 to 10 times the sampling rate - could not see a big difference. But I did not test with collecting data and analysis.

About every second read, it's not exact and syncing can be a problem. Usually I ignore rigorous timestamping in these simple sketches but the MPU9250 allows such if you treat the AK8963 as a SLV0 device, read its data using the internal I2C bus into the FIFO, and then read the time aligned data from the FIFO to the host. But if you do, the data rate is somehow clamped at 100 Hz, so there is a tradeoff. Generally I would recommend running the gyro and accel at 400 Hz, the mag at 100 Hz, and running the fusion rate at 2 kHz. This should be adequate for most human and flying robot applications.

>> I have some doubts whether syncing of incoming data is at the end that important. Just for fun I put acc gyro and mag values somewhat out of sync and the system at least did not flip over. No question - good syncing is nice to have.

The DPLF doesn't affect the sample rates or introduce time delays per se. The accel data is available to the internal ASIC at 1 kHz and the gyro data at 8 kHz. The DPLF simply determines how these data are averaged internally. They are still provided to the host at 200 Hz or 400 Hz or whatever is specified. But is a constraint, of course. There are certain combinations of data rate and LPF allowed and others not. Consult the data sheet.

>>The DPLF has a the delay of up to 66ms, the refresh rate stays al the time at 1khz. Something does not add up. Data out of DPLF might be "old". The AK8963 can deliver data at 100 hz - my conclusion was, that mag data might be fresher than filtered acc/gyro data. From here came my question. I read out all 9250 data interrupt driven at around 100hz at once.

It is unlikely (I won't say impossible) that the mag data is fresher than the accel/gyro data.Of course, if you set the accel/gyro sample rates at 10 Hz and the mag at 100 Hz this is exactly what you would get. The orientation solution is dominated by the gyro and the fusion filter rate needs to be sized according to the gyro rate. The accel and mag are helper functions to correct for gyro drift. So if you run the gyro at 1 kHz and the accel and mag at 100 Hz, you are likely to get a very reasonable orientation solution provided you run the Madgwick/Mahony fusion at 2 kHz or higher.

Best is to test out the parameters in your particular application. It might be surprising to some, but this is more art than science. While the basic principles are fairly well understood, the applications vary widely and there is no one-size-fits-all solutions that I am aware of.

I commented your post above, see >>

Is there also a Madwick for accel/gyro fusion only ?

By the way : corrected/calibrated gyro offsets can in my opinion be written back. This takes away a little bit of computation. See comment in your github lacation.

best regards Andi
 
Last edited:
I think you are right about being able to ignore this generally (I have so far). However, for flying robots respecting the DLPF delay limits is probably the wiser course.

I guess what I'm saying is that the DLPF delay is a phase delay in the measured signal rather than a computational delay in the ASIC, which is why the DLPF bandwidth isn't tied to the sample rate divider. Working with UAVs as well, typically for rigid vehicles, the control requirements are actually pretty slow even for unstable vehicles. 50 Hz update rates for the flight control and 20 Hz bandwidth for sensor filters seem to work well for many vehicles. Granted, depending on the AHRS or EKF filter used for attitude, that loop may need to run much faster, as your work has shown.

I took a look at your repository and the functions are straightforward. One thing I don't like about having the MPU6500 manage the AK8963C is that the data is either limited to 100 Hz output rate (like the MPU6500 DMP) or mag data is read multiple times before refreshing. I'll stick to the polling I am doing now. It is simpler and seems to me to be no less efficient than making use of the SLV0 register. I would still prefer a dedicated mag sensor interrupt.

I was going to say that I'm not sure how you're polling the AK8963C faster than 100 Hz, but looking through the datasheet again, I think I see what you're saying. The datasheet doesn't actually give a maximum output rate for the sensor, just that in continuous mode you can select between 100 Hz and 8 Hz. In other words, it may be able to output data faster than 100 Hz in single shot mode. Have you measured the delay between requesting data, in single shot mode, and the data being ready? I agree, I would prefer a dedicated mag interrupt and more choices for continuous output rates (i.e. a sample rate divider off the maximum output rate).
 
I nowhere read that data out of the filters is ready in sync. Since you can select different filter bandwiths its may out of sync anyway and shows up as soon as ready to be packed into the FIFO. Maybe its bold to say that - give the noise these sensors have, timing is maybe a problem, but not the biggest one. I made my life simple - I just take all the data out at 100hz and I am quite happy about it.
 
I was simple saying that if I read all data at 200 Hz I am by definition reading 100 Hz mag data twice anyway. But this is a good idea, to run the mag in single shot mode and then I could run at 200 Hz. Haven't tried this yet.

We are running our flight control loop at 1 kHz (yes, 1 ms loop time!) and this provides a much more stable flight for very small UAVs.
 
I just take all the data out at 100hz and I am quite happy about it

And for the majority of applications this is just fine.

But then maybe a DLPF of 20 Hz would be better.
 
Last edited:
I was simple saying that if I read all data at 200 Hz I am by definition reading 100 Hz mag data twice anyway. But this is a good idea, to run the mag in single shot mode and then I could run at 200 Hz. Haven't tried this yet.

We are running our flight control loop at 1 kHz (yes, 1 ms loop time!) and this provides a much more stable flight for very small UAVs.

You say the control loop is going at 1 kHz. Could you please be more specific ? The control loop (whatever it finally is) runs at 1kHz. Is it correct, that data acquisition runs in the region of 50 to 200 Hz, depending on sensor, gets some filtering (maybe not, I was a little surprised by what the Madwick did - does it need filtering in advance ?), runs into a fusion process that runs at around 500 Hz and then the results end in the control loop working at 1kHz ?
 
Yes, gyro at 1 kHz, quaternion update at 100 Hz, and control loop at 1 kHz. But this is not a Madgwick fusion filter. My point was that some flying robots need greater than 50 Hz update rates.
 
Status
Not open for further replies.
Back
Top