Skip to content

Repository files navigation

esp32idf_APRS

A complete APRS station on a single ESP32 — native ESP-IDF, no Arduino.

IGate · Digipeater · Tracker · Weather · Telemetry, with a built-in web admin, an on-chip AFSK/FSK soft-modem, APRS-IS uplink, a runtime sensor-driver framework and OTA firmware updates.

Docs License Platform Framework

🌐 Languages: English · Español · Italiano


What is this?

esp32idf_APRS turns a bare ESP32 DevKit plus a cheap audio interface into a complete, self-contained APRS station. Everything runs on the ESP32 itself — there is no Arduino core, no PlatformIO, and no external DSP library. The entire signal chain, from the correlator demodulator through DPLL bit recovery, NRZI, the HDLC framer, the AX.25 codec and Reed–Solomon FX.25 forward error correction, executes on the microcontroller using only the SAR-ADC in continuous/DMA mode, the DAC, and a general-purpose timer.

In one sentence, the firmware demodulates AFSK/FSK audio from a radio's speaker or discriminator output, decodes HDLC/AX.25 (optionally FX.25 error-corrected) frames, gates them to APRS-IS over Wi-Fi, digipeats them back on RF, beacons its own position, weather and telemetry, modulates and transmits frames back through the ESP32's 8-bit DAC — and is configured entirely through a web admin served by the device itself. No serial console, no recompilation for ordinary settings.

📖 The full, exhaustive documentation lives at esp32idf-aprs.readthedocs.io — trilingual (English / Español / Italiano), with getting-started guides, hardware wiring, the DSP signal chain, the configuration engine, HTTP routes and troubleshooting. This README is only a presentation. For anything beyond a first look, go to the docs.


Highlights

  • On-chip soft-modem. AFSK 1200 Bd Bell 202 (standard APRS) with a dual demodulator, plus AFSK 1200 Bd V.23, AFSK 300 Bd, and G3RUH 9600 Bd FSK — all in pure C on the ESP32's own ADC/DAC.
  • FX.25 forward error correction. Reed–Solomon FEC over AX.25, RX-only or RX+TX, for reliable decodes in weak-signal conditions.
  • Full APRS-IS IGate. Bidirectional RF→INET and INET→RF gating with duplicate suppression, qAR/qAO construction, payload-type gating, callsign budlists, a local range gate (haversine distance) and prefix whitelist. Up to four APRS-IS servers can be listed, with automatic failover between the enabled ones.
  • Digipeater. A four-row n-N alias table (WIDE1-1 / WIDE2-2 / WIDE#-2 by default), each row with its own hop limit and trace/flood mode, plus hop-count trapping, fill-in-only operation and duplicate suppression.
  • Beacons, messaging & chat. Fixed-position beacons for tracker/igate/digi, APRS text messaging with ack/retry (RF and/or INET), and an in-browser message chat UI.
  • Weather & telemetry. On-air APRS Weather Reports with 1 Hz sensor refresh and per-field averaging, plus APRS Telemetry (analog A1–A5 + digital B1–B8) with T#nnn reports and metadata.
  • Objects, items & bulletins. Up to five own-station APRS Objects/Items and five bulletins (BLN1–BLN5), each on RF and/or INET with expiry/decay control.
  • Runtime sensor framework. A dynamic, self-registering driver registry (sensors_local) — includes a BMP180 (I²C) driver out of the box.
  • Web admin, ~30 pages. HTTP Basic auth, a live dashboard, a live traffic log and last-heard table (JSON long-poll), LittleFS file management (upload/download/delete/format), Wi-Fi AP/STA/AP+STA with scan and TX-power control, and CPU frequency control (80/160/240 MHz).
  • OTA updates with auto-rollback. Dual ota_0/ota_1 app slots; a failed image rolls back automatically on the next boot.
  • Trilingual UI. English, Spanish and Italian (compile-time, one language per image).

Feature matrix

Area Notes
AFSK 1200 Bd Bell 202 Dual demodulator, default profile
AFSK 1200 Bd V.23 · AFSK 300 Bd · G3RUH 9600 Bd FSK Multiple selectable modem profiles
HDLC / AX.25 UI frame RX + TX Full soft-modem TX/RX path
FX.25 (Reed–Solomon FEC over AX.25) RX-only / RX+TX modes
PTT keying Compile-time GPIO + polarity, minimum-unkey hold
CSMA / TX time-slot / TXDelay preamble preamble, tx_timeslot
Transmit duty-cycle limiter Optional ceiling over a rolling 10-minute window
APRS-IS IGate RF→INET & INET→RF Filters, dedup, budlist, third-party unwrap opt-in
APRS-IS multiserver failover 4 server slots, circular retry over the enabled ones
Local range gate & prefix gate Haversine distance + callsign-prefix whitelist
Digipeater Configurable n-N alias table (trace/flood), hop trapping, dup-suppression
Objects / Items · Bulletins Up to 5 each, RF and/or INET, expiry/decay
Messaging + ack/retry · Chat UI RF and/or INET
Weather Report 1 Hz sensor refresh, optional averaging
Telemetry Analog A1–A5 + digital B1–B8, T#nnn + metadata
Sensor driver framework Dynamic registry, BMP180 driver included
Web admin ~30 pages, live dashboard, traffic + last-heard
Storage LittleFS 512 KB, upload/download/delete/format
Networking Wi-Fi AP/STA/AP+STA, scan, TX power, SNTP (UTC clock, selectable timezone for display)
CPU frequency control 80 / 160 / 240 MHz
OTA update ota_0/ota_1 slots, auto-rollback
Localization EN / ES / IT, compile-time

Hardware

  • Target: ESP32 (classic, Xtensa dual-core), 4 MB flash. Dual-core is required — the ADC ISR and DAC sample clock are pinned to different cores on purpose.
  • Audio in (ADC): default GPIO33 (ADC1). GPIO 32–39 only — ADC2 is unusable while Wi-Fi is up.
  • Audio out (DAC): default GPIO25. GPIO 25 or 26 only — the ESP32 DAC is hard-wired to those pads.
  • PTT: default GPIO26, polarity selectable at compile time.
  • Note: ESP32-S3/C3/C6/H2 have no DAC and cannot run the TX path unmodified.

Board wiring (audio pins, PTT pin/polarity, sample rates) is set as compile-time constants in the top-level CMakeLists.txt. A KiCad radio-interface schematic is included under schematics/.

Full pinout tables and wiring constraints are in the Hardware chapter of the documentation.


Quick start

# Requires ESP-IDF v6.x (tested and locked at 6.0.2)
idf.py set-target esp32
idf.py build
idf.py -p PORT flash monitor

On first boot the device brings up a Wi-Fi AP; connect and open the web admin to configure your callsign, radio and services. After the one-time USB/UART flash, all further updates can be done from the web admin's About / Firmware page over OTA.

📖 The step-by-step first-run guide is in Getting Started.


Documentation

Everything is documented in full at 👉 esp32idf-aprs.readthedocs.io

The documentation is trilingual and organised into Functionalities (what the station does), Capabilities (cross-cutting properties), Internals (how it is built) and a Reference section:

This README is a presentation only — please consult the documentation for installation, wiring, configuration and internals.


Credits & license

Created by Emiliano Augusto González (LU3VEA).

Built on ideas from earlier projects — VP-Digi, ESP32APRS and LibAPRS; please refer to their authors for more information.

Released under the GNU General Public License v3. See LICENSE.