★ ACADEMIC USE · MIL-EDU PROJECT ★

C-27J SPARTAN · TACTICAL WX OPS

Sistem suport-decizie meteo pentru misiuni transport aerian tactic

Author: Ioana Diaconu  ·  Codename: SPARTAN-MET  ·  Status: OPERATIONAL

🎯 Mission

Platformă de generare și distribuție scenarii meteo dinamice pentru simulator C-27J. Construită pentru susținere proiect academic ATM (Academia Tehnică Militară) — modul autonom integrat cu APK Android tactical display + decision engine MATLAB + ESP32 cabin gateway.

📡 Modules

🛠

Mission Planner

Editor scenarii meteo cu evoluție temporală automată (mișcare, intensificare, decay) și override-uri forțate. Player TV-style pentru briefing.

Auth: HTTP Basic · CRUD via JSON
→ Use case: instructor & briefing officer
📺

Briefing Replay

Player read-only pentru prezentări scenarii — timeline ×30/×60, animație continuă, optimizat proiector.

2 scenarii operaționale
→ Use case: briefing class · debrief AAR
📖

Tech Documentation

Manualul tehnic complet — arhitectură, model date, API, workflow integrat cu APK + MATLAB. Pentru referință și anexă memoriu.

PDF-ready · academic format
→ Use case: redactare memoriu licență

🛰 Tactical Endpoint TOKEN AUTH

Endpoint public read-only pentru clienții C-27J Radar și MATLAB decision engine. Autentificare prin token fix (32+ caractere hex), rate-limit 120/min, audit log.

GET /api/endpoint.php?token=<APK_TOKEN>&action=list&type=wx
GET /api/endpoint.php?token=<APK_TOKEN>&action=get&type=wx&id=<ID>

Token-urile sunt distribuite operatorilor autorizați. Niciodată nu se trimit prin email/Slack — doar transferate manual.

⚙ System Architecture

Componente: 📺 BRIEFING 🛠 PLANNER 📖 DOCS 📱 C-27J RADAR 🖥 MATLAB 📡 ESP32 GW 🎛 GPS ADJUST

