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

ampheoampheo
2 min read

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

ComponentExample
Arduino Uno/NanoMain controller
Barometer SensorBMP280, BMP180, or MS5611
MPU6050For attitude stabilization
ESCs + MotorsFor drone control
Power (LiPo + BEC)For Arduino + ESCs

  • 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 PinArduino Pin
VCC3.3V or 5V
GNDGND
SDAA4 (Uno)
SCLA5 (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:

FeatureSensor/MethodPurpose
Altitude + vertical speedKalman Filter or complementary filterMore stable altitude
Outdoor navigationGPS + barometerPosition + altitude hold
Optical flowPMW3901 or similarIndoor hover without GPS
0
Subscribe to my newsletter

Read articles from ampheo directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

ampheo
ampheo