How the BMP280 Sensor Actually Measures Pressure and Temperature

The BMP280 relies on a piezoresistive pressure sensing element fabricated directly onto a silicon die. As atmospheric pressure pushes against a suspended silicon diaphragm, the diaphragm deflects. This physical deformation changes the electrical resistance of implanted piezoresistors arranged in a Wheatstone bridge configuration. Simultaneously, a bandgap temperature sensor on the exact same silicon die measures the local ambient temperature, which is critical because silicon piezoresistors are highly sensitive to thermal drift.

The output of the BMP280 is strictly digital. It does not output an analog voltage, a ratiometric signal, or a 4-20mA current loop. Instead, an internal 20-bit sigma-delta ADC converts the analog bridge voltages into raw digital counts (adc_P for pressure, adc_T for temperature). These raw integers are then clocked out to your microcontroller via an I2C bus (up to 3.4 MHz) or SPI bus (up to 10 MHz). You will never measure a voltage on the signal pins with a multimeter; you must read the registers via code.

Wiring the BMP280 to ESP32 and Arduino (Pinout & Power)

The most common way to destroy a bare BMP280 chip on the bench is applying 5V to the VCC pin. According to the Bosch Sensortec BMP280 datasheet, the absolute maximum supply voltage range is 1.71V to 3.6V. While many third-party breakout boards include an onboard 3.3V LDO regulator allowing 5V input, you must verify your specific board's schematic before connecting it to a 5V Arduino Uno.

Standard I2C Wiring Table

BMP280 Pin Function ESP32 DevKit V1 Arduino Uno (3.3V Pro Mini) Notes & Constraints
VCC Power Supply 3V3 VCC (3.3V) 1.71V - 3.6V. Do not use 5V unless breakout has an LDO.
GND Ground GND GND Must share common ground with MCU.
SCL I2C Clock GPIO 22 A5 Requires 4.7kΩ pull-up to 3.3V if not on breakout.
SDA I2C Data GPIO 21 A4 Requires 4.7kΩ pull-up to 3.3V if not on breakout.
CSB Chip Select Connect to VCC Connect to VCC Tie HIGH for I2C mode. Tie LOW for SPI mode.
SDO Address Select Float or GND Float or GND GND = I2C addr 0x76. VCC = I2C addr 0x77.
Bench Tip: If you are wiring the BMP280 on a breadboard with long jumper wires (over 15cm), the parasitic capacitance on the I2C lines will cause ACK failures at 400kHz. Drop your I2C clock speed to 100kHz in your Wire.setClock(100000); initialization, or add 2.2kΩ pull-up resistors to stiffen the bus.

Output Signal Math: Converting Raw ADC Reads to Pascals and °C

A common beginner mistake is assuming the BMP280 outputs human-readable floats. It does not. When you read the data registers (0xF7 to 0xFC), you get 20 bits of raw pressure data and 16 bits of raw temperature data. To convert these raw integers into physical units (Pascals and degrees Celsius), you must apply the Bosch compensation algorithm using 11 factory-programmed calibration parameters stored in the sensor's NVM (registers 0x88 to 0xA1).

The Critical Link: t_fine

The compensation math is heavily optimized for 32-bit integer arithmetic so it can run on microcontrollers without a floating-point unit (FPU). The most important concept to grasp is the t_fine variable. The pressure sensor's thermal drift is so significant that you cannot calculate compensated pressure without first calculating the compensated temperature.

  1. Read Calibration Data: On boot, read the 26 bytes of NVM into local variables (dig_T1 through dig_T3, and dig_P1 through dig_P9).
  2. Calculate Temperature: Use adc_T and the dig_T parameters to calculate the true temperature in °C. During this calculation, a 32-bit integer named t_fine is generated as a byproduct.
  3. Calculate Pressure: Feed adc_P, the dig_P parameters, AND the t_fine variable into the pressure compensation formula. The output is pressure in Q24.8 format (which you divide by 256 to get standard Pascals).

If you skip reading the NVM calibration registers and just apply a linear scale factor to the raw ADC values, your pressure readings will be wildly inaccurate—often off by tens of hectopascals. Always use a proven library like Adafruit's BMP280 library or the official Bosch Sensortec API, which handles the bitwise shifting and integer overflow protection required by the compensation formulas.

Real-World Interference and Troubleshooting

On the bench, the BMP280 is highly susceptible to three specific interference sources that will ruin your data:

  • Thermal Gradients (Self-Heating): The BMP280 is incredibly sensitive to localized heat. If you mount the breakout board directly above an ESP32's onboard AMS1117-3.3 voltage regulator, the thermal bleed through the FR4 fiberglass will cause the temperature reading to skew 2°C to 4°C high. Because pressure compensation relies on temperature, your pressure reading will also drift. Always mount the sensor away from heat-dissipating components.
  • Light Exposure (Photocurrent Effect): The epoxy package covering the silicon die is not perfectly opaque to infrared and strong visible light. Shining a desk lamp or direct sunlight onto the sensor generates photocurrents in the silicon diaphragm, which the ADC interprets as physical pressure changes. If your project is in a high-light environment, cover the sensor with a small piece of dark heat-shrink tubing or PTFE tape (which blocks light but passes air).
  • Oversampling Configuration: By default, the sensor might be in 'sleep' mode or configured for ultra-low power. For indoor weather station use, configure the oversampling registers (ctrl_meas) to osrs_t = 2x and osrs_p = 16x with an IIR filter coefficient of 16. This drastically reduces RMS noise from ~1.5 Pa down to 0.2 Pa.

BMP280 Sensor FAQ

Why is my BMP280 sensor reading 800 hPa instead of 1013 hPa?

If your sensor is outputting a value around 800 hPa (or roughly 80,000 Pascals) while sitting at sea level, you are almost certainly reading the uncompensated raw ADC pressure value or applying the wrong mathematical bit-shift. The raw 20-bit ADC value for standard atmospheric pressure is typically in the 400,000 to 500,000 range. If you bypass the Bosch NVM calibration algorithm and just divide the raw register value by a constant, you will get nonsensical readings. Ensure your code is fetching the dig_P calibration parameters from registers 0x88-0x9F and running the full 32-bit integer compensation routine.

Can I use the BMP280 sensor to measure altitude accurately?

Yes, but with strict caveats. The BMP280 has a relative accuracy of ±0.12 hPa, which translates to roughly ±1 meter of altitude resolution under ideal conditions. However, absolute altitude calculation requires the barometric formula, which needs a highly accurate, real-time sea-level reference pressure (P0). Because weather systems change P0 constantly, a standalone BMP280 will experience altitude drift of up to 10 meters per day as weather fronts move in. For drone or rocketry applications, you must fuse the BMP280's relative altitude changes with a GPS module's absolute altitude using a Kalman filter to maintain long-term accuracy.

What is the difference between the BMP280 and BME280 sensors?

The BMP280 measures only pressure and temperature. The BME280 measures pressure, temperature, and humidity. Physically, they look identical on many third-party breakout boards, but the BME280 contains an additional capacitive humidity sensing element. From a firmware perspective, the BME280 requires reading extra humidity calibration registers (0xA1, 0xE1-0xE7) and running a third compensation algorithm. Furthermore, the BME280 consumes slightly more current during a measurement burst due to the humidity sensor's heating element, which is used to burn off condensation. If you do not need humidity data, stick with the BMP280 to save battery life and code space.