BMP280 Altimeter
ESP32 DevKit (WROOM-32)·Arduino C++·Updated Jul 27, 2026·by FluxBench TeamIncludes Lab + Schematic
A barometric altimeter: a BMP280 pressure sensor (Adafruit BMP280 library, I2C) converts air pressure into altitude - roughly 1 hPa lower for every 8 meters you climb. A 128x64 OLED shows the height above a baseline in big digits (meters and feet), a CLIMBING / DESCENDING / LEVEL trend, and the raw pressure. Click the BMP280 on the bench and drag its P slider to fly up and down - the green LED on GPIO 4 lights while you climb - and press the button on GPIO 14 to zero the altimeter.
sketch.ino
// BMP280 Altimeter - barometric pressure turns into altitude. The BMP280
// measures air pressure, and every ~8 meters you climb the pressure drops
// by about 1 hPa. The sketch converts pressure to altitude, remembers a
// baseline, and shows how far above or below it you are.
// Click the BMP280 on the bench and drag its P slider to 'fly' up and down.
// Press the button to zero the altimeter at the current altitude.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_BMP280.h>
#define ZERO_PIN 14 // push button: set baseline to current altitude
#define CLIMB_LED 4 // lights while climbing
Adafruit_BMP280 bmp;
Adafruit_SSD1306 display(128, 64, &Wire, -1);
float baseline = 0;
float lastRel = 0;
void setup() {
Serial.begin(115200);
pinMode(ZERO_PIN, INPUT_PULLUP);
pinMode(CLIMB_LED, OUTPUT);
Wire.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
bmp.begin(0x76);
delay(100);
baseline = bmp.readAltitude(1013.25);
Serial.println("BMP280 Altimeter ready - button zeroes the altitude");
}
void loop() {
float p = bmp.readPressure() / 100.0; // Pa -> hPa
float alt = bmp.readAltitude(1013.25); // meters above sea level
float rel = alt - baseline; // meters above the baseline
if (digitalRead(ZERO_PIN) == LOW) {
baseline = alt;
rel = 0;
lastRel = 0;
Serial.println("Altimeter zeroed at current altitude");
delay(300); // simple debounce
}
float vspeed = (rel - lastRel) * 2.0; // m/s (loop runs every 500 ms)
lastRel = rel;
const char* trend = "LEVEL";
if (vspeed > 0.5) {
trend = "CLIMBING";
} else if (vspeed < -0.5) {
trend = "DESCENDING";
}
if (vspeed > 0.5) {
digitalWrite(CLIMB_LED, HIGH);
} else {
digitalWrite(CLIMB_LED, LOW);
}
float feet = rel * 3.281;
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.print("BMP280 ALTIMETER");
display.setTextSize(3);
display.setCursor(0, 12);
display.print(rel, 1);
display.setTextSize(1);
display.print(" m");
display.setCursor(0, 40);
display.print(feet, 0);
display.print(" ft ");
display.print(trend);
display.setCursor(0, 52);
display.print("P ");
display.print(p, 1);
display.print(" hPa Btn=zero");
display.display();
Serial.print("P=");
Serial.print(p, 1);
Serial.print(" hPa alt=");
Serial.print(rel, 1);
Serial.print(" m ");
Serial.println(trend);
delay(500);
}Built with FluxBench.AI — the AI workbench for embedded projects.