MS5803-14BA pressure sensor code issues


#1

This is in reference to the MS5803-14BA.cpp and .h files on the OpenROV Github repository.

I've recently been fooling around the the Measurement Specialties MS5803 pressure sensor, like that used on the OpenROV IMU board. Along the way I hit some issues with the pressures jumping around on my sensor, which I traced back to my original library code using float variables when it should have been using 64-bit integers to do the temperature compensation.

The current OpenROV files for that sensor also use a bunch of float values that will generate rollovers and cause pressure values to deviate from the true values. I've since revamped my library for the MS5803-14BA (and the other MS5803 models) to do all of the calculations properly and avoid those jumps in the pressure value. The rollovers can lead to deviations in the 2-20mbar range over the normal range of operating temperatures, although the pressure maybe off as much as 100mbar if you manage to land exactly on one of the very narrow temperature ranges where the variable rollovers matter most.

If you want to see how the Arduino math problems manifest themselves, I have a blog post here: http://lukemiller.org/index.php/2014/04/arduino-code-for-ms5803-pressure-sensors/ describing how the two methods of carrying out the math (float vs. int64_t) compare. The attached figure shows the deviations.

My library for the MS5803-14BA is here: https://github.com/millerlp/MS5803_14, and there are separate repositories for the other pressure models. The library can't be seamlessly inserted into the existing OpenROV codebase as-is with the way the existing ROV code is arranged, but I hope you all find it helpful enough to use as a guide for your purposes.


648-FixedD1varyD2.png (14.9 KB)

#2

One of these spikes is right in my target temperature range but my prototypes are going to be under water and unreachable for another couple of months. Good thing I am saving the unconverted raw ADC readings on the logger as well.

Thanks for spotting that Luke!


#3

Thanks for the links and the post. We have seen these massive spikes in pressure readings during some recent deeper dives. I'll be taking a longer look at the libraries you have put together!

-Brian


#4

Hi Luke:

This is cool stuff!

So I'm the guy responsible for the use of floats in the existing OROV code. When we went to integrate the MS5803, we couldn't find any Arduino code on the web that could be easily clipped into the OROV software, so I sat down to write something myself. Upon reading the datasheet, it was clear that the computation flowchart wanted one to use 64-bit ints, and I had no idea how to do that with an Arduino. So I just made everything a float and pressed on from there. The code seemed to work, so we all moved on with more pressing (ha ha, no pun intended) issues.

I'll try to take a look at your library tonight, as well as studying your blog post some more.

Thanks for your work on this.

-Walt


#5

Walt,

I did the exact same thing with floats initially, and only discovered the problem after leaving the thing running overnight in a car while it got cold enough to trigger a few of the overflows as the temperature dropped. I was baffled until I finally paid attention to the datasheet and tried doing some math problems with the Arduino.

Edward has the right idea if one doesn't need the actual pressure data in real time. Simply storing D1 + D2 from the MS5803 would save a bunch of program memory space and RAM if someone wants to post-process it on a more robust processor than the 8-bit AVR. My library is definitely not lightweight when it comes to memory usage.


#6

Hi Luke:

While just storing the raw sensor values would work fine for a datalogger, we want to have real-time display of depth on the ROV, plus any sort of autopilot code that has depth stabilization is obviously going to need real-time depth. So we'll just have to bite the bullet and do the correct calculation. If that proves to be too CPU- or memory-intensive on the microcontroller, we could offload things to the BeagleBone. But our current plan is to keep any autopilot in the Arduino for the tightest real-time control, so I don't even think that that is a realistic option.

I haven't had a chance to see what triggers the overflow in the calculations, but do you think there's any way that a simple re-arrangement of the float calculations could solve this issue?

Thanks,

-W


#7

Walt,

I don't really think anything can be done to make floats work during the stages of the calculation process where the datasheet calls for 64-bit values. I played around a bit with using smaller 32-bit integers (same memory footprint as a float, 4 bytes) to see how far I could get. Eventually I decided that it was just going to be safest to use 64-bit values where the datasheet requires them because I could still trigger rollovers within the "normal" range of temperatures you might encounter when I was fooling around with 32-bit values.

I suppose I shouldn't necessarily say that my version of the library is radically larger than the float-version. I went back and looked at my old float version of the library (not posted anywhere, but similar to yours), and a basic sketch compiles to ~10kb, while the basic test example in my current library compiles at 13,290 bytes. The RAM footprint will be a bit bigger, since 5 of the variables that were 4-byte floats are now 8-byte int64_t values, so there's an extra 20 bytes. Some of the operations in my library might also take up a bit more RAM as well since there are some casts to 64-bit values, but I haven't done a complete accounting of the RAM usage.