+---------------+ +----------------+ +---------------+ | BRIEFING | | PLANNER (web) | | DOCS (web) | | ROOM | | ioana / passwd | | /docs/ | +-------+-------+ +--------+-------+ +-------+-------+ | | HTTPS Basic | | v | | +---------------------+ | +---HTTPS----->| IOANAD.MENSOFT.RO |<--------+ | PHP 7.1 + JSON | | /scenarios/wx/* | +----------+----------+ | TOKEN AUTH (read-only) +----------+----------+ v v +-------------------+ +-------------------+ | C-27J RADAR | | MATLAB engine | | (Android tablet) | | decision tree | +---------+---------+ +---------+---------+ | POST /advice | webread /gps | WX OWM + METAR | v ^ +----------------------------+ | ESP32 CABIN GATEWAY | | /gps /advice /display | +-------------+--------------+ | Serial TX (9600) v +----------------------------+ | ARDUINO GPS ADJUST | | ADJ / FIX / NEO modes | | v1: LCD shield + 2x KY040 | | v2: OLED + 3x EC11 + 3btn | +----------------------------+

🎛 GPS Adjust Hardware ARDUINO UNO R3

Dispozitiv fizic de ajustare coordonate GPS pentru simulatorul C-27J. Trimite NMEA (GGA+RMC) la ESP32 via Serial TX. Trei moduri de operare, schimbate prin long press (>800ms) tasta UP de pe shield.

Componentă Pin Arduino Rol
DFRobot LCD Keypad Shield 16×2D8/D9/D4/D5/D6/D7, A0Display + 5 butoane (rezistiv pe A0)
KY-040 Encoder LATCLK=D2 (INT0), DT=D11Ajustare latitudine
KY-040 Encoder LONCLK=D3 (INT1), DT=D12Ajustare longitudine
Potențiometru ALTA1Altitudine 0–5000 m (ADJ + FIX; în NEO vine din GGA GPS)
Potențiometru LATA3Latitudine absolută (mod FIX)
Potențiometru LONA2Longitudine absolută (mod FIX)
NEO-6M GPS (opțional)TX→A4 (SoftSerial RX)Relay GPS real (mod NEO) — 3.3V direct
ESP32 Cabin GatewayTX→ESP32 RX (9600 baud)Output NMEA GGA+RMC la 1 Hz
MOD ADJ (implicit la pornire — offset din encodere față de referință ESP32) ┌────────────────┐ ┌────────────────┐ │45.9432 24.9668│ │45.9457 24.9521│ <-- lat+dLat lon+dLon │A:1500 e-4 ADJ+│ │A:1500 e-3 ADJ │ <-- alt pas MOD enc-symbol └────────────────┘ └────────────────┘ MOD FIX (3 potențiometre → coordonate absolute; encoder setare limite la extreme pot) ┌────────────────┐ ┌────────────────┐ │46.1200 25.3400│ │LAT< 43.5000 │ <-- la pot LAT la minim: edit latMin │A:2300 .01 FIX │ │A:2300 .01 FIX │ └────────────────┘ └────────────────┘ MOD NEO (relay NMEA de la NEO-6M GPS real; LED2 roșu=power, LED1 albastru=fix 3D) ┌────────────────┐ │46.0753 24.8812│ <-- coordonate reale GPS │A:1200 S:5 NEO│ <-- alt(GPS) sateliți MOD └────────────────┘

Butoane LEFT/RIGHT → schimbă pasul encoder: e-5 / e-4 / e-3 / e-2 / e-1 (ADJ) sau 0.01 / 0.1 / 0.5 / 1.0 / 5.0 grad (FIX).
SELECT → resetează offseturile dLat/dLon la zero (ADJ) sau nu face nimic (FIX/NEO).
Referință ADJ → la primire SETSTART,lat,lon,alt\n pe Serial RX (de la ESP32/MATLAB), referința se actualizează automat.
NEO-6M conexiune → TX (galben) direct la A4, fără level shifter (3.3V → logică Arduino 5V OK pe RX). GND comun obligatoriu. Nu e nevoie de switch fizic — SoftwareSerial e activat doar în mod NEO.

🎛 GPS Adjust Hardware v2 OLED + CARCASĂ 3D

Revizia hardware v2 — port LCD shield → modul OLED 0.96" SSD1306 (I2C) + carcasă OpenSCAD parametrică 160×115×50 mm cu controale panel-mount precision-grade. Același firmware compilează ambele variante prin #ifdef HW_OLED_MODULE / HW_LCD_SHIELD — toată logica (encodere, NMEA, moduri ADJ/FIX/NEO, UTC clock, parser NEO-6M, ESP32 RX) este identică între v1 și v2. Diferența: display + butoane + carcasă portabilă cu baterie.

Componentă Pin Arduino Rol
Modul OLED 0.96" SSD1306 128×64A4 (SDA) / A5 (SCL)Display I2C @ 400 kHz (U8g2 page-buffer 256 B)
PSH — push encoder din modul OLEDD4short: step+  ·  long (≥800 ms): cycle mod ADJ→FIX→NEO
CON — buton confirm OLEDD5short: contrast OLED (32/128/255)  ·  long: reset offsets (ADJ) / reset corners (FIX) / forceADJ (NEO)
BAK — buton return OLED (rezervat — pin D6 cu pullup, nu este conectat fizic în v actuală)D6short: step−  ·  long: saveEEPROM corners (FIX) / forceADJ (ADJ + NEO)
Encoder integrat OLED (TRA/TRB) — ABANDONAT v3.20D9 (TRA) / D10 (TRB)Hardware prezent dar nefolosit. UNO are doar 2 hardware INT-uri (INT0=D2, INT1=D3 — ocupate cu LAT/LON). PJRC Encoder pe D9/D10 (PCINT only) ratează edges; PinChangeInterrupt conflictă cu PJRC pe PCINT0_vect (același vector ca D11/D12 LAT/LON B-pins). Polling-ul direct e prea fragil (loop blocked de I2C/SoftwareSerial). Renunțat → altitudine ADJ exclusiv din pot A1.
Encoder EC11 LAT panel-mount (axă M7)CLK=D2 (INT0), DT=D11PJRC Encoder ISR. Offset latitudine (ADJ) / colț zonă (FIX)
Encoder EC11 LON panel-mount (axă M7)CLK=D3 (INT1), DT=D12PJRC Encoder ISR. Offset longitudine (ADJ) / colț zonă (FIX)
Potențiometru ALT (6.3 mm rotativ)A1Altitudine 0–5000 m (ADJ baseline; FIX absolut)
Bourns 3590S 10-turn LAT (precizie)A2Latitudine absolută rezoluție 10 ture (FIX)
Bourns 3590S 10-turn LON (precizie)A3Longitudine absolută rezoluție 10 ture (FIX)
NEO-6M GPSTX→D7 (SoftSerial RX)Relay GPS real (mod NEO); D8 SoftSer TX rezervat neconectat
TP4056 D1 Mini boost + 18650 protejat5V output → UNO 5V/GNDAlimentare portabilă (≈15–18 h fără NEO)
ESP32 Cabin GatewayTX→ESP32 RX (9600 baud)Output NMEA GGA+RMC @ 1 Hz

Notă encodere — fizic există 3 encodere EC11, dar doar 2 active: cele 2 panel-mount externe LAT/LON (axe 6,3 mm cu mufă M7, PJRC ISR pe INT0/INT1 hardware interrupts). Al 3-lea, integrat în modulul OLED pe D9/D10, a fost abandonat în v3.20 după teste extensive — D9/D10 nu au INT hw, și PCINT0 e deja folosit de PJRC pentru pinii secundari LAT/LON (D11/D12). Logica butoane PSH/CON/BAK distinge automat short press (<800 ms) de long press (≥800 ms) — modurile sunt ciclate prin PSH long.

📋 Mapări control per mod operațional

Control ADJ (offset) FIX (absolut) NEO (relay)
Enc LAT (D2/D11)±dLat (pas curent)colț latMin/Max când pot LAT la extreminactiv (GPS real)
Enc LON (D3/D12)±dLon (pas curent)colț lonMin/Max când pot LON la extreminactiv
Enc OLED (D9/D10) abandonatinactiv (renunțat v3.20)inactivinactiv
Pot ALT (A1)altitudine (eA = pot direct)altitudine absolutăinactiv (ALT din GGA)
Pot LAT/LON (A2/A3)inactivlatitudine/longitudine absolută (10-turn)inactiv
PSH shortstep+ (e-5→e-4→e-3→e-2→e-1)step+ (0.01→0.1→0.5→1.0→5.0°)step+ (irelevant)
PSH long→ FIX→ NEO→ ADJ
CON shortciclu contrast OLED 3 nivele (32 / 128 / 255)
CON longreset offsets (dLat=dLon=0)reset colțuri zonă FIXforce ADJ
BAK shortstep− (în direcția inversă față de PSH short)
BAK longforce ADJ (no-op)save colțuri în EEPROM (4 float-uri + magic byte 0xA5, restaurate auto la boot)force ADJ
ESP32 RX (D0)SETSTART,lat,lon,alt\n → baseline (baseLat/Lon/Alt)ignoratignorat

⚠ Lecție wiring (2026-05-19): la prima alimentare a modulului OLED display-ul nu a afișat nimic și scanner-ul I2C a returnat „Done" fără device — cauza s-a dovedit a fi VCC pus la GND în loc de 5 V (cei doi pini „GND-like" arătau identic vizual). Regulatorul AMS1117 a tolerat scurt swap-ul de polaritate, dar nu garantat. Regulă: la cablarea modulelor noi, verifică polaritatea fizică cu multimetru înainte de alimentare.

📐 CAPAC — layout panou frontal (194 × 114 mm, vedere de sus)

M3M3 M3M3 MODUL OLED 0.96" SSD1306 128 × 64 ENC D9/D10 (nefolosit) PSH D4 Enc LAT EC11 D2 (INT0) + D11 Bourns LAT A2 · 10-turn Pot ALT 6.3mm A1 · 0–5000 m Bourns LON A3 · 10-turn Enc LON EC11 D3 (INT1) + D12 18650 holder (interior) 75 × 21 mm 2500–3000 mAh protejat TP4056 BMS snap-in GPS antenna patch (slide-in) 28 × 8.3 mm · ghidaj 2.5 mm ◄ DC 5.5/2.1 · USB-C UNO USB-C BMS · jack 3.5mm ► Linie întreruptă = sub capac (interior baza) · Cercuri continue = controale pe capac

🔌 SCHEMA CONEXIUNI — Arduino UNO R3 (hub central)

ARDUINO UNO R3 USB-C clone · ATmega328P · 16 MHz A4 SDA ──┐ A5 SCL ──┤ I2C D4 ──── PSH D5 ──── CON D6 ──── BAK D7 ── NEO RX D2 INT0 ◄ LAT CLK D11 ── LAT DT D3 INT1 ◄ LON CLK D12 ── LON DT A1 ── Pot ALT A2 ── Bourns LAT A3 ── Bourns LON TX/RX ◄═► ESP32 MODUL OLED 0.96" SSD1306 I2C + EC11 + 3 butoane SDA/SCL/5V/GND · D4/D5/D6 + enc D9/D10 (abandonat v3.20) ─ 6 fire active spre UNO ─ EC11 LAT (panel) CLK=D2 (INT0 hardware) DT=D11 · GND EC11 LON (panel) CLK=D3 (INT1 hardware) DT=D12 · GND Potențiometre analog Pot ALT 6.3mm → A1 Bourns 3590S 10t → A2 Bourns 3590S 10t → A3 NEO-6M GPS 3.3V TX → D7 SoftSer RX 9600 baud · GGA/RMC/GSV + antenă patch 28×8 mm TP4056 + 18650 BMS 5V boost → UNO 5V/GND Charge: USB-C BMS · 15–18h ESP32 Cabin Gateway UNO TX (D1) → ESP RX UNO RX (D0) ◄ ESP TX SETSTART input · GGA/RMC out Săgeți unidirecționale = direcție semnal · Linii groase = magistrală principală

Carcasă 3D-print — OpenSCAD parametric (gpsadjust_v2_case_usbc.scad pentru clone USB-C / gpsadjust_v2_case.scad pentru USB-B clasic), 160×115 mm × ≈50 mm total (35 base + 14 cover). PLA/PETG ≥40 % infill + 3 perimetri pentru bossuri M3 self-tap. Slot USB-C + DC jack 5,5/2,1 mm în peretele stâng, antenă GPS patch 25×25 mm în buzunar slide-in deasupra bateriei (cu fereastră în peretele top pentru sky-view direct când device-ul e orientat vertical).
Autonomie — 18650 protejat 2500–3000 mAh + TP4056 D1 Mini boost 5V cu cut-off 3.3V → cca 15–18 h fără NEO (mod ADJ/FIX) sau 10–12 h cu NEO-6M acquisition activ.
Firmwaregpsadjust_v2.ino v3.23 (30.9 KB flash 95% / 1351 B SRAM 65%; PROGMEM/PSTR pe toate string-urile, snprintf_P pe display). Librării: Encoder (PJRC) pentru cele 2 encodere active LAT/LON (ISR pe INT0/INT1), U8g2 page-buffer SSD1306, SoftwareSerial pentru NEO-6M, EEPROM pentru salvare colțuri FIX. Bus I2C @ 400 kHz (standard SSD1306). Cold-start delay 1000 ms înainte de oled.begin() pentru sursă externă cu rampă lentă. Diagnostic „Aștept NEO fix" live cu contor sateliți (in-use / in-view din GGA + GSV) + ultima linie NMEA primită (truncată 21 char) pentru wiring/no-fix triage instant. Display NEO redesigned similar ADJ: LAT/LON/ALT pe 3 rânduri + linie orizontală + bară animată [*     ] (asterisc avansează 1 poziție per linie NMEA primită, ricochet la capete — se oprește când nu mai vine semnal) + SAT use/view.
SurseD:/apps/gpsadjust_v2/: sketch unified gpsadjust_v2.ino (compile pentru ambele variante via #ifdef HW_OLED_MODULE / HW_LCD_SHIELD) + 4 SVG templates A4 print 1:1 pentru verificare componente + STL-uri base/cover/preview exportate din OpenSCAD + carcasele cu/fără USB-C (v0.3 fork) + CLAUDE_NOTES.md documentație tehnică internă.

📡 Sentințe NMEA 0183 procesate

Toate sentințele sunt ASCII, format $TIPp1,p2,...,pN*CC<CR><LF> cu checksum XOR pe 1 octet. Prefix GP = GPS exclusiv (NEO-6M default), GN = multi-constelație, GL = GLONASS. Parser-ul acceptă oricare variantă.

Sentință Direcție Conținut & utilizare
$G?GGA
Global Pos. Fix Data
RX (NEO mode) + TX emis (ADJ/FIX)14 câmpuri: UTC time (HHMMSS.ss), lat (DDMM.MMMM)+N/S, lon (DDDMM.MMMM)+E/W, fix quality (0=invalid, 1=GPS, 2=DGPS, 4=RTK fix, 5=RTK float), sats în uz, HDOP, altitudine MSL (m), separație geoid (m), age DGPS, ID statie. Sursa principală pentru poziție 3D + numărul satelților folosiți la fix.
$G?RMC
Recommended Minimum
RX (NEO mode) + TX emis (ADJ/FIX)12 câmpuri: UTC time, status (A=activ, V=void), lat+N/S, lon+E/W, SOG (knots), COG (°true), date (DDMMYY), variație magnetică+E/W, mode indicator. Aici se citesc viteza (knots → km/h prin ×1.852) și direcția de deplasare.
$G?GSV
Satellites in View
RX only (NEO mode)Multi-message (până la 4): nr mesaj curent, total mesaje, număr total sateliți vizibili, apoi câte 4 sateliți/mesaj cu (PRN, elevație°, azimut°, SNR dB-Hz). Folosit pre-fix pentru afișaj "Aștept NEO fix... SAT use/view" — diferența între în-uz (GGA) și vizibili (GSV) indică starea de achiziție.

Notă: în mod ADJ și FIX, sketch-ul generează propriile $GPGGA/$GPRMC cu poziția curentă (encodere/poți) și le trimite pe TX hardware (D1) către ESP32 la 1 Hz. În mod NEO, sketch-ul doar relay-uiește (retransmite) sentințele venite de la modulul NEO-6M pe SoftwareSerial (D7 RX) către ESP32, fără modificări.

🪖 Operational Workflow

  1. Mission planning — Officer creează scenariul WX în Planner (5-10 min). Salvat ca JSON pe server.
  2. Pre-flight — APK pe tabletă în cabină, tab Replay → Remote, descarcă scenariul ales (cache local nelimitat).
  3. Mission start — MATLAB pornește scenariul de zbor, push fake GPS la ESP32 (pattern /setgpsstart).
  4. In-flight — APK în mod Apply/Run citește GPS de la ESP32 → calculează WX la poziția și timpul curent → push /advice JSON cu OWM + METAR.
  5. Decision loop — MATLAB face webread la ESP32 /gps, primește GPS + secțiunea realwx, evaluează decizii (NORMAL · LATERAL DEV · LEVEL CHG · DIVERT · GO-AROUND).
  6. Debrief — Briefing Replay pe proiector pentru AAR (After Action Review).