Try   HackMD

Let’s build a full quadcopter flight controller using Arduino + MPU6050, with PID control for pitch, roll, and yaw. This setup will stabilize all three axes and drive 4 ESCs for brushless motors.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

System Overview

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Hardware Required

  • Arduino Uno / Nano / Mega
  • MPU6050 (6-axis IMU)
  • 4× ESCs (PWM compatible)
  • 4× Brushless motors (2 CW + 2 CCW)
  • Power supply (LiPo + BEC for 5V to Arduino)
  • Optional: RC receiver (for user control)

Wiring (Example for Arduino Uno)

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Code: Full 3-Axis PID Stabilization
Libraries Needed:

  • Wire.h
  • MPU6050 (by Jeff Rowberg)
  • Servo.h

Arduino Code (Simplified)

cpp

#include <Wire.h>
#include <MPU6050.h>
#include <Servo.h>

MPU6050 mpu;
Servo esc1, esc2, esc3, esc4;

float pitch, roll, yaw;
float gyroX, gyroY, gyroZ;
float accX, accY, accZ;
float dt = 0.01;
unsigned long prevTime;

// PID gains (adjust for tuning)
float kp = 1.5, ki = 0.0, kd = 0.5;
float pitchI, pitchD, pitchErr, pitchPrevErr;
float rollI, rollD, rollErr, rollPrevErr;

int baseThrottle = 1150; // hover point

void setup() {
  Serial.begin(9600);
  Wire.begin();
  mpu.initialize();

  esc1.attach(3);  // Front
  esc2.attach(5);  // Right
  esc3.attach(6);  // Back
  esc4.attach(9);  // Left

  // Arm ESCs
  esc1.writeMicroseconds(baseThrottle);
  esc2.writeMicroseconds(baseThrottle);
  esc3.writeMicroseconds(baseThrottle);
  esc4.writeMicroseconds(baseThrottle);

  delay(3000); // Wait for ESCs
  prevTime = millis();
}

void loop() {
  unsigned long now = millis();
  dt = (now - prevTime) / 1000.0;
  prevTime = now;

  int16_t ax, ay, az, gx, gy, gz;
  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

  accX = ax / 16384.0;
  accY = ay / 16384.0;
  accZ = az / 16384.0;
  gyroX = gx / 131.0;
  gyroY = gy / 131.0;
  gyroZ = gz / 131.0;

  // Complementary filter for pitch and roll
  float accPitch = atan2(accY, accZ) * 180 / PI;
  float accRoll = atan2(-accX, accZ) * 180 / PI;
  pitch += gyroX * dt;
  roll  += gyroY * dt;
  pitch = 0.98 * pitch + 0.02 * accPitch;
  roll  = 0.98 * roll  + 0.02 * accRoll;
  yaw   += gyroZ * dt; // Optional for basic yaw control

  // PID - Pitch
  pitchErr = 0 - pitch;
  pitchI += pitchErr * dt;
  pitchD = (pitchErr - pitchPrevErr) / dt;
  pitchPrevErr = pitchErr;
  float pitchPID = kp * pitchErr + ki * pitchI + kd * pitchD;

  // PID - Roll
  rollErr = 0 - roll;
  rollI += rollErr * dt;
  rollD = (rollErr - rollPrevErr) / dt;
  rollPrevErr = rollErr;
  float rollPID = kp * rollErr + ki * rollI + kd * rollD;

  // Combine throttle + PID to control each motor
  int m1 = baseThrottle + pitchPID - rollPID; // Front
  int m2 = baseThrottle - pitchPID - rollPID; // Right
  int m3 = baseThrottle - pitchPID + rollPID; // Back
  int m4 = baseThrottle + pitchPID + rollPID; // Left

  // Limit motor values (1000–2000us)
  esc1.writeMicroseconds(constrain(m1, 1000, 2000));
  esc2.writeMicroseconds(constrain(m2, 1000, 2000));
  esc3.writeMicroseconds(constrain(m3, 1000, 2000));
  esc4.writeMicroseconds(constrain(m4, 1000, 2000));

  Serial.print("Pitch: "); Serial.print(pitch);
  Serial.print(" | Roll: "); Serial.println(roll);
}

What This Code Does:

  • Stabilizes pitch and roll using gyro + accel data
  • Runs PID loop for both axes
  • Outputs adjusted PWM values to 4 ESCs
  • Optional: yaw control can be added using gyroZ

Next Steps for Real Drone Flight:

  1. Tune PID gains carefully (start small, increase gradually)
  2. Integrate RC receiver for manual throttle/yaw/pitch/roll input
  3. Add arming/safety switch
  4. Implement altitude hold (barometer) or GPS navigation