The BMP180 barometric pressure sensor outputs a strictly digital I2C signal, not an analog voltage. To extract usable Pascals or hectoPascals (hPa), your microcontroller must read 11 factory-stored calibration coefficients from the sensor's internal EEPROM and apply Bosch's proprietary compensation algorithm to the raw ADC temperature and pressure registers. While Bosch Sensortec has officially deprecated the BMP180 in favor of the BMP280 and BME280, the BMP180 (ubiquitously sold on $2 GY-68 breakout boards) remains heavily deployed in legacy weather stations, drone altimeters, and DIY telemetry projects.

BMP180 Sensing Principle and Signal Output

The BMP180 relies on a piezoresistive sensing element. Atmospheric pressure pushes against a suspended silicon diaphragm inside the sensor package, physically deforming it. This microscopic deformation alters the electrical resistance of piezoresistors implanted directly into the diaphragm, which are wired in a Wheatstone bridge configuration. A built-in delta-sigma ADC converts this resistance change into a raw, uncompensated digital pressure value (UP).

Because silicon's piezoresistive properties are highly temperature-dependent, the BMP180 integrates a secondary bandgap temperature sensor on the same die. It measures the ambient silicon temperature (UT) so the microcontroller can mathematically cancel out thermal drift before calculating the final pressure. The output is entirely digital via the I2C bus (default address 0x77); there is no analog voltage or current output to measure with a multimeter.

⚠️ Common Interference Sources:
  • Light Exposure: The silicon die is exposed through the package lid. Shining a bright desk lamp or direct sunlight on the sensor generates photocurrents in the PN junctions, skewing the pressure reading by 1–3 hPa. Always shield the sensor with PTFE tape or a 3D-printed cap.
  • Thermal Gradients: Mounting the GY-68 board too close to a 3.3V LDO voltage regulator or an ESP32 WiFi antenna will heat the local air, causing continuous barometric drift.
  • Mechanical Stress: Bending the PCB or applying excessive soldering heat to the header pins alters the diaphragm's baseline tension, ruining absolute accuracy.

Hardware Specifications and I2C Wiring

Before wiring the sensor, verify your breakout board's voltage regulation. The raw BMP180 IC operates at 1.8V to 3.6V. Most GY-68 modules include an onboard 3.3V LDO and 4.7kΩ I2C pull-up resistors, allowing you to power the VIN pin with 5V from an Arduino Uno, but the I2C data lines must still respect the 3.3V logic threshold.

BMP180 Datasheet Specifications (Source: Bosch Sensortec)
Parameter Min Typ Max Unit
Supply Voltage (VDD) 1.8 3.3 3.6 V
Pressure Range 300 - 1100 hPa
Absolute Accuracy (25°C) - - ±0.12 hPa
Temperature Resolution - 0.1 - °C
I2C Address - 0x77 - Hex
Standby Current - 0.1 - µA

Wiring Pinout Table

GY-68 Pin ESP32 Pin Arduino Uno Pin Notes
VIN / VCC 3V3 5V Use 3.3V if bypassing onboard LDO
GND GND GND Common ground required
SCL GPIO 22 A5 I2C Clock (Needs 4.7k pull-up)
SDA GPIO 21 A4 I2C Data (Needs 4.7k pull-up)
💡 Pro-Tip on Pull-ups: If your I2C bus hangs or returns NaN, check for pull-up resistors. The GY-68 usually has 4.7kΩ resistors tied to 3.3V. If you are wiring multiple I2C sensors, the parallel resistance drops, potentially violating the I2C specification and corrupting the SDA rise times.

Raw-to-Unit Math and Calibration Scaling

Unlike simple analog sensors where Vout = Pressure * Scale, the BMP180 requires fetching 11 calibration words (AC1 through AC6, B1, B2, MB, MC, MD) stored in the factory-programmed EEPROM from addresses 0xAA to 0xBF. These coefficients are unique to every single IC and correct for manufacturing variances in the silicon etching.

The conversion happens in two stages. First, you trigger a temperature read (write 0x2E to 0xF4, wait 4.5ms, read 0xF6) to get the raw uncompensated temperature (UT). Then, you trigger a pressure read based on the Oversampling Setting (OSS, 0 to 3) to get the raw uncompensated pressure (UP).

