Noureddine RAMDI / Trail Mate: Offline GPS and Dual LoRa Mesh Firmware for ESP32 Devices

Created Tue, 05 May 2026 13:37:39 +0000 Modified Sat, 23 May 2026 20:41:27 +0000

vicliu624/trail-mate

Trail Mate tackles a tough problem: providing reliable GPS navigation and team communication without relying on cellular networks. It runs entirely offline on ESP32-class hardware, combining GPS, SD card-based map rendering, and two competing LoRa mesh protocols to keep teams connected in remote environments.

What trail mate firmware does and how it’s built

At its core, Trail Mate is an embedded C firmware designed for handheld ESP32 devices, optimized for offline-first operation. It provides GPS navigation with a fixed north-up map renderer that reads tile data from an SD card, ensuring responsiveness without network dependency. The firmware supports text messaging and team coordination over LoRa radio, crucial for outdoor or remote use cases where cellular coverage is unreliable or unavailable.

The system supports two LoRa mesh protocols simultaneously: the public Meshtastic mesh network and the more recent MeshCore protocol. This dual compatibility is unusual and technically challenging, especially on constrained hardware like ESP32 microcontrollers. Team pairing and secure key exchange are handled via ESP-NOW, a low-level wireless protocol from Espressif, ensuring quick and secure team setup without cellular or Wi-Fi.

Architecturally, Trail Mate emphasizes hardware abstraction. Protocol logic, storage management, and the user interface are decoupled from board-specific drivers, enabling support for multiple ESP32 and nRF52 targets. This design reduces platform lock-in and encourages code reuse across hardware variants.

The build system uses PlatformIO with the Arduino framework, with the LILYGO T-LoRa-Pager (SX1262 radio) as the primary validated hardware. This setup balances ease of use with low-level control, appropriate for embedded C development.

Why the dual LoRa protocol support stands out

Supporting both Meshtastic and MeshCore protocols on the same device is a non-trivial engineering feat. Each protocol has different packet paths and radio configurations, and the firmware maintains a minimal footprint to fit within ESP32 resource constraints.

The codebase implements a compatibility layer that switches between the two protocols depending on the network environment or user choice. This allows users to join existing Meshtastic public meshes or private MeshCore networks without changing hardware. The tradeoff is increased complexity in protocol handling logic and careful resource management to avoid memory bloat or timing issues.

The map renderer is performance-optimized and deterministic, using fixed north-up orientation and SD card stored tiles. This avoids GPS jitter affecting user orientation and provides consistent UX. The tile storage on SD cards is a practical choice, balancing storage capacity and read performance.

ESP-NOW integration for team key exchange is another highlight. It provides secure, low-latency communication that pairs team members without relying on traditional network infrastructure. This fits the offline-first philosophy and improves user experience in field scenarios.

Overall, the code is surprisingly clean given the complexity. The hardware abstraction layer ensures the core logic remains portable and testable. However, the tradeoff is that the firmware focuses on deterministic behavior and honest uncertainty representation rather than feature overload, which some users might find limiting.

// Simplified pseudo-code illustrating dual protocol packet handling
void onLoRaPacketReceived(Packet *pkt) {
    if (pkt->protocol == MESHTASTIC) {
        handleMeshtasticPacket(pkt);
    } else if (pkt->protocol == MESHCORE) {
        handleMeshCorePacket(pkt);
    } else {
        // Unknown protocol
        discardPacket(pkt);
    }
}

This snippet shows how the firmware discriminates packets dynamically, a core part of supporting two mesh networks concurrently.

Explore the project

The repository organizes its code to separate hardware-specific drivers from protocol and UI logic. Key directories include:

  • src/protocol/ for LoRa mesh protocol implementations
  • src/ui/ for the user interface and map rendering
  • src/storage/ managing SD card tile access
  • boards/ containing board-specific configurations and drivers

The README provides a thorough overview of the architecture and design philosophy, emphasizing offline operation and deterministic behavior.

There are no explicit installation or quickstart commands documented, so trying out the firmware involves using PlatformIO to build and flash onto supported hardware, primarily the LILYGO T-LoRa-Pager.

Studying the codebase offers insights into embedded firmware patterns: hardware abstraction, multi-protocol support, and constrained resource management.

Verdict

Trail Mate is a solid embedded firmware project for anyone interested in offline GPS navigation and LoRa mesh messaging on ESP32 devices. Its dual protocol support sets it apart, providing versatility for different mesh networks.

The architecture and clean separation of concerns make it a good reference for embedded developers tackling similar offline communication challenges. The honest focus on deterministic behavior over feature bloat is refreshing, though it may limit some advanced use cases.

If you work with ESP32 or embedded devices in remote or offline contexts and want to understand how to juggle multiple radio protocols and offline map rendering efficiently, this repo is worth your time. However, expect to invest effort in hardware setup and PlatformIO configuration, as the project assumes familiarity with embedded development tooling.

In short, Trail Mate solves a real-world problem with pragmatic engineering and a clear design philosophy, making it a valuable resource for embedded systems practitioners.


→ GitHub Repo: vicliu624/trail-mate ⭐ 301 · C