kriswiner / MPU9250

Arduino sketches for MPU9250 9DoF with AHRS sensor fusion
1.02k stars 469 forks source link

How to verify if calibration is OK #55

Open djsg opened 8 years ago

djsg commented 8 years ago

Hello Kris,

I have implemented your code for 9250 with STM32F401 MCU. The problem that I have is when sensor is flat and still, the calculated Q values are changing at a constant speed (big drifting). I suspect there is something wrong with the calibration, since wrong bias values would cause that. But how to verify calibration is OK or not. The following are the biases values I got from function mpu9250.calibrateMPU9250() gyro bias (-0.992366, -1.099237, 0.648855) accel bias (0.022339, 0.030212, 0.062500) Do you think they make sensse?

Thx & regards DJ

kriswiner commented 8 years ago

If the biases are dps and gs, then yes they make sense. But if you have not calibrated the mag you will get the kind of drift you describe. See here:

https://github.com/kriswiner/MPU-6050/wiki/Simple-and-Effective-Magnetometer -Calibration

Kris

-----Original Message----- From: djsg [mailto:notifications@github.com] Sent: March 30, 2016 10:57 PM To: kriswiner/MPU-9250 Subject: [kriswiner/MPU-9250] How to verify if calibration is OK (#55)

Hello Kris,

I have implemented your code for 9250 with STM32F401 MCU. The problem that I have is when sensor is flat and still, the calculated Q values are changing at a constant speed (big drifting). I suspect there is something wrong with the calibration, since wrong bias values would cause that. But how to verify calibration is OK or not. The following are the biases values I got from function mpu9250.calibrateMPU9250() gyro bias (-0.992366, -1.099237, 0.648855) accel bias (0.022339, 0.030212, 0.062500) Do you think they make sensse?

Thx & regards DJ

You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/kriswiner/MPU-9250/issues/55 https://github.com/notifications/beacon/AGY1qsNtP8o5jDA7Y7aeVR2GrLhkvXyOks5 py2IZgaJpZM4H8cRf.gif

djsg commented 8 years ago

I've read through that post. So my understanding of the proper way of using magnetometer calibration is (1) code a separate sensor application with function magcalMPU9250(float * dest1, float * dest2) to get mag bias and mag calibration values. While running the application, we should move the sensor board in a figure 8 pattern. The bias and calibration values should not change much after sensor board is manufactured. To be more prudent, we'd better do this from time to time. (2) with that six values, I can use your 9250 code (https://github.com/kriswiner/MPU-9250/tree/master/STM32F401) to calculate mag(x, y, z). as mx = (float)magCount[0]_mRes_magCalibration[0] - magbias[0]; my = (float)magCount[1]_mRes_magCalibration[1] - magbias[1];
mz = (float)magCount[2]_mRes_magCalibration[2] - magbias[2]; Is it correct?

Then function mpu9250.initMPU9250() in MPU9250.h is not useful any more, isn't it?

kriswiner commented 8 years ago

This is the correct procedure but I do this as part of the initialization in the setup; that is I calibrate accel, gyro, and mag each time I power on. You could do so well once and store the values for later. You will still need to initialize the MPU9250 for full range, sample rate, setting bypass, setup interrupt, etc.

-----Original Message----- From: djsg [mailto:notifications@github.com] Sent: March 31, 2016 7:22 PM To: kriswiner/MPU-9250 Cc: Kris Winer Subject: Re: [kriswiner/MPU-9250] How to verify if calibration is OK (#55)

I've read through that post. So my understanding of the proper way of using magnetometer calibration is (1) code a separate sensor application with function magcalMPU9250(float dest1, float \ dest2) to get mag bias and mag calibration values. While running the application, we should move the sensor board in a figure 8 pattern. The bias and calibration values should not change much after sensor board is manufactured. To be more prudent, we'd better do this from time to time. (2) with that six values, I can use your 9250 code (https://github.com/kriswiner/MPU-9250/tree/master/STM32F401) to calculate mag(x, y, z). as mx = (float)magCount[0]mResmagCalibration[0] - magbias[0]; my = (float)magCount[1]mResmagCalibration[1] - magbias[1];

mz = (float)magCount[2]mResmagCalibration[2] - magbias[2]; Is it correct?

Then function mpu9250.initMPU9250() in MPU9250.h is not useful any more, isn't it?

You are receiving this because you commented. Reply to this email directly or view it on GitHub https://github.com/kriswiner/MPU-9250/issues/55#issuecomment-204213972 https://github.com/notifications/beacon/AGY1quIwav9TE194XpKbgcCdunZOYvS3ks5 pzIE_gaJpZM4H8cRf.gif

djsg commented 8 years ago

Sorry, I meant mpu9250.initAK8963(magCalibration) is not useful, since there is better function to obtain mag calibration values.

The conditions to calibrate accel, and gyro, and to calibrate mag are different, how you do it during initialization, one after another?

kriswiner commented 8 years ago

Yes, like this now since I don't use the ST device much anymore:

https://github.com/kriswiner/MPU-9250/blob/master/MPU9250_MS5637_AHRS_t3.ino

-----Original Message----- From: djsg [mailto:notifications@github.com] Sent: March 31, 2016 8:10 PM To: kriswiner/MPU-9250 Cc: Kris Winer Subject: Re: [kriswiner/MPU-9250] How to verify if calibration is OK (#55)

Sorry, I meant mpu9250.initAK8963(magCalibration) is not useful, since there is better function to obtain mag calibration values.

The conditions to calibrate accel, and gyro, and to calibrate mag are different, how you do it during initialization, one after another?

You are receiving this because you commented. Reply to this email directly or view it on GitHub https://github.com/kriswiner/MPU-9250/issues/55#issuecomment-204226413 https://github.com/notifications/beacon/AGY1qqja2hsas2PmAyWt_f4lCLoAFGB3ks5 pzIyHgaJpZM4H8cRf.gif

djsg commented 8 years ago

In function accelgyrocalMPU9250, why do you use FIFO to read acc and gyro data? Is there any particular reason? In my test, I've found the some readings from FIFO have big differences from the values I directly read from data register when sensor remains still at the same position. Actually the FIFO readings are a little bit off the expected values as showed below: (ax, ay, az, gx, gy, gz) (68, 232, 17400, -467, 107, -138) (84, 168, 17388, -458, 123, -113) (140, 104, 17388, -460, 131, -94) (176, 124, 17416, -463, 116, -77) (156, 216, 17428, -461, 108, -72) (108, 220, 17504, -467, 127, -85) while what I get from data registers is, which seems better acc (-1479.0000, -10.0000, 16479.0000, ) tempeture = 29.94 gyro (-6.0000, 2.0000, -24.0000, ) acc (-1485.0000, -9.0000, 16485.0000, ) tempeture = 29.98 gyro (-21.0000, 11.0000, -5.0000, ) acc (-1500.0000, 14.0000, 16548.0000, ) tempeture = 29.96 gyro (-27.0000, 0.0000, -6.0000, ) acc (-1500.0000, -12.0000, 16479.0000, ) tempeture = 30.00 gyro (-35.0000, -3.0000, -11.0000, ) acc (-1501.0000, -39.0000, 16528.0000, ) tempeture = 30.00 gyro (-176.0000, 100.0000, 32.0000, ) I guess I'd better use data from data register to do calibration.

kriswiner commented 8 years ago

You can use either but FIFO works well.

Sent from my iPhone

On Apr 3, 2016, at 9:22 PM, djsg notifications@github.com wrote:

In function accelgyrocalMPU9250, why do you use FIFO to read acc and gyro data? Is there any particular reason? In my test, I've found the some readings from FIFO have big differences from the values I directly read from data register when sensor remains still at the same position. Actually the FIFO readings are a little bit off the expected values as showed below: (ax, ay, az, gx, gy, gz) (68, 232, 17400, -467, 107, -138) (84, 168, 17388, -458, 123, -113) (140, 104, 17388, -460, 131, -94) (176, 124, 17416, -463, 116, -77) (156, 216, 17428, -461, 108, -72) (108, 220, 17504, -467, 127, -85) while what I get from data registers is, which seems better acc (-1479.0000, -10.0000, 16479.0000, ) tempeture = 29.94 gyro (-6.0000, 2.0000, -24.0000, ) acc (-1485.0000, -9.0000, 16485.0000, ) tempeture = 29.98 gyro (-21.0000, 11.0000, -5.0000, ) acc (-1500.0000, 14.0000, 16548.0000, ) tempeture = 29.96 gyro (-27.0000, 0.0000, -6.0000, ) acc (-1500.0000, -12.0000, 16479.0000, ) tempeture = 30.00 gyro (-35.0000, -3.0000, -11.0000, ) acc (-1501.0000, -39.0000, 16528.0000, ) tempeture = 30.00 gyro (-176.0000, 100.0000, 32.0000, ) I guess I'd better use data from data register to do calibration.

— You are receiving this because you commented. Reply to this email directly or view it on GitHub

kriswiner commented 8 years ago

You can do I either way, the test though is at rest do you read 0, 0, and 1 for the acceleration in gs?

-----Original Message----- From: djsg [mailto:notifications@github.com] Sent: April 3, 2016 9:23 PM To: kriswiner/MPU-9250 Cc: Kris Winer Subject: Re: [kriswiner/MPU-9250] How to verify if calibration is OK (#55)

In function accelgyrocalMPU9250, why do you use FIFO to read acc and gyro data? Is there any particular reason? In my test, I've found the some readings from FIFO have big differences from the values I directly read from data register when sensor remains still at the same position. Actually the FIFO readings are a little bit off the expected values as showed below:

(ax, ay, az, gx, gy, gz) (68, 232, 17400, -467, 107, -138) (84, 168, 17388, -458, 123, -113) (140, 104, 17388, -460, 131, -94) (176, 124, 17416, -463, 116, -77) (156, 216, 17428, -461, 108, -72) (108, 220, 17504, -467, 127, -85) while what I get from data registers is, which seems better acc (-1479.0000, -10.0000, 16479.0000, ) tempeture = 29.94 gyro (-6.0000, 2.0000, -24.0000, ) acc (-1485.0000, -9.0000, 16485.0000, ) tempeture = 29.98 gyro (-21.0000, 11.0000, -5.0000, ) acc (-1500.0000, 14.0000, 16548.0000, ) tempeture = 29.96 gyro (-27.0000, 0.0000, -6.0000, ) acc (-1500.0000, -12.0000, 16479.0000, ) tempeture = 30.00 gyro (-35.0000, -3.0000, -11.0000, ) acc (-1501.0000, -39.0000, 16528.0000, ) tempeture = 30.00 gyro (-176.0000, 100.0000, 32.0000, ) I guess I'd better use data from data register to do calibration.

You are receiving this because you commented. Reply to this email directly or view it on GitHub https://github.com/kriswiner/MPU-9250/issues/55#issuecomment-205131585 https://github.com/notifications/beacon/AGY1qqA7AUD9mVNM2LdWJrnBoIQ7OTZJks5 p0JIHgaJpZM4H8cRf.gif

djsg commented 8 years ago

I would say yes if you look at the raw acc reading (68, 232, 17400) divided by 16384, we get (0.04, 0.14, 1.06). Now I know why there are difference: it is caused by the following code:

// Push gyro biases to hardware registers writeByte(MPU9250_ADDRESS, XG_OFFSET_H, data[0]); ... If I disable pushing biases back to acc and gyro, the FIFO readings are similar to data register ones. In your function accelgyrocalMPU9250, you mention "Apparently this is not working for the acceleration biases in the MPU-9250"; however, I found with and without that pushing back, acc readings have difference.

BTW, do you sell any evaluation board with 9250? How much does it cost?

kriswiner commented 8 years ago

Take a look here:

https://www.tindie.com/products/onehorse/mpu9250-teensy-31-add-on-shields/

-----Original Message----- From: djsg [mailto:notifications@github.com] Sent: April 4, 2016 7:24 PM To: kriswiner/MPU-9250 Cc: Kris Winer Subject: Re: [kriswiner/MPU-9250] How to verify if calibration is OK (#55)

I would say yes if you look at the raw acc reading (68, 232, 17400) divided by 16384, we get (0.04, 0.14, 1.06). Now I know why there are difference: it is caused by the following code:

// Push gyro biases to hardware registers writeByte(MPU9250_ADDRESS, XG_OFFSET_H, data[0]); ... If I disable pushing biases back to acc and gyro, the FIFO readings are similar to data register ones. In your function accelgyrocalMPU9250, you mention "Apparently this is not working for the acceleration biases in the MPU-9250"; however, I found with and without that pushing back, acc readings have difference.

BTW, do you sell any evaluation board with 9250? How much does it cost?

You are receiving this because you commented. Reply to this email directly or view it on GitHub https://github.com/kriswiner/MPU-9250/issues/55#issuecomment-205602752 https://github.com/notifications/beacon/AGY1qt0W9PoisC7Rri09pIToGaA6Ibg0ks5 p0cfTgaJpZM4H8cRf.gif

saedelman commented 5 years ago

I'm using your code at:

https://github.com/kriswiner/MPU9250/blob/master/STM32F401/MPU9250.h

I've used MagMaster/MagViewer to determine the bias values and transformation matrix and added the necessary code. I've confirmed that the values are properly centered around 0,0,0 using MagViewer when moving the MPU9250 in an 8. I'm getting stable values for pitch, roll and yaw, however, regardless of the physical orientation of MPU9250 on startup, it always starts with a pitch of -180 and a roll value of 0. When I move the MPU9250, the yaw, pitch and roll appear to be increasing/decreasing as expected, it looks like a 6DOF solution instead of a 9DOF with absolute reference. Any ideas why this would be?

kriswiner commented 5 years ago

Well one reason is if you are initializing your quaternion to 1 0 0 0 this is always what will determine yap, pitch, and roll on startup until the quaternions converge to the solution required by the sensor readings. Also, you will need to feed the fusion filter (Madgwick or Mahony) the sensor data in the proper order (NED) for your choice of which board edge is to be North. If these values are incorrect (and Ax, Ay, Az, Gx, Gy, Gz, Mx, My, Mz is incorrect) then you will not get accurate results.

On Fri, Aug 17, 2018 at 6:27 PM Stephan Edelman notifications@github.com wrote:

I'm using your code at:

https://github.com/kriswiner/MPU9250/blob/master/STM32F401/MPU9250.h

I've used MagMaster/MagViewer to determine the bias values and transformation matrix and added the necessary code. I've confirmed that the values are properly centered around 0,0,0 using MagViewer when moving the MPU9250 in an 8. I'm getting stable values for pitch, roll and yaw, however, regardless of the physical orientation of MPU9250 on startup, it always starts with a pitch of -180 and a roll value of 0. When I move the MPU9250, the yaw, pitch and roll appear to be increasing/decreasing as expected, it looks like a 6DOF solution instead of a 9DOF with absolute reference. Any ideas why this would be?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-414022799, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qlWNrFL7JqXe9FNgDayYQM1w77BRks5uR211gaJpZM4H8cRf .

saedelman commented 5 years ago

I guess the fusion filter update rate was too low, so I did not see that the yaw is actually drifting. I've increased the rate to the maximum possible in our environment and will check that the data is being feed in the proper NED order. I'm getting slightly better performance out of the Mahony fusion solution, so that is what I am using and getting approx. 500 iterations per second. This hopefully should be enough for an update rate of 5Hz or less. We're not controlling any servos, only data logging.

kriswiner commented 5 years ago

500 Hz is a bit low, surprisingly so for an F401. I would run the gyro/accel at 1 kHz and expect you cvould get 5 - 10 iterations for each data sample using an F401. Are you using 400 kHz for the I2C bus speed? Maybe try 1 MHz?

On Fri, Aug 17, 2018 at 7:54 PM Stephan Edelman notifications@github.com wrote:

I guess the fusion filter update rate was too low, so I did not see that the yaw is actually drifting. I've increased the rate to the maximum possible in our environment and will check that the data is being feed in the proper NED order. I'm getting slightly better performance out of the Mahony fusion solution, so that is what I am using and getting approx. 500 iterations per second. This hopefully should be enough for an update rate of 5Hz or less. We're not controlling any servos, only data logging.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-414027618, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qsnIhm_mRTBQuGbfgy8OTeukzDcFks5uR4HsgaJpZM4H8cRf .

saedelman commented 5 years ago

I'm running on a Nordic NRF52832, but running multiple threads for various other tasks including BLE services. I'm already running at 400 kHz for the I2C bus speed, the TWI hardware does not support 1MHz. I don't have the PCB real-estate for an EM7180, otherwise I would have used it. I've managed to fit the MPU9250 in the lower right hand corner of our PCB and no parts or copper on any of the 4 layers directly above it and that was a tremendous challenge given the density of our board (took us 2 months nudging the autorouter to a solution). I used your MPU9250 PCB footprint, but I think the pads are too long for a QFN package and can probably be halved.

kriswiner commented 5 years ago

Yes, you can shorten the pads, I have on some other designs. The nRF52 can run the fusion at > 1 kHz IIRC, been a while since I checked. I usually get pretty good results using the nRF52 + MPU9250 even with BLE running using this https://www.tindie.com/products/onehorse/nrf52832-development-board/ board. I think even at 400 kHz bus speed you should be able to get much higher fusion rates. Are you using the interrupt for data ready; I would recommend this.

TWI in the nRF52 is seriously messed up. There is no hardware TWI per se, everything is done in software and poorly at that. One of many silicon errors made by Nordic with this chip (I2S being the other major screw up).

On Fri, Aug 17, 2018 at 8:30 PM Stephan Edelman notifications@github.com wrote:

I'm running on a Nordic NRF52832, but running multiple threads for various other tasks including BLE services. I'm already running at 400 kHz for the I2C bus speed, the TWI hardware does not support 1MHz. I don't have the PCB real-estate for an EM7180, otherwise I would have used it. I've managed to fit the MPU9250 in the lower right hand corner of our PCB and no parts or copper on any of the 4 layers directly above it and that was a tremendous challenge given the density of our board (took us 2 months nudging the autorouter to a solution). I used your MPU9250 PCB footprint, but I think the pads are too long for a QFN package and can probably be halved.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-414029051, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qvEXy02770yL8uIujLCk4FalSo9bks5uR4pXgaJpZM4H8cRf .

saedelman commented 5 years ago

We're using a Taiyo Yuden certified module with integrated NRF52832. The upside is that it has integrated antenna and does not require us to obtain FCC/IC certification, but the downside is that there are limited I/O pins brought out from the chip so I am not using an interrupt pin for data ready, merely checking the MPU9250 INT_STATUS flag and AK8963 status flag. I'm sure that lowers our fusion rate a bit, but the biggest hit is that we are running 5 other threads.

You are absolutely correct regarding the TWI on the NRF52. At one point we were bit banging I2C because their driver did not play nice between threads. We have now moved all I2C functions to one thread to avoid that scenario altogether.

kriswiner commented 5 years ago

Probably too late, but you might consider Rigado's BMD-350. It is an excellent module, easy to use, very small, and all of the pins are exposed to the user. I use them for all of my BLE work (except for those cutomers who insist on the ESP32).

On Fri, Aug 17, 2018 at 9:09 PM Stephan Edelman notifications@github.com wrote:

We're using a Taiyo Yuden certified module with integrated NRF52832. The upside is that it has integrated antenna and does not require us to obtain FCC/IC certification, but the downside is that there are limited I/O pins brought out from the chip so I am not using an interrupt pin for data ready, merely checking the MPU9250 INT_STATUS flag and AK8963 status flag. I'm sure that lowers our fusion rate a bit, but the biggest hit is that we are running 5 other threads.

You are absolutely correct regarding the TWI on the NRF52. At one point we were bit banging I2C because their driver did not play nice between threads. We have now moved all I2C functions to one thread to avoid that scenario altogether.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-414030699, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qtlyaJsLG18sQRvyF3CQgpcxuovQks5uR5NrgaJpZM4H8cRf .

saedelman commented 5 years ago

Thanks for the heads up, I have not seen the BMD-350 before. The module is twice the width of the Taiyo Yuden module that we are using (EYSHJNZXZ) and longer also. The BMD-350 is 10mm wide and the TY is 5mm wide. The price on the BMD-350 is excellent (about the same price at 1000 pieces as the TY) and best of all, easy to get (DigiKey/Mouser/etc.). I'll have to keep it in mind.

kriswiner commented 5 years ago

" The BMD-350 is a variant of our BMD-300 module in an ultra-compact 6.4 x 8.65 x 1.5mm package."

https://www.rigado.com/products/modules/bmd-350/

The EYSHJNZXZ is 5.1 x 11.3 mm, about the same area but the BMD-350 exposes all 32 of the pins, not just 20.

On Fri, Aug 17, 2018 at 10:42 PM Stephan Edelman notifications@github.com wrote:

Thanks for the heads up, I have not seen the BMD-350 before. The module is twice the width of the Taiyo Yuden module that we are using (EYSHJNZXZ) and longer also. The BMD-350 is 10mm wide and the TY is 5mm wide. The price on the BMD-350 is excellent (about the same price at 1000 pieces as the TY) and best of all, easy to get (DigiKey/Mouser/etc.). I'll have to keep it in mind.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-414034154, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qlUGZbKiI95utDYTpOLeH1pyx2WTks5uR6kqgaJpZM4H8cRf .

saedelman commented 5 years ago

You are correct, my previous comments were for a 9.8mm x 14mm package which appears to be for the BMD-300 module. The only downside I see at first glance with the BMD-350 6.4mm x 8.65mm package is that limited fanout is possible using 4/5mil traces so laser-drilled via-in-pads are necessary to access all the pins. A regular (rotating) drill would likely lift the pad, so manufacturing cost would be higher and provide fewer board shops that can do this. It would likely still work for us without via-in-pad as we don't need all the pins. I'll have a serious look at this option. Thanks again for providing it.

saedelman commented 5 years ago

Just checked the pad spacing using the part library (https://www.rigado.com/download/bmd-350-altium-library/ and https://www.rigado.com/download/bmd-350-eagle-library/) by RIGADO and it appears fanout is possible without resorting to via-in-pad.

kriswiner commented 5 years ago

Yes, I use OSHPark https://www.oshpark.com/#support 4-layer fab rules to expose all of the pins to the board without fancy fab methods. A very easy-to-use and assemble module.

On Sat, Aug 18, 2018 at 6:00 AM Stephan Edelman notifications@github.com wrote:

Just checked the pad spacing using the part library ( https://www.rigado.com/download/bmd-350-altium-library/ and https://www.rigado.com/download/bmd-350-eagle-library/) by RIGADO and it appears fanout is possible without resorting to via-in-pad.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-414056329, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qtZlugV222ERdejmCsBAPN6wQ_-Cks5uSA_SgaJpZM4H8cRf .

saedelman commented 5 years ago

We're using PCBWay in Shenzhen. Not generally a fan of board shops and CMs in China, but it looks like PCBWay is run by a Chinese American who understands western standards. They provide tracking of your order through their entire manufacturing process, showing the date and time of the 12 or so steps in the process. They typically finish a 4-layer board in 2 days and delay it in shipping depending on what service option you chose (24 hour, 48 or 72 hour turn). The have 8mil minimum drill, and 4/4mil traces/separation, 10mill for ground pours. They do automated visual inspection and netlist continuity checking of all boards included in the price. I have used them over a dozen times and typically rate their quality as good or better than locally sourced boards. Especially when it comes to registration (drill holes centered in via pads), they are consistently excellent. For price comparison, local shops charge me around $1000 for 10 4-layer boards with gold immersion and double-sided silk and one week turn and PCBWay does the same job in the same time (in hand) for $178 including shipping.

kriswiner commented 5 years ago

Sounds pretty good. OSH Park charges $10 per sq. inch fpr 4-layer boards and you get 3 each per order, so three 1 sq. inch boards is $10. The turn around is two weeks or so but for prototype work this is perfect.

On Sat, Aug 18, 2018 at 3:36 PM Stephan Edelman notifications@github.com wrote:

We're using PCBWay in Shenzhen. Not generally a fan of board shops and CMs in China, but it looks like PCBWay is run by a Chinese American who understands western standards. They provide tracking of your order through their entire manufacturing process, showing the date and time of the 12 or so steps in the process. They typically finish a 4-layer board in 2 days and delay it in shipping depending on what service option you chose (24 hour, 48 or 72 hour turn). The have 8mil minimum drill, and 4/4mil traces/separation, 10mill for ground pours. They do automated visual inspection and netlist continuity checking of all boards included in the price. I have used them over a dozen times and typically rate their quality as good or better than locally sourced boards. Especially when it comes to registration (drill holes centered in via pads), they are consistently excellent. For price comparison, local shops charge me around $1000 for 10 4-layer boards with gold immersion and double-sided silk and one week turn and PCBWay does the same job in the same time (in hand) for $178 including shipping.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-414090310, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qqTfo8AHRDOQ-3MBe1_tSao601Zkks5uSJbUgaJpZM4H8cRf .

saedelman commented 5 years ago

That is very attractive pricing for US sourced boards. Our boards are actually 5/5mil, but their 10mil minimum drill would require us to increase the annular ring diameter of our vias, which would break the design rules for clearance and require a reroute. I'll keep them in mind for other projects.

kriswiner commented 5 years ago

Yes, I would prefer small minimum drills also, but you can't have everything I suppose. Their quality is usually excellent but occasionally there is a hiccup. I have had problems with 2-layer boards years ago, not so much with the 4-layer; these days the quality is more consistently excellent to outstanding. When there is a problem they are very responsive and quick to rerun or refund as desired. For prototyping this is a great service (free shipping anywhere in the world). But for production I go to China.

On Sat, Aug 18, 2018 at 3:56 PM Stephan Edelman notifications@github.com wrote:

That is very attractive pricing for US sourced boards. Our boards are actually 5/5mil, but their 10mil minimum drill would require us to increase the annular ring diameter of our vias, which would break the design rules for clearance and require a reroute. I'll keep them in mind for other projects.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-414091118, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qmMoG583pN6upj1TygkfbPsFMhNfks5uSJuKgaJpZM4H8cRf .

saedelman commented 5 years ago

I've created a small test program and I'm able to get approx. 3600 iterations/second out of Mahony on the NRF52832. This is primarily limited by the I2C clock speed of 400KHz. I'm finding that Mahony fusion produces less jitter compared to Madgwick and is also less computationally expensive. What initially surprised me was that when dropping the iterations to around 250/second (which is what we can achieve in our I2C worker thread), the convergence is not much worse than running at 3600 iterations/second. This makes some sense as the integration being done in the algorithm is now over a longer time period producing a larger correction input on the subsequent iteration and therefore convergence is about the same but with more jitter. I can live with that because we only need at output from the fusion solution at 5Hz.

I am going to try and drive up the I2C clock speed by using our bit-banged library, but there are other I2C devices on the bus that may not like this and inadvertently become asserted and corrupt the data on the bus. We'll see.

kriswiner commented 5 years ago

What accel/gyro rate are you using? I would recommend 1 kHz for best results, but you might not need best results in your application...

~3 kHz fusion rate is about what I remember getting in my tests as well.

On Sun, Aug 19, 2018 at 7:34 AM Stephan Edelman notifications@github.com wrote:

I've created a small test program and I'm able to get approx. 3600 iterations/second out of Mahony on the NRF52832. This is primarily limited by the I2C clock speed of 400KHz. I'm finding that Mahony fusion produces less jitter compared to Madgwick and is also less computationally expensive. What initially surprised me was that when dropping the iterations to around 250/second (which is what we can achieve in our I2C worker thread), the convergence is not much worse than running at 3600 iterations/second. This makes some sense as the integration being done in the algorithm is now over a longer time period producing a larger correction input on the subsequent iteration and therefore convergence is about the same but with more jitter. I can live with that because we only need at output from the fusion solution at 5Hz.

I am going to try and drive up the I2C clock speed by using our bit-banged library, but there are other I2C devices on the bus that may not like this and inadvertently become asserted and corrupt the data on the bus. We'll see.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-414131793, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qiXyY0oXenjFkf3hWps3q3GhYXUfks5uSXdZgaJpZM4H8cRf .

saedelman commented 5 years ago

I should clarify that the 3600 iterations/sec represents the number of calls to the Mahony fusion function. This does not mean that I am feeding the Mahony function with new data with each call. I am not using hardware interrupt, but merely checking the INT_STATUS flag in the MPU9250 by making an I2C read call, so the actual data rate into the Mahony function will be less. I will add a couple of additional counters to show the data rate from the accel/gryo and the Magnetometer (which produces data at a lower rate) and report back. With respect to the accel/gyro, the data rate is set to 1KHz:

writeByte(MPU9250_ADDRESS, CONFIG, 0x03);

kriswiner commented 5 years ago

Generally by the "fusion rate" I mean how many times the fusion filter is called per data (usually gyro) sample. 5 - 10x is optimum.

So if you are sampling data at 1 kHz and calling the fusion filter at 3.6 kHz this is 3.6x, which shouldn't be too bad.

It is really more complicated than this since in reality when the filter is called it is generally called with the same sensor data input which would ordinarily lead to a false rotation impulse but because the deltat in the loop (with a fast enough processor) is very small the filter can asymptote to a stable solution. We really need to fix this but we have taken a "if it ain't broke don't fix it attitude" so far. But in reality we are calling the fusion filter incorrectly.

One thing you could do is instead of polling constantly you could use a timer and just read all the data at 1 kHz. You might be out of step by 1 ms but this shouldn;t hurt you except in the most demanding applications (5 Hz is not demanding). Best is using the interrupt as you know.

On Sun, Aug 19, 2018 at 2:38 PM Stephan Edelman notifications@github.com wrote:

I should clarify that the 3600 iterations/sec represents the number of calls to the Mahony fusion function. This does not mean that I am feeding the Mahony function with new data with each call. I am not using hardware interrupt, but merely checking the INT_STATUS flag in the MPU9250 by making an I2C read call, so the actual data rate into the Mahony function will be less. I will add a couple of additional counters to show the data rate from the accel/gryo and the Magnetometer (which produces data at a lower rate) and report back. With respect to the accel/gyro, the data rate is set to 1KHz:

writeByte(MPU9250_ADDRESS, CONFIG, 0x03);

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-414157820, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qtkGQCQTIS5v_n3x5UjFzF_lkQFZks5uSdrhgaJpZM4H8cRf .

saedelman commented 5 years ago

I'm not as versed in this, but I'm not sure I understand why sending the same accel/gyro/mag data to the fusion solution would lead to a false rotation. I was under the impression, at least for Mahony, in a overly simplified sense, that it is driven by the difference error between the input and output and internal state variables are used so that subsequent calls to the fusion function allows the solution to converge to a stable output that minimizes this error. This suggests that it is necessary to always iterate more frequently than the input data changes in order to get convergence. This would support the requirement that you have stated that the fusion rate should be 5-10x faster than the data input rate. If we do this:

if (data_ready(accel) && data_ready(gyro) && data_ready(mag)) { ManohyUpdate(....); }

Then the input data rate and the fusion rate are identical and would the solution still converge? I have not yet tested this, but it would seem that the system is constantly perturbed and not allowed to converge to a solution.

Is it possible to separate the code in Mahony/Madgwick that deals with the iteration to a solution for a given input so that we can presumably call this for every iteration (when there is no new data) and call another function to inject new data? This may speed up processing if it were possible.

kriswiner commented 5 years ago

It is a subtle point I won't belabor but it is close enough to think of it this way:

" I was under the impression, at least for Mahony, in a overly simplified sense, that it is driven by the difference error between the input and output and internal state variables are used so that subsequent calls to the fusion function allows the solution to converge to a stable output that minimizes this error."

But we have implemented this in a not entirely correct way, but it works just fine.

I usually do:

main_loop { if(interrupt) {get data};

for (i = 0;i > N;i++){call fusion filter};

end_loop}

where N is 10 or 20.

Again, this is not entirely correct but is good enough because the time between iterations when there is no new data is very small.

On Sun, Aug 19, 2018 at 5:45 PM Stephan Edelman notifications@github.com wrote:

I'm not as versed in this, but I'm not sure I understand why sending the same accel/gyro/mag data to the fusion solution would lead to a false rotation. I was under the impression, at least for Mahony, in a overly simplified sense, that it is driven by the difference error between the input and output and internal state variables are used so that subsequent calls to the fusion function allows the solution to converge to a stable output that minimizes this error. This suggests that it is necessary to always iterate more frequently than the input data changes in order to get convergence. This would support the requirement that you have stated that the fusion rate should be 5-10x faster than the data input rate. If we do this:

if (data_ready(accel) && data_ready(gyro) && data_ready(mag)) { ManohyUpdate(....); }

Then the input data rate and the fusion rate are identical and would the solution still converge? I have not yet tested this, but it would seem that the system is constantly perturbed and not allowed to converge to a solution.

Is it possible to separate the code in Mahony/Madgwick that deals with the iteration to a solution for a given input so that we can presumably call this for every iteration (when there is no new data) and call another function to inject new data? This may speed up processing if it were possible.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-414168262, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qnZEhFpwMo-nXjFw0F4moOeJtVyZks5uSgaWgaJpZM4H8cRf .

saedelman commented 5 years ago

Thanks for the clarification. I will give that a shot. Minor detail, but I presume you really only want to trigger the N loop when there is new data, not otherwise. So, technically:

main loop
{
if (interrupt) { get data; new_data_flag = true; }

if (new_data_flag)  {

new_data_flag = false;

for (i = 0; i < N; i++) { call fusion filter; }

}

...do other things...

end_loop}
kriswiner commented 5 years ago

Yes, like https://github.com/kriswiner/MPU9250/blob/master/MPU9250_BME280_SPIFlash_Ladybug/MPU9250_BME280_SPIFlash_Ladybug.ino this among other examples.

On Sun, Aug 19, 2018 at 7:07 PM Stephan Edelman notifications@github.com wrote:

Thanks for the clarification. I will give that a shot. Minor detail, but I presume you really only want to trigger the N loop when there is new data, not otherwise. So, technically:

main loop { if (interrupt) { get data; new_data_flag = true; }

if (new_data_flag) {

new_data_flag = false;

for (i = 0; i < N; i++) { call fusion filter; }

}

...do other things...

end_loop}

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-414177970, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qpEuHNNmKiQGatXhkfkDFr7RgHt-ks5uShnygaJpZM4H8cRf .

saedelman commented 5 years ago

I'm having trouble with the AK8963 re-initialization. It appears that sending a H_RESET to the PWR_MGMT_1 register of the MPU9250, does not reset the AK8963. I tried sending a 0x01 to the AK8963_CNTL2 register of the AK8963, but it never clears the bit no matter how long I wait (I'm doing a loop read). I have to power cycle the whole MPU9250 to get it back to work again.

When I reflash my microcontroller with new firmware, I can't get control of the AK8963 again and a WHO_AM_I_AK8963 does not yield 0x48 and I don't get any mag data even after trying to send 0x00 to power up the chip. Have you seen this before? Do you have any ideas?

kriswiner commented 5 years ago

Not sure what you are doing or why.

Resetting a register in the MPU9250 will not reset the AK8963C, they are two different sensors. You will have to reset one and then the other. But you will also have to enable pass through mode on the MPU9250 after you reset it to be able to reset the AK8963.

If bypass mode is not enable (MPU9250 INT_CFG register) you won't be able to access the AK8963.

Please read the data sheet and register map.

On Sun, Aug 26, 2018 at 5:52 PM Stephan Edelman notifications@github.com wrote:

I'm having trouble with the AK8963 re-initialization. It appears that sending a H_RESET to the PWR_MGMT_1 register of the MPU9250, does not reset the AK8963. I tried sending a 0x01 to the AK8963_CNTL2 register of the AK8963, but it never clears the bit no matter how long I wait (I'm doing a loop read). I have to power cycle the whole MPU9250 to get it back to work again.

When I reflash my microcontroller with new firmware, I can't get control of the AK8963 again and a WHO_AM_I_AK8963 does not yield 0x48 and I don't get any mag data even after trying to send 0x00 to power up the chip. Have you seen this before? Do you have any ideas?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-416086210, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qrX3SkvjCS3CrTrDgCxF6hBmZmUrks5uU0K-gaJpZM4H8cRf .

saedelman commented 5 years ago

The problem that I am having is that I have to remove power from the MPU9250 to be able to talk to the AK8963 again and get mag data. I'm of course setting pass through mode writeByte(MPU9250_ADDRESS, INT_PIN_CFG, 0x22) and everything works fine, the problem is that if I do a host reset (by writing new firmware, for example), I can no longer talk to the AK8963 and my only option to get it to work again is to remove power from the MPU9250. I am looking for a way to be able to reset the AK8963 during initialization so that I can talk to the AK8963 without the need to remove power altogether. Any ideas?

kriswiner commented 5 years ago

If you reset the host by writing new firmware don;t you have to reconfigure both sensors? I really do not understand what you hope to achieve, the sensors will not "remember" their previous configuration, is this what you are thinking?

On Sun, Aug 26, 2018 at 6:12 PM Stephan Edelman notifications@github.com wrote:

The problem that I am having is that I have to remove power from the MPU9250 to be able to talk to the AK8963 again and get mag data. I'm of course setting pass through mode writeByte(MPU9250_ADDRESS, INT_PIN_CFG, 0x22) and everything works fine, the problem is that if I do a host reset (by writing new firmware, for example), I can no longer talk to the AK8963 and my only option to get it to work again is to remove power from the MPU9250. I am looking for a way to be able to reset the AK8963 during initialization so that I can talk to the AK8963 without the need to remove power altogether. Any ideas?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-416087957, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qhQ8fUDEIfYzOUGDiW2VUEBd8QNgks5uU0d0gaJpZM4H8cRf .

saedelman commented 5 years ago

Yes, that's the point I am making. If I reset the host I need to go through the whole ResetMPU9250(), InitMPU9250() and initAK8963() functions again but that is not working because the AK8963 is locked up. I have to physically remove power to be able to get mag data again.

To clarify:

Turn power on

(1) Enable Passthrough (2) Verify AK8963 WHO_AM_I = 0x48 (3) Program runs properly and get AHRS data

Reset Host

(1) Enable Passthrough (2) Verify AK8963 WHO_AM_I = 0x48 (fails reads 0x00) (3) Program does not work properly

I'm not sure why the AK8963 becomes inaccessible after doing a host reset.

kriswiner commented 5 years ago

If you literally reset the host alone, it could be that the I2C transactions are stuck in some undefined state. If you start at the top of the Arduino sketch and in setup call wire.begin() this should reset the I2C bus bit might not reset the MPU9250-to-AK8963C bus, so I would recommend you figure out how to either reset this bus or reset the ak8963C as part of the initialization.

There is a software reset for the AK8963C in CNTL2.

You can reset the I2C_Master_bus in USER_CNTL register of the MPU9250.

Read the data sheet and register map.

On Sun, Aug 26, 2018 at 6:19 PM Stephan Edelman notifications@github.com wrote:

Yes, that's the point I am making. If I reset the host I need to go through the whole ResetMPU9250(), InitMPU9250() and initAK8963() functions again but that is not working because the AK8963 is locked up. I have to physically remove power to be able to get mag data again.

To clarify:

Turn power on

(1) Enable Passthrough (2) Verify AK8963 WHO_AM_I = 0x48 (3) Program runs properly and get AHRS data

Reset Host

(1) Enable Passthrough (2) Verify AK8963 WHO_AM_I = 0x48 (fails reads 0x00) (3) Program does not work properly

I'm not sure why the AK8963 becomes inaccessible after doing a host reset.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-416088731, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qneMxuXC-mHOT6rXW7v4rRZhzo0Aks5uU0k_gaJpZM4H8cRf .

saedelman commented 5 years ago

I've done everything already except reset the I2C_Master_BUS in USER_CNTL. I'll try this, hopefully it works.

kriswiner commented 5 years ago

Did it work?

I don't recall having this problem, or at least not having it very often.

On Sun, Aug 26, 2018 at 6:53 PM Stephan Edelman notifications@github.com wrote:

I've done everything already except reset the I2C_Master_BUS in USER_CNTL. I'll try this, hopefully it works.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-416092613, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qt0gcxbtVz6ouB_FKwfMMnmbYU8-ks5uU1EJgaJpZM4H8cRf .

saedelman commented 5 years ago

No, unfortunately, it did not. I sent it 0x07 to the USER_CNTL register and I'm still not getting a response from the AK8963 when sending a WHO_AM_I. Sometimes it locks the AK8963 after the first host reset and other times after several, but usually within 3 host resets. It clearly has to do with the I2C transaction to the AK8963 getting interrupted "mid sentence" and leaving it hung. This should be cleared by a host bus reset, but, perhaps, the pass through mode is pseudo and the MPU9250 is re-streaming I2C commands it hears for the AK8963's address. I'm going to play with a bit-banged I2C library to see if there is any compatibility issue with the (terrible) Nordic TWI driver and the MPU9250. I'm not sure what else to try.

kriswiner commented 5 years ago

Oh, you didn't say (or I forgot) that you were using the nRF52 I2C API, yes this is a hideous software I2C patch job Nordic was forced to put together since they botched the hadware peripheral.

This is why I don't usually see this behavior.

I don't see this behavior even when I use the nRF52 https://www.tindie.com/products/onehorse/nrf52832-development-board/ when I use the nRF51 I2C API that is part of Sandeep Mistry's Arduino core for the nRF52. It is not that great but at least it does manage to work without this kind of I2C bus stalling problem.

This kind of nonsense is why I use the STM32L4 when I can.

On Sun, Aug 26, 2018 at 8:31 PM Stephan Edelman notifications@github.com wrote:

No, unfortunately, it did not. I sent it 0x07 to the USER_CNTL register and I'm still not getting a response from the AK8963 when sending a WHO_AM_I. Sometimes it locks the AK8963 after the first host reset and other times after several, but usually within 3 host resets. It clearly has to do with the I2C transaction to the AK8963 getting interrupted "mid sentence" and leaving it hung. This should be cleared by a host bus reset, but, perhaps, the pass through mode is pseudo and the MPU9250 is re-streaming I2C commands it hears for the AK8963's address. I'm going to play with a bit-banged I2C library to see if there is any compatibility issue with the (terrible) Nordic TWI driver and the MPU9250. I'm not sure what else to try.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-416104601, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qmQWBoR0M2Dw3t6yE-lRF3qv6QV1ks5uU2gFgaJpZM4H8cRf .

saedelman commented 5 years ago

With embarrassment, it turns out the AK8963 was toast. I replaced the MPU9250 chip and now all is well. It looks like under certain conditions in our circuit the MPU9250 (and other chips) were presented with 4.2v instead of 3.3v for a short period of time. At any rate, 4.2v is well above the absolute maximum ratings for most of these chips, so it is not surprising that the AK8963 had a flaky response.

kriswiner commented 5 years ago

Yup, it is always something. Didn;t think this might be the case though. With nRF52 I2C, anything is possible!

On Mon, Aug 27, 2018 at 9:14 AM Stephan Edelman notifications@github.com wrote:

With embarrassment, it turns out the AK8963 was toast. I replaced the MPU9250 chip and now all is well. It looks like under certain conditions in our circuit the MPU9250 (and other chips) were presented with 4.2v instead of 3.3v for a short period of time. At any rate, 4.2v is well above the absolute maximum ratings for most of these chips, so it is not surprising that the AK8963 had a flaky response.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-416280100, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qnbnX6_bggUHplAfQvveg9zSf91uks5uVBrZgaJpZM4H8cRf .

saedelman commented 5 years ago

As part of the troubleshooting, I replaced the I2C library with a bit-banged I2C library utilizing straight nrf_gpio_pin_clear(), nrf_gpio_pin_set(), calls, but the problem persisted so there was really no other thing to try then to replace the chip. The positive thing out of this is that I appear to be able to drive the I2C clock speed above 400KHz with the bit-banged library.

It looks like we have a capacitor discharging through a coulomb counter chip. The chip has an input to reset the coulomb counter to "full" which we've attached to the Li-Ion charger so that when it indicates battery "full", the column counter is automatically reset. Well, it looks like these may not be compatible with each other.

saedelman commented 5 years ago

It looks like the biases and offsets that I calculated for the (now) defective MPU9250 also work good for the replacement chip. Looks like the bulk of the corrections needed are for the influence of the board itself, not manufacturer trim. It looks like yaw repeatability is excellent. I bought one of your "Ultimate sensor fusion" boards with MPU9250+EM7180+BMP280 and will use that as my "gold" standard for comparing heading accuracy.

kriswiner commented 5 years ago

You should be able to get ~4 degree rms heading accuracy with host fusion and ~2 degree rms using the EM7180. Let me know what you find...

On Mon, Aug 27, 2018 at 9:43 AM Stephan Edelman notifications@github.com wrote:

It looks like the biases and offsets that I calculated for the (now) defective MPU9250 also work good for the replacement chip. Looks like the bulk of the corrections needed are for the influence of the board itself, not manufacturer trim. It looks like yaw repeatability is excellent. I bought one of your "Ultimate sensor fusion" boards with MPU9250+EM7180+BMP280 and will use that as my "gold" standard for comparing heading accuracy.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/55#issuecomment-416288973, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qr2e-Q99ZmKyww9gZw7pX0LmYDR_ks5uVCG5gaJpZM4H8cRf .