Learn

A BMP180 on an Arduino: pressure, temperature and altitude

Intermediate

Or see every lesson.

  • 455parts on the bench
  • 43boards running now
  • 1.00xreal time, on every board
Arduino Uno: a BMP180 barometerlive0.000 s 0.00x
Click to open it in the editor
The Barometer example on a simulated ATmega328P: drag the temperature and pressure sliders on the GY-68.

The BMP180 is a tiny Bosch barometer: it measures air pressure, and the temperature beside it, and talks to an Arduino over I2C. It is the chip on the purple GY-68 breakout that comes in many sensor kits, and it is the classic first way to make a weather station or an altimeter.

The circuit above is an Uno reading a BMP180 with the Adafruit BMP085 library (the BMP180 is the BMP085’s successor and uses the same code). Twice a second it prints the temperature, the pressure in pascals and the altitude that pressure works out to. Press Run, then drag the two sliders on the breakout and watch the numbers follow.

What you need

  • An Arduino Uno
  • A BMP180 breakout (GY-68)
  • Four jumper wires
  • A breadboard (optional)

Wiring

Part and pinGoes toNote
BMP180 VCC5 VThe GY-68 has its own 3.3 V regulator, so 5 V is fine
BMP180 GNDGND
BMP180 SDAA4The Uno’s I2C data pin
BMP180 SCLA5The Uno’s I2C clock pin
BMP180 3V3NothingThe regulator’s output; leave it free

What the BMP180 measures

Air has weight, and the pressure of all the air above you pushes on everything at about 101,325 pascals at sea level. That is 1013.25 hectopascals (hPa), the same thing as millibars, or 29.92 inches of mercury on a US weather report. Climb a hill and there is less air above you, so the pressure drops by about 12 Pa for every meter near sea level.

Inside the BMP180 is a small membrane that bends with the pressure, and a temperature sensor next to it. The chip does not hand over pascals, though. It gives raw counts and eleven calibration numbers stored at the factory, and the library runs the datasheet’s math to turn them into a temperature to a tenth of a degree and a pressure to one pascal.

The chip sits at I2C address 0x77, and only there, so one Uno can read one BMP180 on its bus.

The sketch

bmp.begin() checks that the chip answers with its ID and reads the calibration. If it fails, the sketch prints the library’s famous line, "Could not find a valid BMP085 sensor, check wiring!", and stops. Then every half second it prints three readings.

Run it as it starts and you see "Temperature = 22.0 *C Pressure = 101325 Pa Altitude = 0 meters". Drag the pressure slider to 1000 hPa (100,000 Pa) and the temperature to 30.5 degrees, and the next line says 30.5 *C, 100000 Pa and 111 meters. Drag the pressure down to 900 hPa and the altitude reads 989 meters, about the height of a small mountain town.

The barometer sketch
#include <Wire.h>
#include <Adafruit_BMP085.h>

Adafruit_BMP085 bmp;

void setup() {
  Serial.begin(9600);
  if (!bmp.begin()) {
    Serial.println("Could not find a valid BMP085 sensor, check wiring!");
    while (1) {
    }
  }
  Serial.println("Barometer ready");
}

void loop() {
  Serial.print("Temperature = ");
  Serial.print(bmp.readTemperature(), 1);
  Serial.print(" *C  Pressure = ");
  Serial.print(bmp.readPressure());
  Serial.print(" Pa  Altitude = ");
  Serial.print(bmp.readAltitude(), 0);
  Serial.println(" meters");
  delay(500);
}

Why the altitude is only a guess

readAltitude() uses the standard barometric formula: altitude = 44330 x (1 - (p / p0) ^ 0.1903), where p is the pressure you measured and p0 is the pressure at sea level. By default p0 is the standard 101,325 Pa, which is only true on an average day.

Weather moves the sea-level pressure up and down by 30 hPa or more, and at about 8 meters per hectopascal that shifts the altitude by tens of meters while the sensor sits still on your desk. So a barometer can tell you very well how much you climbed in the last ten minutes, and only roughly how high you are.

To get a true altitude, look up today’s sea-level pressure for your area (weather services list it, often as "pressure" or "QNH") and pass it in: bmp.readAltitude(102000) for 1020 hPa. Or go the other way: if you know your height, bmp.readSealevelPressure(250) gives the sea-level pressure for a sensor 250 meters up, which is the number weather maps show.

BMP180, BMP280 or BME280?

Bosch stopped making the BMP180 years ago, and you mostly find it in older kits now. Its replacement, the BMP280, is more exact and also talks SPI. The BME280 adds humidity. Both need a different library (Adafruit_BMP280 or Adafruit_BME280), since their registers are different, but the idea and the altitude math are the same.

If your board says BMP280 and this sketch says it cannot find the sensor, that is the reason: the BMP085 library looks for the BMP180’s chip ID, 0x55, and a BMP280 answers 0x58.

Common mistakes

SDA and SCL swapped, or one of them loose. The library cannot find the chip and prints "Could not find a valid BMP085 sensor, check wiring!". Swap A4 and A5 in the circuit above and you get exactly that.

Trusting the altitude to the meter. It is pressure, turned into height with a guess about the weather. Give it today’s sea-level pressure, or only use the change.

Using the BMP085 library on a BMP280 or BME280. The chip ID does not match, so begin() fails. Use the library for your chip.

Putting the sensor next to something warm, like the Uno’s regulator, or in direct sun. The temperature reading is the chip’s own, so it reads the heat around it, not the room.

Reading faster than the chip converts. A pressure reading at the highest accuracy takes 25.5 ms. The library waits for you, but a sketch that writes to the chip by hand has to wait too, or it reads the last result again.

Questions

How do I connect a BMP180 to an Arduino Uno?

Four wires: VCC to 5 V, GND to GND, SDA to A4 and SCL to A5. The GY-68 board has a regulator and pull-up resistors, so nothing else is needed.

Which library do I use for a BMP180?

The Adafruit BMP085 Library. The BMP180 kept the BMP085’s registers, so the same library and calls work: bmp.begin(), bmp.readTemperature(), bmp.readPressure() and bmp.readAltitude().

Why does my BMP180 altitude change when I have not moved?

Because the weather changes the air pressure, and the altitude is worked out from pressure. Pass today’s sea-level pressure to readAltitude() for a better number.

What is the BMP180 I2C address?

0x77. It cannot be changed, so you cannot put two of them on one I2C bus without a multiplexer.

Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.