Veerendra R. Patil
Project 02 — Aeris
02 Autonomous systems · Robotics software

Aeris — Ground Control Station for an ESP32-S3 drone

A desktop ground station that speaks the drone's own protocol over Wi-Fi. Telemetry, manual flight, PID tuning and flight recording — without touching a line of the drone's firmware.

RoleSole designer & developer
StackPython · PySide6 · cflib · CRTP · PyQtGraph
TargetESP32-S3 quadcopter over Wi-Fi
StatusFlying — telemetry and manual control verified
Aeris running live against the drone — attitude plot, link dashboard, artificial horizon, manual control Screen capture
01 — Overview

The drone could fly. Nothing could tell me why it flew badly.

A small ESP32-S3 quadcopter running Crazyflie-compatible firmware will take commands and stay in the air, but a bare link gives you no visibility: no attitude history, no link quality, no way to change gains without a reflash, and no record of what happened on the flight that just ended badly.

Aeris is the missing half of that system — a ground control station built to make the drone observable and tunable in flight, communicating over Wi-Fi using the drone's existing CRTP protocol so that no firmware modification was required.

02 — System

Drone to desktop, over the air

Commands and telemetry share a single Wi-Fi link. The station opens a CRTP connection through cflib, subscribes to the drone's log variables, and fans that stream out to every panel that needs it — plots, instruments, the recorder — while control input flows back the other way at interactive rates.

Aeris architecture: drone over Wi-Fi CRTP into a communication layer, which feeds telemetry, control and data layers, all rendered by the PySide6 user interface ESP32-S3 drone IMU · motors · radio Wi-Fi · CRTP Comm layer cflib · link + packets Telemetry Attitude · gyro · battery Control Keyboard · virtual · gamepad Data Flight recorder · CSV / JSON PySide6 GCS PyQtGraph · instruments · panels

Architecture diagram — drawn for this case study

03 — Engineering

What I actually built

  • A modular four-layer architecture — communication, control, data and UI — so a change to the link protocol never reaches into a plotting widget, and the recorder can be driven by the same stream that feeds the graphs.
  • Live multi-channel telemetry graphing built on PyQtGraph, plotting roll, pitch and yaw against a moving time axis with per-signal tabs for gyro, accelerometer, motors, battery and link.
  • Manual flight control with three interchangeable input sources — keyboard, on-screen virtual sticks, and a physical gamepad — feeding a shared thrust / yaw / pitch / roll command channel.
  • A PID tuning panel that changes gains against the live aircraft, so a tuning pass is a conversation with the drone rather than a reflash-and-hope cycle.
  • A flight recorder that captures the telemetry stream and exports it to CSV or JSON for post-flight analysis.
  • An operational dashboard — link state, battery voltage, link quality, latency, packet rate, protocol version, arm state and uptime — plus an always-reachable emergency stop.
04 — In flight

The whole loop, closed

Gamepad in hand, station on the laptop, aircraft in the air. The same link carrying the stick commands is carrying the attitude stream back into the plot.

Gamepad input → GCS → aircraft01
Outdoor flight test02
A custom ESP32-S3 quadcopter flight-controller board, with the ESP32-S3-WROOM module at the centre of an X-shaped frame
The airframe: an ESP32-S3-WROOM flight controller integrated into the frame03
05 — Implementation

Decisions worth defending

  • Speak the drone's protocol, don't invent one. Implementing against CRTP through cflib meant the aircraft's firmware stayed untouched — the station is a client of an existing, tested interface rather than a second thing that can be wrong.
  • Separate the transport from the view. Telemetry arrives once and is distributed; panels subscribe. Adding the flight recorder was a new consumer, not a rewrite.
  • Make the link itself visible. Latency, packet rate and link quality are first-class readouts. On a Wi-Fi control link, the health of the connection is flight-critical information.
  • Instruments over numbers where it matters. An artificial horizon and compass communicate attitude faster than three decimal values ever will — the numbers stay available underneath.
06 — Results

Outcome

0firmware modifications required
3interchangeable control inputs
4decoupled subsystems
CSV / JSONflight-log export formats

The station connects, streams live attitude data, flies the aircraft manually from three different input devices, tunes PID gains against the running drone and records the session for later analysis — verified in indoor and outdoor flight, on video above.

07 — Technologies

Application

  • Python
  • PySide6
  • PyQtGraph

Link

  • cflib
  • CRTP
  • Wi-Fi

Aircraft

  • ESP32-S3
  • IMU
  • PID control

Data

  • CSV
  • JSON
  • Flight recorder
08 — Repository

Source

Code and build notes live on GitHub.

Veerendra R. Patil — © 2026 Back to index