🎯 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.
Briefing Replay
Player read-only pentru prezentări scenarii — timeline ×30/×60, animație continuă, optimizat proiector.
Tech Documentation
Manualul tehnic complet — arhitectură, model date, API, workflow integrat cu APK + MATLAB. Pentru referință și anexă memoriu.
🛰 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>
⚙ System Architecture
Componente: 📺 BRIEFING 🛠 PLANNER 📖 DOCS 📱 C-27J RADAR 🖥 MATLAB 📡 ESP32 GW 🎛 GPS ADJUST
🎛 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×2 | D8/D9/D4/D5/D6/D7, A0 | Display + 5 butoane (rezistiv pe A0) |
| KY-040 Encoder LAT | CLK=D2 (INT0), DT=D11 | Ajustare latitudine |
| KY-040 Encoder LON | CLK=D3 (INT1), DT=D12 | Ajustare longitudine |
| Potențiometru ALT | A1 | Altitudine 0–5000 m (ADJ + FIX; în NEO vine din GGA GPS) |
| Potențiometru LAT | A3 | Latitudine absolută (mod FIX) |
| Potențiometru LON | A2 | Longitudine absolută (mod FIX) |
| NEO-6M GPS (opțional) | TX→A4 (SoftSerial RX) | Relay GPS real (mod NEO) — 3.3V direct |
| ESP32 Cabin Gateway | TX→ESP32 RX (9600 baud) | Output NMEA GGA+RMC la 1 Hz |
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×64 | A4 (SDA) / A5 (SCL) | Display I2C @ 400 kHz (U8g2 page-buffer 256 B) |
| PSH — push encoder din modul OLED | D4 | short: step+ · long (≥800 ms): cycle mod ADJ→FIX→NEO |
| CON — buton confirm OLED | D5 | short: 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ă) | D6 | short: step− · long: saveEEPROM corners (FIX) / forceADJ (ADJ + NEO) |
| Encoder integrat OLED (TRA/TRB) — ABANDONAT v3.20 | D9 (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=D11 | PJRC Encoder ISR. Offset latitudine (ADJ) / colț zonă (FIX) |
| Encoder EC11 LON panel-mount (axă M7) | CLK=D3 (INT1), DT=D12 | PJRC Encoder ISR. Offset longitudine (ADJ) / colț zonă (FIX) |
| Potențiometru ALT (6.3 mm rotativ) | A1 | Altitudine 0–5000 m (ADJ baseline; FIX absolut) |
| Bourns 3590S 10-turn LAT (precizie) | A2 | Latitudine absolută rezoluție 10 ture (FIX) |
| Bourns 3590S 10-turn LON (precizie) | A3 | Longitudine absolută rezoluție 10 ture (FIX) |
| NEO-6M GPS | TX→D7 (SoftSerial RX) | Relay GPS real (mod NEO); D8 SoftSer TX rezervat neconectat |
| TP4056 D1 Mini boost + 18650 protejat | 5V output → UNO 5V/GND | Alimentare portabilă (≈15–18 h fără NEO) |
| ESP32 Cabin Gateway | TX→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 extrem | inactiv (GPS real) |
| Enc LON (D3/D12) | ±dLon (pas curent) | colț lonMin/Max când pot LON la extrem | inactiv |
| Enc OLED (D9/D10) abandonat | inactiv (renunțat v3.20) | inactiv | inactiv |
| Pot ALT (A1) | altitudine (eA = pot direct) | altitudine absolută | inactiv (ALT din GGA) |
| Pot LAT/LON (A2/A3) | inactiv | latitudine/longitudine absolută (10-turn) | inactiv |
| PSH short | step+ (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 short | ciclu contrast OLED 3 nivele (32 / 128 / 255) | ||
| CON long | reset offsets (dLat=dLon=0) | reset colțuri zonă FIX | force ADJ |
| BAK short | step− (în direcția inversă față de PSH short) | ||
| BAK long | force 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) | ignorat | ignorat |
⚠ 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)
🔌 SCHEMA CONEXIUNI — Arduino UNO R3 (hub central)
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.
Firmware — gpsadjust_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.
Surse — D:/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?GGAGlobal 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?RMCRecommended 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?GSVSatellites 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
- Mission planning — Officer creează scenariul WX în Planner (5-10 min). Salvat ca JSON pe server.
- Pre-flight — APK pe tabletă în cabină, tab Replay → Remote, descarcă scenariul ales (cache local nelimitat).
- Mission start — MATLAB pornește scenariul de zbor, push fake GPS la ESP32 (pattern
/setgpsstart). - In-flight — APK în mod Apply/Run citește GPS de la ESP32 → calculează WX la poziția și timpul curent → push
/adviceJSON cu OWM + METAR. - Decision loop — MATLAB face
webreadla ESP32/gps, primește GPS + secțiunearealwx, evaluează decizii (NORMAL · LATERAL DEV · LEVEL CHG · DIVERT · GO-AROUND). - Debrief — Briefing Replay pe proiector pentru AAR (After Action Review).