The Integer Compensation Algorithm

Because the BMP180 was designed in an era where 8-bit microcontrollers were standard, Bosch engineered the math to use strictly 32-bit and 64-bit integer operations, avoiding slow floating-point calculations. Here is the exact sequence to convert UT to true temperature in 0.1°C:

long X1 = ((long)UT - AC6) * (long)AC5 / 32768; // 2^15
long X2 = ((long)MC * 2048) / (X1 + (long)MD);   // 2^11
long B5 = X1 + X2;
long T = (B5 + 8) / 16;                          // 2^4, Result in 0.1 °C

Pressure calculation is significantly more complex, requiring intermediate variables B6 (derived from B5), and calculating X1, X2, X3 to find B3 and B4. Finally, the true pressure P in Pascals is extracted using a 64-bit integer cast to prevent overflow during the B7 * B7 multiplication step:

long long p = ((long long)B7 * (long long)B7) / 2;
// ... [intermediate X1, X2, X3 scaling] ...
unsigned long long P = (p * 3038) >> 16;
P = P + ((-7357 * P) >> 16) + 3791;
// Final P is in Pascals (divide by 100.0 for hPa)

Note: If you are porting this to a 32-bit ARM Cortex or ESP32, standard int is 32 bits, but you must explicitly use int64_t or long long for the B7 multiplication block, or your pressure output will silently overflow and return negative numbers.

Practical Interfacing: ESP32 Code and Debugging

While you can write the raw I2C register reads yourself, using a battle-tested library saves hours of debugging integer overflows. The Adafruit BMP085 library is fully backward-compatible with the BMP180, as they share the exact same I2C register map and EEPROM layout. Below is a minimal, robust implementation for an ESP32 using the Arduino core.

#include <Wire.h>
#include <Adafruit_BMP085.h>

Adafruit_BMP085 bmp;

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22); // ESP32 SDA, SCL
  
  // Verify I2C communication
  if (!bmp.begin()) {
    Serial.println("FATAL: BMP180 not found. Check wiring and I2C pull-ups.");
    while (1) { delay(100); } // Halt execution
  }
  Serial.println("BMP180 initialized successfully.");
}

void loop() {
  // Read Temperature (returns float in Celsius)
  float tempC = bmp.readTemperature();
  
  // Read Pressure (returns int32_t in Pascals)
  int32_t pressurePa = bmp.readPressure();
  float pressureHpa = pressurePa / 100.0F;
  
  // Calculate Altitude assuming standard sea level pressure (1013.25 hPa)
  float altitudeM = bmp.readAltitude();
  
  Serial.printf("Temp: %.2f C | Pressure: %.2f hPa | Alt: %.1f m\n", 
                tempC, pressureHpa, altitudeM);
                
  delay(1000); // BMP180 max sampling rate is ~32Hz, 1Hz is ideal for thermal stability
}

Troubleshooting Common Failure Modes

  • Sensor reads exactly 1013.25 hPa but temperature is 85°C: You have wired the VCC pin to a 5V source on a raw BMP180 module without an LDO. The internal silicon is overheating. Disconnect immediately; the die may be permanently damaged.
  • Altitude drifts by 20 meters over an hour: Barometric pressure changes with weather fronts. A drop of 1 hPa equates to roughly 8.5 meters of apparent altitude gain. For drone or hiking altimeters, you must implement a dynamic sea-level pressure baseline using local METAR weather data via WiFi, rather than hardcoding 1013.25 hPa.
  • Library fails to initialize (!bmp.begin()): Run an I2C scanner sketch. If the scanner shows no devices, your SDA/SCL lines are swapped, or the 3.3V LDO on the GY-68 board has failed (a common issue with cheap $1 clones). If it shows an address other than 0x77, you are likely communicating with a different sensor on the bus.
🛑 End-of-Life Notice: Bosch Sensortec discontinued the BMP180 in 2016. If you are designing a new PCB in 2026, do not use the BMP180. Use the BMP280 (for pressure/temp) or BME280 (for pressure/temp/humidity). They are cheaper, smaller, consume less power, and use standard floating-point math libraries without the complex 11-coefficient EEPROM calibration matrix.