A compact live aircraft radar built for the M5Stack Dial using the ESP32-S3, OpenSky Network, and ADSBdb.
The project displays nearby aircraft on the M5Stack Dial’s 240 × 240 circular screen, allows touch-based aircraft selection, supports rotary encoder range control, and provides multiple pages of live aircraft and route information.
View the published project page on Schematik:
https://www.schematik.io/projects/live-flight-radar-scanner-mt5stack-p2gh
- Live aircraft radar centered on a configurable location
- Nearby aircraft loaded from OpenSky Network
- Aircraft icons rotated according to reported heading
- Touch selection of aircraft on the radar
- Rotary encoder control for radar range
- Radar range from 10 km to 150 km
- Reliable detent-based encoder handling
- Delayed radar refresh after encoder movement stops
- Nearby airport markers with ICAO identifiers
- Five aircraft information pages
- Callsign-based origin and destination lookup
- ICAO and IATA airport formatting
- Aircraft and operator metadata where available
- Graceful fallback to
Unavailable - No route lookup until the user selects an aircraft
- In-memory caching to reduce repeated API calls
- No SD card or filesystem dependency
- M5Stack Dial
- ESP32-S3
- 1.28-inch 240 × 240 round TFT display
- Rotary encoder with push capability
- Capacitive touch screen
- 2.4 GHz Wi-Fi connection
- USB-C power and programming
- Arduino C++
- PlatformIO
- M5Dial library
- ArduinoJson
- OpenSky Network API
- ADSBdb API
Use the following PlatformIO board target:
board = esp32-s3-devkitc-1Do not use:
board = m5stack_dialThat board ID does not exist in PlatformIO.
OpenSky is used for live aircraft state vectors:
- ICAO24 address
- Callsign
- Origin country
- Latitude
- Longitude
- Barometric altitude
- Geometric altitude
- Ground speed
- Heading
- Vertical speed
- Squawk
- Ground status
- SPI status
- Position source
- Aircraft category
- Last contact time
- Position time
OpenSky does not provide a verified live commercial route or intended destination in its live state-vector response.
ADSBdb is used only after the user selects an aircraft.
It may provide:
- Origin airport
- Destination airport
- ICAO airport codes
- IATA airport codes
- Airline name
- Airline ICAO code
- Airline IATA code
- Airline callsign
- Airline country
- Aircraft registration
- Aircraft type
- Aircraft model
- Manufacturer
- Owner or operator
Availability depends on ADSBdb coverage.
If route or aircraft metadata cannot be verified, the firmware displays:
Unavailable
The application does not invent, infer, or reuse stale route data.
Displays:
- Callsign
- ICAO24 address
- Airborne or ground state
- Departure airport
- Destination airport
- Route source
- Origin country
Example:
FLIGHT / ROUTE 1/5
UAE1
ICAO 8966E6 AIRBORNE
FROM OMDB (DXB)
TO EGLL (LHR)
SOURCE ADSBDB
Displays:
- Distance from the configured radar center
- Heading
- Barometric altitude
- Geometric altitude
- Ground speed
- Vertical speed
- Altitude color band
Displays:
- Latitude
- Longitude
- Squawk
- SPI state
- Position source
- Aircraft category
- Receiver count
- Position timestamp
Displays, where available:
- Registration
- Aircraft type
- Model
- Manufacturer
- Owner or operator
Unknown fields are shown as Unavailable.
Displays, where available:
- Airline name
- ICAO airline code
- IATA airline code
- Airline callsign
- Country
Unknown fields are shown as Unavailable.
| Altitude | Color |
|---|---|
| 0–9,999 ft | Cyan |
| 10,000–19,999 ft | Green |
| 20,000–29,999 ft | Yellow |
| 30,000–34,998 ft | Orange |
| 34,999 ft and above | Red |
| Altitude unavailable | Grey |
Outside detail mode:
- Turn clockwise to increase radar range
- Turn anticlockwise to decrease radar range
- One physical detent changes the range by 5 km
- Range is constrained between 10 km and 150 km
- Fast turns are accumulated correctly
- The OpenSky request is delayed until knob movement stops
Inside detail mode:
- Turn clockwise or anticlockwise to move between the five information pages
On the radar screen:
- Tap an aircraft icon to select it
- Route and metadata lookups are performed only after selection
On an information page:
- Tap the screen to return to the radar
The firmware includes fixed markers for nearby airports around Dubai.
Current markers include:
| ICAO | IATA | Airport |
|---|---|---|
| OMDB | DXB | Dubai International Airport |
| OMDW | DWC | Al Maktoum International Airport |
| OMSJ | SHJ | Sharjah International Airport |
| OMAA | AUH | Zayed International Airport |
| OMRK | RKT | Ras Al Khaimah International Airport |
| OMFJ | FJR | Fujairah International Airport |
Only airports inside the current radar radius are drawn.
.
├── include/
│ ├── plane_icon.h
│ ├── secrets.example.h
│ └── secrets.h
├── src/
│ └── main.cpp
├── .gitignore
├── platformio.ini
└── README.md
include/secrets.h must remain local and must not be committed.
Create a local copy:
Copy-Item include\secrets.example.h include\secrets.hOr copy it manually.
Edit:
include/secrets.h
Example:
#pragma once
const char* WIFI_SSID = "YOUR_WIFI_SSID";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";
const char* OPENSKY_CLIENT_ID = "YOUR_OPENSKY_CLIENT_ID";
const char* OPENSKY_CLIENT_SECRET = "YOUR_OPENSKY_CLIENT_SECRET";
const float HOME_LATITUDE = 25.2048f;
const float HOME_LONGITUDE = 55.2708f;Do not commit real credentials or precise private coordinates.
Your src/main.cpp should contain:
#include "secrets.h"A typical platformio.ini may look like:
[env:esp32-s3-devkitc-1]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
monitor_speed = 115200
lib_deps =
m5stack/M5Dial
bblanchon/ArduinoJsonAdjust library versions if your project already pins specific releases.
From the project folder:
pio runConnect the M5Stack Dial through USB-C and run:
pio run --target uploadpio device monitorDefault serial speed:
115200
The radar polls OpenSky periodically for aircraft inside the configured bounding box.
The bounding box is calculated from:
- Home latitude
- Home longitude
- Current radar radius
A route request is sent only when an aircraft is selected.
The selected aircraft callsign is used with ADSBdb.
The result is accepted only when:
- The response is valid JSON
- A route object exists
- The returned callsign matches the selected callsign
- Origin and destination identifiers are present
Otherwise, the display shows Unavailable.
Aircraft metadata is looked up independently using ICAO24.
A failed aircraft lookup does not prevent route information from displaying.
Successful and failed lookups should be cached for a limited time to reduce API requests and avoid repeated lookups.
The cache is stored in memory only and is cleared when the device restarts.
Never commit:
- Wi-Fi SSID
- Wi-Fi password
- OpenSky client ID
- OpenSky client secret
- Device access tokens
- Exact home coordinates
- Private proxy credentials
Recommended .gitignore entry:
include/secrets.hBefore making the repository public, check for exposed values:
git grep -n -i "password"
git grep -n -i "secret"
git grep -n -i "client_id"
git grep -n -i "client_secret"Also inspect Git history if credentials were previously committed.
- OpenSky state vectors are not guaranteed to be complete or uninterrupted.
- Aircraft without valid position data are skipped.
- Callsigns may be missing, delayed, reused, or malformed.
- ADSBdb route information may be missing or outdated.
- ADSBdb is not an authoritative airline operational flight plan.
- Aircraft metadata coverage is incomplete.
- Private, military, cargo, repositioning, and general aviation flights may have little or no route information.
- The firmware is not intended for navigation or air-traffic-control use.
- The display is limited to 24 aircraft per refresh.
- The device requires 2.4 GHz Wi-Fi.
- API availability and limits may change.
This project is intended for:
- Embedded systems experimentation
- Aviation visualization
- ESP32-S3 development
- M5Stack Dial interface design
- Learning about ADS-B data
- Learning about REST APIs on microcontrollers
It is not intended for:
- Air-traffic control
- Flight safety decisions
- Navigation
- Emergency response
- Surveillance of restricted aircraft
- Commercial operational dispatch
M5Stack Dial, ESP32-S3, live flight radar, aircraft tracker, ADS-B radar, OpenSky, ADSBdb, Arduino aircraft scanner, PlatformIO aviation project, round TFT radar, rotary encoder aircraft display.
A visual overview of the project is available here:
https://www.schematik.io/projects/live-flight-radar-scanner-mt5stack-p2gh
Issues and pull requests are welcome.
When contributing:
- Do not commit credentials
- Do not add paid API dependencies without discussion
- Preserve fallback behavior for unavailable data
- Keep route lookups selection-based
- Avoid breaking touch controls, airport markers, encoder handling, or altitude colors
- Preserve the
esp32-s3-devkitc-1build target
MIT License
Copyright (c) 2026 Aliferous3
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files, to deal in the software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and sell copies of the software, subject to the conditions included in the repository’s LICENSE file.
This project uses third-party aviation data that may be delayed, incomplete, inaccurate, or unavailable.
Do not use this device or its displayed information for navigation, operational flight decisions, safety-critical purposes, or air-traffic-control activity.
All trademarks, airline names, airport identifiers, and third-party services belong to their respective owners.