Sage and Pepper's Musings

Life through the eyes of two German Shepherds and their staff.


Adding ACARS to My ADS-B Flight Tracker: A Deep Dive into Aircraft Data Integration

For the past several months, I’ve been running a personal ADS-B flight tracking system from my home in Arlington, Texas. Using a Raspberry Pi with an RTL-SDR dongle feeding data to an Oracle database on my Mac Mini, I’ve built up a comprehensive system that tracks aircraft positions, detects routes, and provides real-time visualization through a Flask web application.

But I wanted more. ADS-B gives you position, altitude, speed, and heading—the where of flight tracking. What about the what? What’s the aircraft actually doing? When did it push back from the gate? What’s the pilot reporting about turbulence ahead? That’s where ACARS comes in.

What is ACARS?

ACARS (Aircraft Communications Addressing and Reporting System) is essentially text messaging for aircraft. It’s a digital datalink system that’s been around since 1978, transmitting short messages between aircraft and ground stations on VHF frequencies around 129-131 MHz.

The messages I’m now capturing include:

OOOI Events – Out of gate, Off ground, On ground, Into gate. Airlines use these timestamps for crew pay calculations and on-time performance metrics.

Position Reports – Lat/long and altitude transmitted via datalink, useful over oceans where radar coverage doesn’t exist.

Weather Data – Pilot reports (PIREPs) on turbulence, icing, and winds aloft.

Maintenance Messages – Engine performance data, fault codes, and system alerts sent automatically to airline operations.

Operational Messages – Gate assignments, fuel data, delay codes, connecting flight info.

The Hardware Setup

Since ACARS operates on completely different frequencies than ADS-B (129 MHz vs 1090 MHz), I needed additional hardware:

  • A second RTL-SDR V5 dongle (~$35)
  • A VHF dipole antenna tuned for 129-131 MHz (~$25)

My existing ADS-B antenna is optimized for 1090 MHz and would perform terribly at VHF frequencies. The RTL-SDR dipole kit was perfect—telescoping elements that I extended to about 22 inches (quarter wavelength for 130 MHz), and no soldering required.

Software Architecture

The ACARS integration follows the same architectural patterns as my existing ADS-B system:

Database Integration with Oracle

The ACARS data lives in Oracle 23ai Free (running in Docker) alongside my existing ADS-B tables. I used interval partitioning on the acars_messages table—new daily partitions are created automatically as data arrives, and a scheduled job drops partitions older than 14 days.

The key insight was linking ACARS messages to existing ADS-B flight records. ACARS messages include aircraft registration (tail number) and flight ID, while ADS-B provides the ICAO hex address. By joining through the aircraft table (which maps registrations to ICAO addresses), I can correlate operational messages with position tracks:

Real-time Flight Enrichment

One of the most valuable features is using ACARS data to enrich the ADS-B records in real-time. When the collector links an ACARS message to a flight, it immediately:

  1. Updates the flight with the ACARS flight number (often more reliable than ADS-B callsign)
  2. Sets the callsign if the ADS-B data was missing it
  3. For OOOI ‘OFF’ events (H2 label): sets actual_departure in the flight_routes table
  4. For OOOI ‘ON’ events (H3 label): sets actual_arrival in the flight_routes table

This means my route tracking now has precise departure and arrival times from the airline’s own OOOI system, not just estimates based on when the aircraft entered or left my ADS-B coverage area.

The Web Interface

I extended my existing Flask webapp with an /acars page that provides:

  • Real-time statistics: messages today, OOOI events, weather reports, unique aircraft
  • Sortable tables: click any column header to sort ascending or descending
  • Filter buttons: quickly show only OOOI, Weather, Position, or Maintenance messages
  • Full-text search: filter by aircraft registration, flight number, or message content
  • Linked indicator: shows which ACARS messages matched to ADS-B flights

The page auto-refreshes every 30 seconds, so I can leave it open on a secondary monitor and watch the messages stream in. The most interesting ones are the OOOI events—seeing “OFF (Takeoff)” appear seconds after watching the aircraft symbol climb on my ADS-B map is deeply satisfying.

Lessons Learned

Coordinate Parsing is Tricky

ACARS position reports come in multiple formats: decimal degrees (N32.897W097.038), degrees and decimal minutes (N3253.8W09702.3), and various others. My initial regex was too permissive and extracted values like “35218” as latitude, which Oracle rightfully rejected. The fix required strict pattern matching with mandatory decimal points and range validation.

Oracle Reserved Words

I initially named a column “MODE” (for ACARS mode). Oracle was not amused. Renamed to “ACARS_MODE” and life continued.

Parity Errors and Gain Settings

acarsdec reports “too many parity errors” when signal quality is poor. The fix is usually adjusting the RTL-SDR gain—too high and it overloads, too low and weak signals get lost in the noise. I found -g 38 works well for my setup near DFW.

What’s Next?

With ACARS integrated, I’m already thinking about the next additions:

  • VDL Mode 2 decoding for additional digital messages
  • Correlating weather PIREPs with actual flight paths on the map
  • Building analytics dashboards for delay patterns by airline/route
  • Possibly adding ADS-B Exchange data for aircraft outside my receiver range

The beauty of running your own flight tracking system is that you own the data and can extend it however you want. What started as a simple “let me see what’s flying overhead” project has evolved into a genuinely useful aviation data platform.

Technical Summary

ComponentDetails
HardwareRTL-SDR V5, VHF dipole antenna (separate from ADS-B setup)
Decoderacarsdec with JSON output over UDP
Frequencies129.125, 130.025, 130.450, 131.550 MHz (DFW area)
DatabaseOracle 23ai Free with interval partitioning (14-day retention)
CollectorPython with oracledb, real-time flight enrichment
Web InterfaceFlask with sortable/filterable tables, auto-refresh

The complete integration package—including database schemas, Python collectors, and web interface code—is available for anyone interested in building their own. Happy tracking!



Leave a comment