---
title: "StratoTrack LoRa Pro"
canonical: https://hamzadenizyilmaz.com.tr/projeler/stratotrack-lora-pro
author: "Hamza Deniz Y\u0131lmaz"
created: 2026-07-23T02:34:58.0487293+00:00
published: 2026-07-23T02:34:58.0487293+00:00
---

# StratoTrack LoRa Pro

## StratoTrack LoRa Pro




**Offline long-range GPS beacon tracker powered by ESP32-C6, NEO-6M GNSS, RAK3172/RAK3272S LoRa P2P, a 2.8-inch SPI TFT dashboard, and a local Wi-Fi web panel.**




StratoTrack LoRa Pro is an embedded tracking project designed for offline field use. The tracker reads GPS/GNSS data from a NEO-6M module, renders a professional live dashboard on an ILI9341 TFT screen, broadcasts compact position packets over LoRa P2P using a RAK3172/RAK3272S module, and exposes a local web dashboard from the ESP32-C6 itself.




The project does **not** require GSM, SIM cards, cloud services, routers, internet access, or LoRaWAN gateways. It is designed as a direct, offline, long-range LoRa beacon system.




---




## Table of Contents



- [Project Goals](#project-goals)
- [What This Project Does](#what-this-project-does)
- [System Architecture](#system-architecture)
- [Hardware Overview](#hardware-overview)
- [Main Tracker Hardware](#main-tracker-hardware)
- [Second LoRa Receiver Hardware](#second-lora-receiver-hardware)
- [Pinout](#pinout)
- [Firmware Structure](#firmware-structure)
- [Programming Language and Libraries](#programming-language-and-libraries)
- [PlatformIO Setup](#platformio-setup)
- [Build, Upload and Monitor](#build-upload-and-monitor)
- [TFT Dashboard](#tft-dashboard)
- [Web Panel](#web-panel)
- [GNSS / Satellite Data](#gnss--satellite-data)
- [LoRa P2P Protocol](#lora-p2p-protocol)
- [Second LoRa Receiver](#second-lora-receiver)
- [Packet Format](#packet-format)
- [Configuration](#configuration)
- [Field Testing Guide](#field-testing-guide)
- [Troubleshooting](#troubleshooting)
- [Safety and Legal Notes](#safety-and-legal-notes)
- [Roadmap](#roadmap)
- [License](#license)




---




## Project Goals




StratoTrack LoRa Pro was built with the following goals:



1. **Offline operation**

The device must work without cellular network, internet, cloud platform, or LoRaWAN gateway.
2. **Long-range beaconing**

The tracker periodically transmits compact GPS packets over raw LoRa P2P.
3. **Professional field UI**

The device has a local TFT interface showing GPS, satellite, LoRa and TX status.
4. **Local diagnostics**

A Wi-Fi access point and local web panel allow live monitoring from a phone or laptop.
5. **Modular firmware**

The codebase is organized as multiple firmware modules instead of a single sketch.
6. **Expandable architecture**

The project can later support ACK messages, LoRa command mode, multiple nodes, track logging, and additional dashboard pages.




---




## What This Project Does




The main tracker device:



- reads NMEA data from a NEO-6M GPS module,
- determines whether GPS state is ` WAIT `, ` DATA `, or ` FIX `,
- parses GPS satellite data from NMEA GSV messages,
- displays GPS and LoRa data on a 2.8-inch SPI TFT,
- starts a local Wi-Fi access point,
- serves a browser-based web dashboard at ` http://192.168.4.1 `,
- builds a compact tracker packet,
- converts the packet to HEX for RAK RUI3 P2P transmission,
- sends the packet over LoRa P2P,
- prints detailed debug logs through Serial Monitor.




A second LoRa receiver can be added using another ESP32/Arduino-compatible board plus a RAK3172/RAK3272S module. The receiver listens for LoRa P2P packets and decodes the tracker data.




---




## System Architecture




### Main Tracker




```text
NEO-6M GPS
    |
    | UART / NMEA 9600 baud
    v
ESP32-C6
    |
    | SPI
    v
2.8-inch ILI9341 TFT Display

ESP32-C6
    |
    | UART / RAK RUI3 AT Commands
    v
RAK3172 / RAK3272S LoRa Module
    |
    | LoRa P2P 868 MHz
    v
Second LoRa Receiver
```




### Local Web Panel




```text
Phone / Laptop
    |
    | Wi-Fi AP
    v
ESP32-C6 Local Web Server
    |
    v
http://192.168.4.1
```




The web panel is served directly by the ESP32-C6. No router or internet connection is required.




---




## Hardware Overview




### Main Tracker Hardware




Recommended hardware:




| Part | Purpose |
| --- | --- |
| ESP32-C6 DevKitC-1 | Main controller |
| NEO-6M GPS | GNSS position source |
| RAK3172 / RAK3272S | LoRa P2P modem |
| 2.8-inch SPI TFT ILI9341 | Local dashboard |
| 18650 / LiPo battery system | Portable power |
| USB cable | Programming/debug |
| LoRa antenna | Required before TX |




### Second LoRa Receiver Hardware




For the second LoRa receiver:




| Part | Purpose |
| --- | --- |
| ESP32 / ESP32-C6 / Arduino-compatible MCU | Receiver controller |
| RAK3172 / RAK3272S | LoRa P2P receiver |
| USB cable | Serial Monitor |
| LoRa antenna | Required |




The second receiver firmware listens in P2P mode and prints decoded packets.




---




## Pinout




The current tested tracker pinout is:




### Main Tracker: ESP32-C6 + RAK + GPS + TFT




| Module | Module Pin | ESP32-C6 Pin | Notes |
| --- | --- | --- | --- |
| RAK3272S / RAK3172 | UART2\_TX | GPIO0 | ESP32 RX for LoRa |
| RAK3272S / RAK3172 | UART2\_RX | GPIO1 | ESP32 TX for LoRa |
| RAK3272S / RAK3172 | 3V3 | 3V3 | Do not use 5V |
| RAK3272S / RAK3172 | GND | GND | Common ground |
| NEO-6M | TX | GPIO4 | GPS TX to ESP32 RX |
| NEO-6M | RX | GPIO5 / not required | Optional |
| NEO-6M | VCC | 5V or 3V3 depending on board | Most breakout boards work well with 5V |
| NEO-6M | GND | GND | Common ground |
| TFT ILI9341 | SCK | GPIO6 | SPI clock |
| TFT ILI9341 | MOSI | GPIO7 | SPI MOSI |
| TFT ILI9341 | MISO | Not connected | Not required |
| TFT ILI9341 | CS | GPIO10 | Chip select |
| TFT ILI9341 | DC | GPIO2 | Data/command |
| TFT ILI9341 | RST | GPIO3 | Reset |
| TFT ILI9341 | BL/LED | 3V3 | Backlight always on |




### Important Wiring Rules



- All grounds must be common.
- RAK LoRa module must be powered from 3.3V.
- Do not transmit LoRa without antenna.
- GPS RX is optional; only GPS TX is needed for receiving NMEA.
- If LoRa returns unreadable characters, check baud rate and TX/RX direction.
- If GPS ` NMEA ` count is zero, the GPS TX pin is not reaching ESP32 RX.




---




## Firmware Structure




StratoTrack LoRa Pro firmware is written in **C++** using the **Arduino framework** on top of **PlatformIO**. The project is intentionally organized as a modular embedded firmware instead of a single-file sketch. Each hardware responsibility is separated into its own module to make the codebase easier to maintain, debug, extend, and publish as an open-source project.




The firmware runs on an **ESP32-C6** main controller and communicates with external modules through UART and SPI interfaces. The GPS module provides GNSS/NMEA data, the RAK LoRa module handles long-range P2P communication through AT commands, the TFT display renders the local dashboard, and the ESP32-C6 exposes a local Wi-Fi web panel.




### ` config.h `




Contains all hardware pin definitions, baud rates, LoRa parameters, display settings, firmware metadata and feature flags.




This is the first file to edit when changing:



- pins,
- LoRa frequency,
- spreading factor,
- device ID,
- Wi-Fi SSID/password,
- display rotation,
- beacon interval.




### ` globals.h ` / ` globals.cpp `




Contains shared global objects and shared state variables used across modules.




Examples:




```cpp
TinyGPSPlus gps;
HardwareSerial GPSSerial;
HardwareSerial LoRaSerial;
String gpsState;
String loraState;
String txState;
```




This prevents duplicate object definitions across multiple ` .cpp ` files.




### ` gps_tracker.h ` / ` gps_tracker.cpp `




Responsible for GPS and GNSS logic:



- reads NMEA data from GPS UART,
- updates TinyGPSPlus,
- tracks NMEA character count,
- detects GPS state: ` WAIT `, ` DATA `, ` FIX `,
- parses GSV satellite messages,
- stores PRN, SNR, elevation and azimuth,
- provides helper functions for latitude, longitude, speed, altitude and satellite count.




### ` lora_modem.h ` / ` lora_modem.cpp `




Responsible for RAK3172/RAK3272S communication:



- sends AT commands,
- configures RAK P2P mode,
- builds LoRa tracker packets,
- converts packets to HEX,
- transmits packets with ` AT+PSEND `,
- tracks TX state and last RAK response.




### ` display_ui.h ` / ` display_ui.cpp `




Responsible for the TFT dashboard:



- initializes ILI9341,
- draws the GNSS panel,
- draws LoRa Radio panel,
- draws NMEA Stream panel,
- shows satellite PRN:SNR values,
- shows GPS state, fix, speed and altitude,
- shows LoRa and TX state.




### ` web_panel.h ` / ` web_panel.cpp `




Responsible for the local web dashboard:



- starts ESP32-C6 Wi-Fi AP,
- serves the HTML dashboard,
- exposes ` /api/status `,
- shows live GPS/LoRa data,
- shows satellites,
- provides map link when GPS fix is available.




### ` main.cpp `




The firmware entry point:



- initializes Serial Monitor,
- initializes TFT,
- initializes GPS UART,
- initializes LoRa UART,
- starts web panel,
- starts LoRa P2P mode,
- runs the main loop,
- updates display,
- handles web requests,
- sends LoRa packets periodically.




---




## Programming Language and Libraries




### Language




```text
C++ / Arduino Framework
```




The project uses Arduino-style APIs, but follows a modular C++ firmware layout.




### Development Environment




```text
VS Code + PlatformIO
```




PlatformIO is recommended because it provides:



- repeatable builds,
- dependency management,
- cleaner modular project structure,
- easier GitHub publishing,
- better Serial Monitor control.




### Main Libraries




#### TinyGPSPlus




```cpp
#include
```




Used to parse GPS/NMEA data from the NEO-6M module.




Provides:



- latitude,
- longitude,
- speed,
- altitude,
- satellite count,
- GPS fix validity,
- data age.




The project also manually parses ` $GPGSV ` / ` $GNGSV ` messages to display satellite PRN, SNR, elevation and azimuth.




#### Adafruit GFX




```cpp
#include
```




Used for graphics primitives:



- text,
- lines,
- rectangles,
- rounded rectangles,
- colored panels,
- UI layout.




#### Adafruit ILI9341




```cpp
#include
```




Used to drive the 2.8-inch SPI TFT screen.




#### WiFi




```cpp
#include
```




Used to create the ESP32-C6 local Wi-Fi access point.




#### WebServer




```cpp
#include
```




Used to serve the local dashboard and JSON API.




---




## PlatformIO Setup




Example ` platformio.ini `:




```ini
[env:esp32c6]
platform = https://github.com/pioarduino/platform-espressif32.git#develop
board = esp32-c6-devkitc-1
framework = arduino

upload_port = COM3
monitor_port = COM5

monitor_speed = 115200
upload_speed = 460800
monitor_rts = 0
monitor_dtr = 0

lib_deps =
  mikalhart/TinyGPSPlus
  adafruit/Adafruit GFX Library
  adafruit/Adafruit ILI9341
  adafruit/Adafruit BusIO

build_flags =
  -DARDUINO_USB_CDC_ON_BOOT=1
  -DARDUINO_USB_MODE=1
```




### Notes for ESP32-C6




ESP32-C6 Arduino support may require the ` pioarduino ` platform. If you see:




```text
Error: This board doesn't support arduino framework!
```




use the platform line shown above.




---




## Build, Upload and Monitor




Clean build:




```powershell
pio run -t clean
```




Build:




```powershell
pio run
```




Upload:




```powershell
pio run -t upload
```




Monitor:




```powershell
pio device monitor -p COM5 -b 115200
```




If COM5 disconnects randomly, try:




```ini
monitor_rts = 0
monitor_dtr = 0
```




---




## TFT Dashboard




The TFT dashboard is designed for field usage and shows the most important status without requiring a laptop.




Main sections:




### GNSS Panel




Shows:



- GPS state: ` WAIT `, ` DATA `, ` FIX `,
- used satellites,
- visible satellites,
- mode,
- latitude,
- longitude.




### LoRa Radio Panel




Shows:



- LoRa state,
- TX state,
- last TX status.




### NMEA Stream Panel




Shows:



- NMEA character count,
- GNSS stream activity,
- useful debug status.




### Satellite Panel




Shows:



- GPS PRN numbers,
- SNR values,
- active satellite list.




Example:




```text
G05:24  G12:41  G21:38  G29:15
```




Where:



- ` G05 ` = GPS PRN 05,
- ` 24 ` = signal-to-noise ratio.




---




## Web Panel




The ESP32-C6 starts a local Wi-Fi access point.




Default credentials:




```text
SSID: GPS-TRACKER-T1
PASS: 12345678
URL : http://192.168.4.1
```




The web panel displays:



- GPS state,
- latitude and longitude,
- speed,
- altitude,
- satellite count,
- visible satellites,
- LoRa state,
- TX state,
- last LoRa packet,
- RAK response,
- satellite PRN/elevation/azimuth/SNR,
- Google Maps link when GPS fix is available.




### JSON API




The web dashboard reads:




```text
/api/status
```




Example fields:




```json
{
  "device": "T1",
  "firmware": "2.1.0",
  "gpsState": "FIX",
  "fix": true,
  "lat": "39.963205",
  "lon": "32.791445",
  "speed": 1,
  "alt": 1024,
  "sat": 8,
  "gsv": 10,
  "nmea": 12000,
  "lora": "READY",
  "tx": "OK #12",
  "packet": "T1,FIX,39963205,32791445,1,8,1024,10,12,NORMAL"
}
```




---




## GNSS / Satellite Data




The NEO-6M does not provide real satellite names such as official spacecraft names. It provides GPS PRN numbers.




The firmware displays them as:




```text
GPS-05
GPS-12
GPS-21
```




Satellite information parsed from GSV:




| Field | Meaning |
| --- | --- |
| PRN | Satellite identifier |
| Elevation | Degrees above horizon |
| Azimuth | Direction in degrees |
| SNR | Signal strength / carrier-to-noise value |




### GPS States




| State | Meaning |
| --- | --- |
| ` WAIT ` | No NMEA data received |
| ` DATA ` | NMEA data is coming, but no valid fix |
| ` FIX ` | Valid position is available |




If NMEA count increases but latitude/longitude are not available, GPS is working but has no fix yet.




---




## LoRa P2P Protocol




StratoTrack uses raw LoRa P2P through RAK RUI3 AT commands.




RAK setup commands:




```text
AT
AT+NWM=0
ATZ
AT
AT+P2P=868100000:12:125:0:8:14
AT+PRECV=0
```




Send command:




```text
AT+PSEND=
```




The RAK module expects HEX payload for P2P send. Therefore, the firmware converts:




```text
T1,FIX,39963205,32791445,1,8,1024,10,12,NORMAL
```




to HEX before sending.




---




## Packet Format




Current packet format:




```text
ID,STATE,LATx1e6,LONx1e6,SPEED,SAT,ALT,GSV,COUNTER,MODE
```




Example:




```text
T1,FIX,39963205,32791445,1,8,1024,10,12,NORMAL
```




Field details:




| Field | Example | Description |
| --- | --- | --- |
| ID | ` T1 ` | Device ID |
| STATE | ` FIX ` | GPS state |
| LATx1e6 | ` 39963205 ` | Latitude × 1,000,000 |
| LONx1e6 | ` 32791445 ` | Longitude × 1,000,000 |
| SPEED | ` 1 ` | Speed in km/h |
| SAT | ` 8 ` | Used satellites |
| ALT | ` 1024 ` | Altitude in meters |
| GSV | ` 10 ` | Visible satellite entries |
| COUNTER | ` 12 ` | Packet counter |
| MODE | ` NORMAL ` | Device mode |




### Example Decoding




```text
39963205 / 1000000 = 39.963205
32791445 / 1000000 = 32.791445
```




Google Maps:




```text
https://maps.google.com/?q=39.963205,32.791445
```




---




## Second LoRa Receiver




A second LoRa receiver can be built using another ESP32-compatible board and RAK3172/RAK3272S module.




The receiver listens in LoRa P2P mode and decodes packets from the tracker.




### Receiver Wiring




| RAK3172 / RAK3272S | Receiver MCU |
| --- | --- |
| UART2\_TX | GPIO4 |
| UART2\_RX | GPIO5 |
| 3V3 | 3V3 |
| GND | GND |




### Receiver LoRa Config




Must match the tracker:




```text
868100000:12:125:0:8:14
```




### Receiver Behavior




The receiver:



- starts RAK in P2P mode,
- enables continuous receive mode,
- waits for ` +EVT:RXP2P `,
- extracts HEX payload,
- decodes payload to text,
- parses tracker packet,
- prints coordinates,
- prints Google Maps URL,
- prints RSSI and SNR if available.




Example output:




```text
LORA PACKET RECEIVED
RAW     : T1,FIX,39963205,32791445,1,8,1024,10,12,NORMAL
DEVICE  : T1
STATE   : FIX
LAT     : 39.963205
LON     : 32.791445
MAP     : https://maps.google.com/?q=39.963205,32.791445
SPEED   : 1 km/h
SAT     : 8
ALT     : 1024 m
GSV     : 10
COUNT   : 12
MODE    : NORMAL
RSSI    : -84
SNR     : 10
```




---




## Configuration




Main configuration file:




```text
include/config.h
```




Important settings:




```cpp
#define DEVICE_ID "T1"

#define LORA_FREQ_HZ 868100000UL
#define LORA_SF 12
#define LORA_BW 125
#define LORA_CR 0
#define LORA_PREAMBLE 8
#define LORA_TX_POWER 14

#define BEACON_INTERVAL_NORMAL_MS 10000UL

#define WEB_AP_SSID "GPS-TRACKER-T1"
#define WEB_AP_PASS "12345678"
```




### Beacon Interval




Default:




```cpp
#define BEACON_INTERVAL_NORMAL_MS 10000UL
```




This sends one packet every 10 seconds.




---




## Field Testing Guide




### Step 1: Test TFT




Confirm the TFT shows the dashboard.




### Step 2: Test GPS NMEA




Serial should show:




```text
NMEA increasing
```




If NMEA increases but GPS state is ` DATA `, GPS works but has no fix.




### Step 3: Get GPS Fix




Move outdoors or near a clear window.




Expected:




```text
GPS FIX
SAT 5+
LAT valid
LON valid
```




### Step 4: Test LoRa TX




Expected:




```text
RAK: +EVT:TXP2P DONE
TX: T1,FIX,...
```




### Step 5: Test Web Panel




Connect to:




```text
GPS-TRACKER-T1
```




Open:




```text
http://192.168.4.1
```




### Step 6: Test Second Receiver




Power the second receiver and check for ` RXP2P ` events.




---




## Troubleshooting




### GPS stays WAIT




Cause:



- GPS TX not connected,
- wrong GPS RX pin,
- no common ground,
- GPS not powered,
- wrong baud rate.




Check:




```text
NMEA count = 0
```




This means ESP32 receives no GPS data.




### GPS DATA but no FIX




Cause:



- GPS sees NMEA but no satellite lock.




Fix:



- go outside,
- place antenna facing sky,
- wait 2–5 minutes,
- check satellite count.




### LoRa NO AT




Cause:



- wrong UART pins,
- wrong baud,
- no RAK power,
- no common ground,
- TX/RX swapped.




### LoRa P2P ERR




Cause:



- RAK accepted AT but rejected P2P config,
- RAK may need reboot after ` AT+NWM=0 `,
- previous mode not applied yet.




Fix:



- use ` AT+NWM=0 `,
- then ` ATZ `,
- wait,
- send ` AT `,
- send ` AT+P2P=... `.




### LoRa TX works but receiver gets nothing




Check:



- same frequency,
- same SF,
- same bandwidth,
- same coding rate,
- same preamble,
- antennas connected,
- both devices use P2P mode,
- receiver uses ` AT+PRECV=65534 `.




### Web panel does not open




Check:



- phone connected to ` GPS-TRACKER-T1 `,
- password is ` 12345678 `,
- open ` http://192.168.4.1 `,
- disable mobile data if the phone switches away,
- confirm Serial Monitor prints web panel start logs.




### COM5 disconnects




Try:




```ini
monitor_rts = 0
monitor_dtr = 0
```




Use a better USB cable and avoid weak USB hubs.




---




## Safety and Legal Notes



- Always connect a proper antenna before LoRa transmission.
- Do not exceed local RF regulations.
- For EU/Türkiye 868 MHz usage, respect regional duty-cycle and power limits.
- This project is for educational, prototyping and field testing use.
- Do not use for unlawful tracking or surveillance.




---




## Roadmap




Planned improvements:



- ACK packets from second receiver,
- two-way LoRa commands,
- SOS mode,
- adaptive TX interval,
- stopped/moving/fast mode detection,
- local track history,
- CSV export from web panel,
- satellite skyplot on TFT,
- battery voltage monitoring,
- enclosure-ready hardware layout,
- multi-device receiver dashboard.




---




## License




AGPL-3.0 license




---

## StratoTrack LoRa Pro — kaynak ve uygulama notları

### Proje ve belgeyi birlikte değerlendirin

Bu kayıt için kaynak açıklama korunmuştur. Kurulum, bağımlılık ve lisans kararlarında bu kayda bağlı proje ve dokümanı birlikte inceleyin; doğrulanmamış sürüm, ölçüm veya özellik bu ekle ilan edilmemiştir.

### Metinde geçen depo bağlantıları

- [Depo bağlantısı](https://github.com/pioarduino/platform-espressif32.git)

- [Depo bağlantısı](https://github.com/hamzadenizyilmaz/StratoTrack-LoRa-Pro)

### İlgili okuma yolu

- [StratoTrack-LoRa-Pro Proje Dokümanı](/dokumanlar/github-stratotrack-lora-pro)

- [LoRa Paket Kaybı Analizi](/blog/lora-paket-kaybi-analizi)
