Hello all
I am working on an altitude controller to be used in an RC aircraft* (Note below for project specifics). I chose the MPL3115A2 and SFE library since it seemed to be very precise however I am having an issue with drift over time. I understand that the sensor is light sensitive and weather changes over time however I am getting about 25-30 feet of drift within a 5-8 minute time span consistently.
The sensor is currently on a breadboard and connected as per the hook up guide except with a little bit of porous foam gently covering top from light (I had worst drift without this foam). I thought the sensor may need a few minutes to stabilize but if reset the sketch, the same drift pattern occurs. I also noticed that the SFE sketch always says my altitude is about 100-120 feet below what it actually is but I believe that can be fixed with the offset registers 0x14 and 15. I have attached a graph to better show the issue.
http://s27.postimg.org/s7u6gqtxf/MPL3115_A2_Drift.png
Has anyone else has this issue or know how to correct it? I figure this is probably user error since I am new to barometric sensors. I would greatly appreciate any pointers!
Relevant stuff:
https://www.sparkfun.com/products/11084
https://learn.sparkfun.com/tutorials/mp … er-setting
Should I use the altitude equation from the link above instead the altitude function from the SFE library?
I also used the code from here:
http://www.henrylahr.com/?p=99
If I set my altitude basis to what I measure with my GPS, the sketch from above always starts dead on, but it drifts too.
** Project details
I am working on a device to hold my quadcopters altitude so I need a barometer that can report altitude quick and accurate enough to keep the quad within a few feet of the desired altitude. I chose a barometer over a GPS because it’s cheaper and better suited I feel. I also wanted the actual altitude to relay it to a ground station. On the other hand, I am starting to think it would be more effective to use change in pressure instead of change in altitude for altitude control.
My first gut feel was temperature drift, but the part is supposed to be internally temperature compensate.
A few things to check/consider…
The sensor is connected to 3.3V not 5V, correct? (Sensor max voltage = 3.6V)
You have 10K resistors in series with SCL/SDA signals (important if you’re using an arduino with 5V IO)?
Can you put a box or something over the circuit and see if the drift is reduced? Maybe you are still getting light contamination.
I did several test. Originally I started off with 10k resistors inline on the I2C (and 3v to the sensor) but the Sketch kept returning -999 for an altitude. A guy on the product page discussion recommended to remove the resistors which made the sketch work. After that, I placed foam over the sensor which seemed to help a little. I tested the sensor outdoors and indoors in both day and night and the results are the same, it always drifts up 60-70 feet then becomes wavy. But dramatic changes in altitude (10ft in a second) can be seen in some of the graphs I made. I just mounted the sensor to a 3v pro mini and it started off at about 690ft and drifted to 770ft after 5 minutes which is really close to my actual altitude. Interestingly, I disconnected the mini for a minute and when I reconnected it the sensor still reported the same altitude range - it did not reset back to 690ft. However, I am still testing it as I type and the sensor has drifted to 780 feet in 16 minutes (with a 1.6ºF drop in temperature) which is even closer to my altitude. This seems to be better but letting my quad sit for 15 minutes for a sensor to converge seems a bit extreme.
I left the sensor on overnight from about 4am to about 1pm and my location is Northern Ohio which is about 795ft according to my phone GPS or 880ft according to my EM406 GPS. The sketch is “Altitude” from the SFE library examples
I also put the temperature on the graph but had to scale by 10% and shift down by 100 to get them to align.
You can see where morning came around the 300 minute mark and began to warm up. The large waves are probably due to natural changes in atmospheric pressure but I am not sure what to make of with the smaller waves in between.
http://s2.postimg.org/po863aaxl/Overnight.jpg
Zoomed in during the beginning.
http://s24.postimg.org/5duw4u2z9/Close_Up.jpg
I figure it needs a few minutes to “warm up” like some gyros do or perhaps I damaged the sensor by removing the 10k resistors.
Hmmm… this part really shouldn’t require a warm-up. If the Pro Mini is 3V (or 3.3V) removing the 10K resistors is fine. If 5V has been applied, the part may have been damaged.
What are you plugging into the Pro Mini to program it? Is it supplying power to the Pro Mini? Could it have supplied 5V to the board? Can you measure the board power with the programming adapter plugged in?
[edit]
Same for any other power source that may have powered the Pro Mini (i.e. your quad). Measure board Vcc when connected to that source.
[/edit]
Do the temperatures coming from the part look reasonable? With your scaling and offset I can’t tell from your graph what the temperature values are.
I am using the 3.3v SFE FTDI basic to program the mini which is fresh out of the packaging. I measured the voltage and was getting 3.28v at VCC while operating. The temperatures always seems just right. When I switch to barometer mode, the pressure is usually in the 98000pa to 99000pa range which seems reasonable.
Using this equation [pressure = 101326*(1 - (2.25577)(10^-5)(height in meters))^5.25588] from http://www.engineeringtoolbox.com/air-a … d_462.html with 238m as my height, I get 98500pa which agrees with my measurements.
This is the data I started collecting from my last post.
Altitude plot below. The drift I am concerned about is from 0 to 750s (12 minute mark) where it climbs about 75 feet. After that, the gradual 10 foot decline is most likely from the weather changing. But the decline is not as dramatic as when attached to the Uno.
http://s27.postimg.org/r7je5aykj/Mini_Alt.jpg
Temperature plot, it seems the temperature is spot on.
http://s29.postimg.org/4xt0rq3rb/Mini_Temp.jpg
I really hope removing the 10k resistors didn’t damage the sensor. I guess it gives me a reason to go SFE sensor shopping just to be sure. It would be REALLY awesome if Sparkfun provided sample data/graphs of a properly working sensor along with code.
I thought the sensor may need a few minutes to stabilize but if reset the sketch, the same drift pattern occurs.
Is there an internal buffer that filters or averages the data and reports that average or filtered value ? If so try setting the number of samples "averaged" to some low number. :think:
Mee_n_Mac:
I thought the sensor may need a few minutes to stabilize but if reset the sketch, the same drift pattern occurs.
Is there an internal buffer that filters or averages the data and reports that average or filtered value ? If so try setting the number of samples "averaged" to some low number. :think:
It looks like it has an oversample rate which reports the averaged/filtered value and is set to 128 samples. I will play around with the value and report back later tonight. The good news is that it is producing readings way quicker so if I do get it working, I will have a much quicker update rate for my altitude controller. Before polling it too quick would cause it to generate weird negative altitudes. Hopefully this works!
From the SFE library
//Call with a rate from 0 to 7. See page 33 for table of ratios.
//Sets the over sample rate. Datasheet calls for 128 but you can set it
//from 1 to 128 samples. The higher the oversample rate the greater
//the time between data samples.
void MPL3115A2::setOversampleRate(byte sampleRate)
{
if(sampleRate > 7) sampleRate = 7; //OS cannot be larger than 0b.0111
sampleRate <<= 3; //Align it for the CTRL_REG1 register
byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings
tempSetting &= 0b11000111; //Clear out old OS bits
tempSetting |= sampleRate; //Mask in new OS bits
IIC_Write(CTRL_REG1, tempSetting);
}
Alright, I just tested each Oversample Rate with 1 recording a second for 500 seconds. I know the lower OSR’s can go 1 sample every few ms but I wanted to keep the number of data points the same. Plus when I took one every 10ms, the graph looked like a solid thick line from the points being so close. I know the drift occurs over 16 minutes
Set up is a 3.3v pro mini at 8MHz with only the MPL3115A2 connected (No resistors or other sensors at all). I am using an FTDI Basic (3v version) to upload sketches and record data to the serial monitor.
Sketch is a slightly modified example from the library. I just changed the delay to 1 second and made it print Altitude, Time, and Temperature in a comma separated value format.
The test was performed in an air conditioned room and the location of the sensor did not change throughout the test. The only thing I feel that should be mentioned is that each test was done back to back.
I attached the graphs of temperature and altitude plus the original csv data if you wish to graph it in excel or something.
The real interesting stuff happens on OSR 5,6, and 7. Pretty much OSR 5 has a sin wave look, OSR 6 has a slight amount of drift, OSR 7 has the most. OSR 0 to 2 are pretty straight if you draw an average line through it. OSR 3 and 4 have a very small amount of drift.
My next question is, why does the OSR have this effect? Isn’t it supposed to be a good thing? The lower OSR seems better for my application (quick update rate) so I will most likely go that route. I am just curious now just in case if I encounter this at a later date.
I haven’t used the MPL3115A2, but I’ve used several other barometric sensors and have not observed drift behavior as serious as you describe. I suggest to try the LPS25H from Pololu: http://www.pololu.com/product/2724 It is rather new on the market, seems to be state of the art for consumer grade barometric sensors, and in my hands is extremely stable.
joecarb:
It looks like it has an oversample rate which reports the averaged/filtered value and is set to 128 samples. I will play around with the value and report back later tonight. The good news is that it is producing readings way quicker so if I do get it working, I will have a much quicker update rate for my altitude controller. Before polling it too quick would cause it to generate weird negative altitudes. Hopefully this works!
From the SFE library…
Uh, wait… are you using code from the link in your OP, or the SFE code?
joecarb:
I also used the code from here:
http://www.henrylahr.com/?p=99
I haven’t sifted through all of the code, but it looks like the SFE code uses FIFO mode, queueing readings, and may account for the ‘drift’ you’re seeing (actually more of a settling). The code in the OP seems like it is set up more for a faster data acquisition application.
My bad, I should have been more clear. I am using the Spark Fun library and the ‘Altitude’ example sketch and the only modification was for it to put out csv data (Millis, Altitude, Temperature) and in the last set of test I changed the OSR bit.
I put out csv data with the following code:
Serial.print(Millis()/1000); Serial.print(", "); Serial.print(Altitude); and so forth
The code from Henry Lahr has a calibration/initialization using my current altitude in the beginning which sets the offset registers. This code gives me the right starting altitude but drifts in the same pattern. I was sure to reset the device to factory when switching between libraries. I just downloaded the Adafruit code but I am still trying to decipher it
Edit:
At this point I am unsure of what to do next as far as testing goes. If there is a specific setup you would like me to try, just let me know. I wish I had a second barometer to compare readings to. :think: