Barometric Presure sensor BMP180

thanks askjacob and Leo
Well I also had wrong readings with the sparkfun library, but now I'm trying the adafruit library and it seems to work ok:

Temperature = 35.60 *C
Pressure = 101231 Pa
Altitude = 8.00 meters
Pressure at sealevel (calculated) = 101232 Pa
Real altitude = 22.55 meters

I'll try to make changes to the code posted by Leo and also try it on Leonardo and a nano v3.0 and post the results.

Hi Leo,

I wanted to use your code rather than the Adafruit library for 2 reasons really:

1: I have very little codespace left
2: Just "throwing another library at a problem" leaves little to learning

And did I get some learning done last night :slight_smile:

Considering C and all it's variants are new to me (why did my university insist on Pascal?) - at least the strong background on type casting helped :slight_smile: - I have been working hard on both the hardware and software aspects on my current project - hence using the arduino platform to speed things up rather than my usual route of rolling my own. Makes it easier knowing it is less likely to be a hardware issue...

Anyway, back on topic, the environment I have in place is:

Arduino Pro Mini 5v 16MHz 328 (Maybe the 328 is key here? Unsure why it would be a major difference other than ram space although I find more and more quirks with the arduino compiler as I go...)
Bosch BMP180 sensor on breakout with 3v3 supply (ebay special)
Various other i2c devices not currently in use in test code (now in use in full code, and happily co-existing), other than the oLED used as the debug display (rather than serial terminal)

I was getting 1480 - 1508 mbar readings (was actually 1008 compared to my weather station) until I fixed the casting. Once casting fixed - bingo - spot on.

By the way - I popped over to your website to see if there was any updated code, and instead was enthalled by the rocketry and altimeter stuff - amazing stuff :slight_smile:

Cheers from Aus,
Jacob

I have the same sensor and i used a bi-directional logic level converter for it to work. Also, the code i tested it with had altitude input, for a more exact pressure output.
I think you used same code when you got those high readings. Now I don't know if you can use it on 5 v logic level and get valid readings..

The code you tested it with would be the Adafruit Unified library. Dig inside the codebase, and you will find the exact same compenstation logic - taken from the same datasheet sample.

Once you dig in there - Adafruit also cast everything correctly, INCLUDING this example.

As mentioned, the issue appears to be how the compiler/environment handles default casting, if you leave it to the compiler to handle it (bad) you will get an unpredictable result based on how the author of your environment feels on the day. Isn't it better to strictly cast it anyway (good) to ensure you get it in the format you desire regardless? There is no overhead, and at best someone reading your code will also understand what is going on.

I should have mentioned all my i2c is at 3v3, although it is often mentioned that the BMP180 technically 5v tolerant on SDA and SCL - although the datasheet never points it out as the I2C specs are external to the device itself and another kettle of fish - it is about an ability to "drive" a voltage above a threshold cleanly without reflection/ringing (hence the termination resistors) and starts to enter the realm of throw stuff at it and see black magic once lines get long and more devices get added :slight_smile:

Can we please STOP trying to tell me what it isn't in this case? it is not hardware or voltage. I am not a newbie to electronics or to code, just to the arduino environment (and c - c++) - which I am hopping into just because of the flood of cheap dev boards from china...Cheaper than I can get bare ATMegas for these days... I am happy to be wrong, but not happy to have the conversation derailed.

Regards
Jacob

Also, the code i tested it with had altitude input, for a more exact pressure output.

This statement makes no sense. This device measures pressure.

Knowing any other outside information ( other than the temperature, which it measures itself ), cannot make the pressure output "more exact".

Outside information can be used to make the altitude calculation "more exact".

I think I had that sort of problem with the casting as well. Not sure now, it was a couple of years ago. It took a while to get it to work, I went through all those shift manipulations looking very closely at the bosch description. It appears that some of the library code that people published for this device, they never even tried running it.

I also recall seeing somewhere, an alternative processing scheme that someone devised, which used float instead of int ( or maybe the other way around ), to get an output with less bit errors in it. It looked very interesting but I did not implement it.

The Adafruit library allows you to put in a base altitude for more accurate altitude above sea level readings as that library also provides an altitude calculation. It has zero effect on the accuracy of anything else.

It also is no good for compensating any weather effects, so is more for experimentation - it is better to use a sample "ground level at now" and then measure differences rather than ever try to somehow measure an absolute above sea level with just a pressure sensor alone.

Normally if "altitude matters" you want to measure how high something went, or how high above the ground you are in the real time space, not how high above some arbitrary (sea level) number you are. You can always factor in the arbitrary number at another non-realtime time later if need be - well, according to my two cents anyway.

askjacob:
...

Arduino Pro Mini 5v 16MHz 328 (Maybe the 328 is key here? Unsure why it would be a major difference other than ram space although I find more and more quirks with the arduino compiler as I go...)
Bosch BMP180 sensor on breakout with 3v3 supply (ebay special)
Various other i2c devices not currently in use in test code (now in use in full code, and happily co-existing), other than the oLED used as the debug display (rather than serial terminal)

So essentially the same setup as I'm using except that mine are Pro Mini 3.3v boards.

Now, since I want to understand this to the fullest I'd like you to post your sensor variables for me please :slight_smile:

ac1 = ;
ac2 = ;
ac3 = ;
ac4 = ;
ac5 = ;
ac6 = ;
b1 = ;
b2 = ;
mb = ;
mc = ;
md = ;

I'm going to try to replicate it.

askjacob:
...
By the way - I popped over to your website to see if there was any updated code, and instead was enthalled by the rocketry and altimeter stuff - amazing stuff :slight_smile:

Thanks very much mate :slight_smile:

Now imagine if I had the problem with my altimeter (I'm using the Bosch sensor in one of them) I'd be in serious trouble. Rockets aren't very forgiving. Either everything works out 100% or your doomed.

Leo

I tried to replicate the problem but can't.

Example:

Oversampling setting (oss) = 0

Sensor calibration data:
AC1 = 408
AC2 = -72
AC3 = -14383
AC4 = 32741
AC5 = 32757
AC6 = 23153
B1 = 6190
B2 = 4
MB = -32768
MC = -8711
MD = 2868

Calculate true temperature:
UT = 27898 (raw temperature from sensor)
x1 = 4743
x2 = -2343
b5 = 2400
T = 150.00
T = 15.00

Temperature: 15.00 C, 59.00 F

Calculate true pressure:
UP = 23843 (raw pressure from sensor)
b6 = -1600
x1 = 1
x2 = 56
x3 = 57
b3 = 422
x1 = 2809
x2 = 59
x3 = 717
b4 = 33457
b7 = 1171050000
p = 70003
x1 = 74529
x1 = 3454
x2 = -7859

Pressure: 699.64 mbar, 20.66 inHg

Could you post your calibration data, UT and UP.

Leo:
Now, since I want to understand this to the fullest I'd like you to post your sensor variables for me please :slight_smile:

ac1 = 8240;
ac2 = -1128;
ac3 = -1433;
ac4 = 33630;
ac5 = 25458 ;
ac6 = 18542 ;
b1 = 6515;
b2 = 42 ;
mb =-32768 ;
mc = -11786;
md = 2541;

UP= 85170
UT=26199

OK, my values ADDED IN ABOVE. Just to eliminate the chance of i2c corruption, I did a few cold boots and verified these remained unchanged (other of course, than UP and UT). I think these numbers are pretty wild - probably why they are on ebay rather than digikey, making them edge cases for the formula hence why they push the envelope and finding where the gap is.

Incidentally, digging in the Adafruit libaray C file I find this:

b3 = (((((int32_t) _bmp085_coeffs.ac1) * 4 + x3) << _bmp085Mode) + 2) >> 2;

Where they cast it as int32_t. Looks like there is something to it. Anyway, let's keep peeling the layers off this onion..

Cheers
Jacob

Well I also check the .cpp's adafruit library file and they cast others variables as int32_t or uint32_t in that function ( readPressure)
If I force all as you suggest for b3 the result is similar to the one in the local weather station, similar to the result if i use adafruit example.

If I only change the one for b3 I have a low pressure value, don't remember now but it was like 2XX mbar

I try it on Leonardo and Nano (5v) and it looks the same.

Sensor calibration data:
AC1 = 9060
AC2 = -1244
AC3 = -14867
AC4 = 33491
AC5 = 25092
AC6 = 15143
B1 = 6515
B2 = 52
MB = -32768
MC = -11786
MD = 2764

Temperature: 27.70 C, 81.86 F
Pressure: 1013.84 mbar, 29.94 inHg

Temperature: 27.70 C, 81.86 F
Pressure: 1013.87 mbar, 29.94 inHg

Temperature: 27.70 C, 81.86 F
Pressure: 1013.81 mbar, 29.94 inHg

Temperature: 27.70 C, 81.86 F
Pressure: 1013.83 mbar, 29.94 inHg

I need your UT and UP readings...

I added them in in an edit in reply #20. Getting all the values out is a pain, as I only have a 128x64 display, so I have to do a few custom screens/loads with just a basic framework rather than my usual application.

Back then:

UP: 85170
UT: 26199

Now:

UP: 85048
UT: 26341

Cheers
Jacob

Jacob,

I didn't mean you but rather the poster above my requested post :slight_smile:

here:

Sensor calibration data:
AC1 = 9060
AC2 = -1244
AC3 = -14867
AC4 = 33491
AC5 = 25092
AC6 = 15143
B1 = 6515
B2 = 52
MB = -32768
MC = -11786
MD = 2764
----------------------------------
Temperature: 34.00 C, 93.20 F
Pressure: 1014.22 mbar, 29.95 inHg

UT: 42153
UP: 337220
----------------------------------
Temperature: 34.00 C, 93.20 F
Pressure: 1014.27 mbar, 29.95 inHg

UT: 42152
UP: 337218
----------------------------------
Temperature: 34.00 C, 93.20 F
Pressure: 1014.31 mbar, 29.95 inHg

UT: 42153
UP: 337211
----------------------------------
Temperature: 34.00 C, 93.20 F
Pressure: 1014.31 mbar, 29.95 inHg

UT: 42152
UP: 337203
----------------------------------
Temperature: 34.00 C, 93.20 F
Pressure: 1014.26 mbar, 29.95 inHg

UT: 42150
UP: 337189
----------------------------------
Temperature: 34.10 C, 93.38 F
Pressure: 1014.22 mbar, 29.95 inHg

UT: 42147
UP: 337184
----------------------------------
Temperature: 34.10 C, 93.38 F
Pressure: 1014.26 mbar, 29.95 inHg

UT: 42148
UP: 337182

regards

MB = -32768

This number instantly catches the eye as looking suspicious

Sure does - especially across 2 devices showing the same issue. I have 4 more sensors here now I can try out and see what the result is.

Strange enough though, once I modified the b3= line, it behaves itself properly - or - well enough. Again, it is more likely why these are on ebay far cheaper on a breakout board than from a reputable supplier in x5000 piece prices... they are probably from the reject bin as even with maxxed out compensation values they could not get them to true spec...

Cheers
Jacob

askjacob:
Sure does - especially across 2 devices showing the same issue. I have 4 more sensors here now I can try out and see what the result is.

Strange enough though, once I modified the b3= line, it behaves itself properly - or - well enough. Again, it is more likely why these are on ebay far cheaper on a breakout board than from a reputable supplier in x5000 piece prices... they are probably from the reject bin as even with maxxed out compensation values they could not get them to true spec...

Cheers
Jacob

MB = -32768

Looking back - it seems this one is the same across all devices - even Leo's one is the same value - unless he is using ehrja's data. Maybe it is not really a often tweaked value?

Hmm maybe that one is not the smoking gun here! I will hook up some of my other sensors and see.

OK I tried 2 more sensors, same result. Without the modified line, I get almost 500 mbar above the correct reading. They all read within about .2 mbar of each other though which is not bad considering the price...

Oh, and they all read MB = -32768

well it is 0x8000 hex and the biggest -ve number you can have in 16 bit twos-complement numbers.

The Adafruit library allows you to put in a base altitude for more accurate altitude above sea level readings as that library also provides an altitude calculation. It has zero effect on the accuracy of anything else.

It also is no good for compensating any weather effects, so is more for experimentation - it is better to use a sample "ground level at now" and then measure differences rather than ever try to somehow measure an absolute above sea level with just a pressure sensor alone.

Normally if "altitude matters" you want to measure how high something went, or how high above the ground you are in the real time space, not how high above some arbitrary (sea level) number you are. You can always factor in the arbitrary number at another non-realtime time later if need be - well, according to my two cents anyway.

That's all true, but then this "provided altitude" is coming from you, or it is written into the sketch somewhere. It's not coming from the sensor.

My advice would be to implement a sketch which does two things and two things only. Read the data registers from the chip. Implement the conversion algorithm as defined by Bosch.

If you want to "compensate" for the air pressure at the airport, or the known reference altitude, then do that later.