Table of Contents
KEY TAKEAWAYS
- MEMS piezoresistive sensors (BMP280, BME280) are the most popular for embedded projects — cheap, accurate, and easy to interface via I2C/SPI.
- Pressure sensors measure gauge (relative to atmosphere), absolute (relative to vacuum), or differential (between two sources).
- BMP280 achieves ±1 hPa accuracy, enabling altitude estimation to approximately ±1 meter resolution.
- The barometric formula altitude = 44330 × (1 – (P/P0)^0.1903) converts pressure readings to altitude above sea level.
- Temperature compensation and periodic recalibration against a known reference are essential for accurate long-term pressure measurement.
Part of the Complete Guide to Sensors for Embedded Systems series.
Pressure sensors are essential for weather stations, altimeters, tire pressure monitors, HVAC systems, and industrial process control. This guide covers the main pressure sensor technologies, how to choose one for your application, practical interfacing code for the BMP280, and techniques for altitude calculation and calibration.
Pressure Measurement Fundamentals
Pressure is force per unit area, measured in Pascals (Pa), bar, psi, or atmospheres. Standard atmospheric pressure at sea level is 101,325 Pa (1013.25 hPa or 14.7 psi). Understanding the different types of pressure measurement is essential for choosing the right sensor.
Gauge pressure measures relative to atmospheric pressure. A tire pressure gauge reading 32 psi means the tire is 32 psi above ambient atmospheric pressure. If atmospheric pressure changes, the gauge reading stays the same as long as the actual tire pressure does not change. Most industrial pressure sensors measure gauge pressure.
Absolute pressure measures relative to a perfect vacuum. Barometric pressure sensors like the BMP280 measure absolute pressure. This is necessary for weather monitoring and altitude calculation because the measurement must not be affected by the reference. Absolute pressure at sea level is approximately 101,325 Pa.
Differential pressure measures the difference between two pressure sources. This is used for airflow measurement (pitot tubes), filter condition monitoring (pressure drop across a filter indicates clogging), and liquid level measurement in sealed tanks. Differential pressure sensors have two ports, one for each pressure source.
Pressure Unit Conversion
Different industries and regions use different pressure units. Here are the conversion factors you will encounter most often in embedded systems work:
1 atmosphere (atm) = 101,325 Pa = 101.325 kPa = 1013.25 hPa (mbar) = 14.696 psi = 1.01325 bar = 760 mmHg (Torr).
Quick conversions: 1 psi = 6894.76 Pa. 1 bar = 100,000 Pa. 1 kPa = 0.1450 psi. 1 hPa = 1 mbar = 100 Pa. Weather reports typically use hPa (hectopascals) or millibars, which are numerically identical. Industrial applications in the US use psi; Europe and most engineering contexts use bar or kPa.
Sensor Technologies: Working Principles
Piezoresistive sensors are the most common type in embedded systems. A silicon diaphragm with implanted or diffused piezoresistive elements deforms under pressure. The mechanical deformation changes the resistance of the piezoresistors, which are typically arranged in a Wheatstone bridge configuration. The bridge produces a differential voltage proportional to the applied pressure. MEMS fabrication makes these sensors tiny (2-3mm), cheap, and highly integrated — the BMP280 includes the sensing element, ADC, calibration memory, and digital interface on a single chip.
Capacitive sensors use a flexible diaphragm as one plate of a capacitor. Pressure deflects the diaphragm, changing the gap between plates and thus the capacitance. Capacitive sensors have lower hysteresis, better long-term stability, and lower temperature sensitivity than piezoresistive types. They are preferred for precision applications and very low pressure ranges. The main disadvantage is that the capacitance change is small, requiring sensitive readout electronics.
Piezoelectric sensors generate an electric charge in response to mechanical stress. They measure only dynamic (changing) pressure, not static pressure — the charge leaks away over time. This makes them ideal for measuring pressure pulses, vibrations, blast waves, and engine combustion pressure. They have extremely fast response times (microseconds) and can measure very high pressures. Not suitable for barometric or HVAC applications where static pressure measurement is needed.
BMP280 I2C Interfacing: Complete C Code
The BMP280 from Bosch is the most popular MEMS pressure sensor for embedded projects. It measures 300-1100 hPa with ±1 hPa absolute accuracy. Communication is via I2C (address 0x76 or 0x77) or SPI. The following code demonstrates initialization, raw data reading, and the compensation algorithm using factory calibration data.
/* BMP280 I2C pressure/temperature sensor driver */
#include <stdint.h>
#define BMP280_ADDR 0x76
#define BMP280_REG_ID 0xD0
#define BMP280_REG_RESET 0xE0
#define BMP280_REG_STATUS 0xF3
#define BMP280_REG_CTRL 0xF4
#define BMP280_REG_CONFIG 0xF5
#define BMP280_REG_PRESS 0xF7 /* 0xF7-0xF9: pressure */
#define BMP280_REG_TEMP 0xFA /* 0xFA-0xFC: temperature */
#define BMP280_REG_CALIB 0x88 /* 0x88-0xA1: calibration data */
/* Calibration coefficients (read from sensor at init) */
typedef struct {
uint16_t dig_T1;
int16_t dig_T2, dig_T3;
uint16_t dig_P1;
int16_t dig_P2, dig_P3, dig_P4, dig_P5;
int16_t dig_P6, dig_P7, dig_P8, dig_P9;
int32_t t_fine; /* Shared between temp and pressure compensation */
} BMP280_Calib;
static BMP280_Calib calib;
/* I2C helper functions (platform-specific, implement for your MCU) */
extern uint8_t i2c_read_reg(uint8_t addr, uint8_t reg);
extern void i2c_read_burst(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
extern void i2c_write_reg(uint8_t addr, uint8_t reg, uint8_t val);
uint8_t bmp280_init(void) {
/* Verify chip ID (should be 0x58 for BMP280) */
uint8_t id = i2c_read_reg(BMP280_ADDR, BMP280_REG_ID);
if (id != 0x58) return 0; /* Wrong chip or not connected */
/* Soft reset */
i2c_write_reg(BMP280_ADDR, BMP280_REG_RESET, 0xB6);
HAL_Delay(10);
/* Read calibration coefficients */
uint8_t cal[26];
i2c_read_burst(BMP280_ADDR, BMP280_REG_CALIB, cal, 26);
calib.dig_T1 = (cal[1] << 8) | cal[0];
calib.dig_T2 = (cal[3] << 8) | cal[2];
calib.dig_T3 = (cal[5] << 8) | cal[4];
calib.dig_P1 = (cal[7] << 8) | cal[6];
calib.dig_P2 = (cal[9] << 8) | cal[8];
calib.dig_P3 = (cal[11] << 8) | cal[10];
calib.dig_P4 = (cal[13] << 8) | cal[12];
calib.dig_P5 = (cal[15] << 8) | cal[14];
calib.dig_P6 = (cal[17] << 8) | cal[16];
calib.dig_P7 = (cal[19] << 8) | cal[18];
calib.dig_P8 = (cal[21] << 8) | cal[20];
calib.dig_P9 = (cal[23] << 8) | cal[22];
/* Configure: temp oversampling x2, press oversampling x16, normal mode */
i2c_write_reg(BMP280_ADDR, BMP280_REG_CTRL, 0x57);
/* Config: standby 500ms, filter coeff 16 */
i2c_write_reg(BMP280_ADDR, BMP280_REG_CONFIG, 0x90);
return 1;
}
/* Compensate raw temperature - returns temp in 0.01°C */
int32_t bmp280_compensate_temp(int32_t adc_T) {
int32_t var1, var2;
var1 = ((((adc_T >> 3) - ((int32_t)calib.dig_T1 << 1))) *
((int32_t)calib.dig_T2)) >> 11;
var2 = (((((adc_T >> 4) - ((int32_t)calib.dig_T1)) *
((adc_T >> 4) - ((int32_t)calib.dig_T1))) >> 12) *
((int32_t)calib.dig_T3)) >> 14;
calib.t_fine = var1 + var2;
return (calib.t_fine * 5 + 128) >> 8;
}
/* Compensate raw pressure - returns pressure in Pa (Q24.8 fixed point) */
uint32_t bmp280_compensate_press(int32_t adc_P) {
int64_t var1, var2, p;
var1 = ((int64_t)calib.t_fine) - 128000;
var2 = var1 * var1 * (int64_t)calib.dig_P6;
var2 = var2 + ((var1 * (int64_t)calib.dig_P5) << 17);
var2 = var2 + (((int64_t)calib.dig_P4) << 35);
var1 = ((var1 * var1 * (int64_t)calib.dig_P3) >> 8) +
((var1 * (int64_t)calib.dig_P2) << 12);
var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)calib.dig_P1) >> 33;
if (var1 == 0) return 0;
p = 1048576 - adc_P;
p = (((p << 31) - var2) * 3125) / var1;
var1 = (((int64_t)calib.dig_P9) * (p >> 13) * (p >> 13)) >> 25;
var2 = (((int64_t)calib.dig_P8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((int64_t)calib.dig_P7) << 4);
return (uint32_t)p; /* Pressure in Pa * 256 */
}
/* Read both temperature and pressure */
void bmp280_read(float *temp_c, float *press_pa) {
uint8_t buf[6];
i2c_read_burst(BMP280_ADDR, BMP280_REG_PRESS, buf, 6);
int32_t adc_P = ((int32_t)buf[0] << 12) | ((int32_t)buf[1] << 4) |
(buf[2] >> 4);
int32_t adc_T = ((int32_t)buf[3] << 12) | ((int32_t)buf[4] << 4) |
(buf[5] >> 4);
/* Must compute temperature first (sets t_fine for pressure) */
int32_t temp_raw = bmp280_compensate_temp(adc_T);
*temp_c = temp_raw / 100.0f;
uint32_t press_raw = bmp280_compensate_press(adc_P);
*press_pa = press_raw / 256.0f;
}Altitude Calculation from Pressure
The International Standard Atmosphere model relates pressure to altitude. As altitude increases, atmospheric pressure decreases in a predictable way. The barometric formula for altitude below 11,000 meters (troposphere) is:
altitude = 44330.0 × (1.0 – (P / P0) ^ 0.1903)
where P is the measured pressure in Pa and P0 is the sea-level reference pressure (101325 Pa standard, but should be set to the actual local sea-level pressure for accurate results). Near sea level, a 1 hPa change in pressure corresponds to approximately 8.43 meters of altitude change.
/* Calculate altitude from pressure using the barometric formula */
#include <math.h>
/**
* Calculate altitude above sea level.
* @param pressure_pa Measured pressure in Pascals
* @param sea_level_pa Sea-level reference pressure in Pascals
* (use 101325.0 for standard atmosphere,
* or local QNH from weather service for accuracy)
* @return Altitude in meters
*/
float pressure_to_altitude(float pressure_pa, float sea_level_pa) {
return 44330.0f * (1.0f - powf(pressure_pa / sea_level_pa, 0.1903f));
}
/**
* Calculate sea-level pressure from known altitude.
* Useful for calibrating the sensor at a known elevation.
* @param pressure_pa Measured pressure in Pascals
* @param altitude_m Known altitude in meters
* @return Estimated sea-level pressure in Pascals
*/
float altitude_to_sea_level_pressure(float pressure_pa, float altitude_m) {
return pressure_pa / powf(1.0f - (altitude_m / 44330.0f), 5.255f);
}
/* Usage example */
void altitude_demo(void) {
float temp, pressure;
bmp280_read(&temp, &pressure);
/* Using standard atmosphere reference */
float alt_standard = pressure_to_altitude(pressure, 101325.0f);
/* Using local QNH for accurate altitude (get from weather service) */
float local_qnh_pa = 101800.0f; /* Example: 1018.00 hPa */
float alt_accurate = pressure_to_altitude(pressure, local_qnh_pa);
}Calibration and Temperature Compensation
The BMP280 includes factory-calibrated compensation coefficients stored in on-chip memory, which the compensation algorithm uses automatically. However, for applications requiring the highest accuracy, additional calibration steps may be needed.
Offset calibration: Compare the sensor reading against a known reference (a calibrated barometer or a weather station report for your exact location). Apply a constant offset correction in software. For altitude applications, recalibrate the sea-level reference pressure whenever weather conditions change, as atmospheric pressure varies by several hPa day-to-day.
Temperature effects: Even with the built-in temperature compensation, extreme temperatures can introduce small errors. If operating outside the -10°C to 60°C range, consider characterizing the sensor at temperature extremes and applying an additional correction polynomial. The BMP280 datasheet specifies the temperature coefficient of offset (TCO) and temperature coefficient of sensitivity (TCS) for this purpose.
Long-term drift: MEMS pressure sensors can drift 1-2 hPa over years due to stress relaxation in the diaphragm and packaging. For critical applications, schedule periodic recalibration against a known reference.
Industrial Applications
Tire pressure monitoring systems (TPMS): Each tire contains a battery-powered pressure sensor that transmits readings wirelessly to the vehicle ECU. The sensor must operate at temperatures from -40°C to 125°C and withstand centrifugal forces up to 3000g. MEMS piezoresistive sensors are used exclusively for this application.
Altimeters and drones: Barometric altitude hold uses the BMP280 or BMP388 to maintain a constant altitude. The sensor is read at 25-50Hz, and a complementary filter combines pressure-derived altitude with accelerometer data for smooth altitude estimation. The BMP388 offers ±0.5 hPa accuracy (about ±4 meters), which is adequate for outdoor drone flight but insufficient for indoor floor detection.
Hydraulic systems: Industrial hydraulic presses and injection molding machines use strain gauge pressure transducers rated for 500-10,000 psi. These sensors produce a millivolt-level signal proportional to pressure, requiring signal conditioning (amplification) before ADC conversion. 4-20mA current loop output is preferred for long cable runs in noisy factory environments.
Weather stations: Barometric pressure measurement is one of the best predictors of short-term weather changes. A rapidly falling pressure (more than 3 hPa in 3 hours) indicates an approaching storm. Home weather stations use the BMP280 or BME280 to track pressure trends and calculate altitude-corrected sea-level pressure for comparison with official weather reports.
Common Design Mistakes
Forgetting the pressure port: The sensor diaphragm must be exposed to the pressure being measured. In an enclosure, drill a small hole or use a pressure port tube. A completely sealed enclosure traps air, and temperature changes alter the internal pressure, corrupting the reading.
Ignoring wind effects: Moving air creates dynamic pressure (Bernoulli effect) that adds to the static pressure reading. For weather stations, use a static pressure port or baffle that shields the sensor from direct wind while allowing static pressure equalization.
Not temperature-compensating: Always read both temperature and pressure from sensors that provide both (BMP280, BME280). The compensation algorithm requires the temperature reading to correct pressure for thermal effects. Skipping the temperature read produces inaccurate pressure values.
Using stale sea-level reference: For altitude applications, the sea-level reference pressure must be updated regularly. A 1 hPa error in the reference translates to approximately 8.4 meters of altitude error. Weather systems can change local pressure by 20+ hPa over 24 hours, causing altitude errors exceeding 160 meters if the reference is not updated.
Related on this site
- Pressure transducers drift with temperature, supply voltage, and aging — see sensor calibration techniques for periodic recalibration patterns.
- If raw readings are too noisy after the ADC, noise in sensor measurements walks through hardware-side fixes (decoupling, shielding, grounding).
- For a comparable analog-sensor interfacing case study (temperature instead of pressure), see temperature sensors explained.
Going further: Piezoresistive and capacitive pressure sensors produce analog voltages that the MCU reads via its ADC — see ADC in Microcontrollers for the interfacing fundamentals.
Going further: For point-of-contact force measurement with a thin-film approach, see our FlexiForce sensor calibration guide.

Vivek Bhageria — Lead Firmware R&D Engineer, 12+ years. Ex-Bosch (automotive powertrain), MusicTribe (real-time audio), medical devices. M.Tech BITS Pilani. I write at NerdyElectronics — practical, register-level embedded systems for engineers who want to understand what’s actually happening under the hood.



