How to implement altitude hold in your Arduino-based drone?


To implement altitude hold in your Arduino-based drone, you’ll need a barometric pressure sensor to measure altitude and feed it into a PID controller that adjusts motor throttle to maintain a fixed height.
Goal
Keep the drone hovering at a stable height automatically, even if there's disturbance (like wind).
Required Components
Component | Example |
Arduino Uno/Nano | Main controller |
Barometer Sensor | BMP280, BMP180, or MS5611 |
MPU6050 | For attitude stabilization |
ESCs + Motors | For drone control |
Power (LiPo + BEC) | For Arduino + ESCs |
Recommended Sensor: BMP280
Measures barometric pressure + temperature
Calculates altitude based on air pressure
Uses I2C interface (easy to connect to Arduino)
Accurate within ~±1 meter (for basic hovering)
Wiring BMP280 to Arduino (I2C)
BMP280 Pin | Arduino Pin |
VCC | 3.3V or 5V |
GND | GND |
SDA | A4 (Uno) |
SCL | A5 (Uno) |
Sample Arduino Code: Read Altitude
Install the Adafruit BMP280 library from the Library Manager.
cpp
#include <Wire.h>
#include <Adafruit_BMP280.h>
Adafruit_BMP280 bmp; // I2C interface
float targetAltitude = 1.2; // meters
float currentAltitude;
float error, integral, derivative, lastError;
float kp = 40.0, ki = 0.1, kd = 25.0;
int baseThrottle = 1150;
void setup() {
Serial.begin(9600);
if (!bmp.begin()) {
Serial.println("BMP280 not detected!");
while (1);
}
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,
Adafruit_BMP280::SAMPLING_X2,
Adafruit_BMP280::SAMPLING_X16,
Adafruit_BMP280::FILTER_X16,
Adafruit_BMP280::STANDBY_MS_500);
}
void loop() {
currentAltitude = bmp.readAltitude(1013.25); // sea-level pressure (adjustable)
// PID calculation
error = targetAltitude - currentAltitude;
integral += error;
derivative = error - lastError;
lastError = error;
float output = kp * error + ki * integral + kd * derivative;
int throttle = baseThrottle + output;
throttle = constrain(throttle, 1000, 2000);
// Send throttle to motors
// esc1.writeMicroseconds(throttle);
// esc2.writeMicroseconds(throttle);
// esc3.writeMicroseconds(throttle);
// esc4.writeMicroseconds(throttle);
Serial.print("Altitude: ");
Serial.print(currentAltitude);
Serial.print(" m | Throttle: ");
Serial.println(throttle);
delay(100);
}
Notes:
targetAltitude
: Desired hover height (in meters)You must combine this with pitch/roll stabilization from the MPU6050 code
PID tuning is essential to avoid oscillations
Avoid using barometers alone outdoors (wind/pressure changes); use with accelerometer for filtering
Next-Level Options:
Feature | Sensor/Method | Purpose |
Altitude + vertical speed | Kalman Filter or complementary filter | More stable altitude |
Outdoor navigation | GPS + barometer | Position + altitude hold |
Optical flow | PMW3901 or similar | Indoor hover without GPS |
Subscribe to my newsletter
Read articles from ampheo directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
