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.
- 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.
| 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) |
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 than0x77, you are likely communicating with a different sensor on the bus.






