Tornar
Manual d'Usuari de l'AquaPulse Marine Tracker
Sistema de Telemetria Marítima i Estimació d'Estat de Mar basat en FireBeetle 2 ESP32-E
1. Introducció
L'AquaPulse Marine Tracker és un dispositiu de telemetria marítima compacte basat en el microcontrolador DFRobot FireBeetle 2 ESP32-E. A diferència del seu germà GeoPulse (orientat a la integració completa amb pantalla Nextion, autopilot i AIS), l'AquaPulse està dissenyat com una unitat headless de telemetria contínua, amb un focus especial en l'estimació de l'estat de mar mitjançant un IMU de 9 graus de llibertat.
Característiques Principals:
- GPS multi-constel·lació BN-880 (GPS, GLONASS, Galileo, SBAS, QZSS, IMES) a 5 Hz
- IMU ICM-20948 de 9 eixos amb fusió Madgwick AHRS
- Estimació d'estat de mar basada en heave (alçada d'ona física) — escala WMO/Douglas 0-9
- Filtre Aranovskiy per a estimació del període d'ona
- Brúixola electrònica amb taula de desviació de 36 punts (cada 10°)
- Auto-calibració del rumb magnètic comparant amb COG GPS
- Sistema d'indicadors de 4 LEDs PWM (Blanc, Blau, Verd, Vermell) gestionats per LEDC
- Multi-WiFi amb autenticació automàtica a portals captius (Stena Line "Crew", Balearia Guest)
- Telemetria UDP i sortida NMEA 0183 per OpenCPN
- Geofencing persistit en LittleFS amb notificació d'entrada/sortida
- Actualització de firmware OTA i comandes remotes via HTTP polling (cada 30 s)
- Watchdog independent amb reinici automàtic en cas de bloqueig
Diferències respecte a GeoPulse: L'AquaPulse no incorpora pantalla Nextion, ni LEDs WS2812B de navegació, ni autopilot, ni AIS, ni sensors ambientals (BME280), ni mòdem extern, ni control de bateria/corrent (ADS1115/INA260), ni detector de llamps (AS3935). En canvi, ofereix capacitats avançades d'IMU/heave/brúixola que GeoPulse no té.
2. Components del Sistema
2.1 Unitat Principal de Processament
FireBeetle 2 ESP32-E (DFR1139)
| Especificació | Valor |
| Processador | Dual-core Xtensa LX6 @ 240 MHz |
| Memòria RAM | 520 KB SRAM |
| Memòria Flash | 4 MB (LittleFS per a credencials i geofences) |
| WiFi | 802.11 b/g/n (2.4 GHz) — power saving desactivat |
| Bluetooth | BLE 4.2 (no utilitzat en aquesta versió) |
| GPIO disponibles | 0,1,2,3,4,12,13,14,15,17,18,19,21,22,23,25,26 |
| Pins NC (No Connectats) | GPIO16 i GPIO27 — NO utilitzar! |
| Voltatge d'operació | 3.3 V |
| Sortida PWM | LEDC hardware @ 5 kHz, 8-bit |
2.2 Sensors
BN-880 — GPS Multi-constel·lació
- Constel·lacions: GPS, GLONASS, Galileo, SBAS, QZSS, IMES
- Velocitat sèrie: 115200 baud (NMEA)
- Freqüència d'actualització: 5 Hz (200 ms)
- Buffer Serial1 RX: 512 bytes (per a multi-constel·lació)
- Llibreria: TinyGPS++ v1.0.3
- Dades: Posició, velocitat, rumb (COG), satèl·lits, hora UTC, HDOP
ICM-20948 — IMU 9-DoF
- Acceleròmetre: 3 eixos
- Giroscopi: 3 eixos
- Magnetòmetre: 3 eixos (compass)
- Fusió: Madgwick AHRS (quaternió)
- Freqüència de mostreig: 25 Hz
- Interfície: I2C (default 0x69)
- Llibreria: SparkFun ICM-20948 v1.3.2
2.3 Indicadors
Sistema de 4 LEDs Discrets (anode comú / catode comú segons cablejat)
L'AquaPulse usa 4 LEDs independents controlats per hardware PWM (LEDC) a 5 kHz amb resolució 8-bit. Cada LED té un canal LEDC dedicat, eliminant qualsevol càrrega de CPU per als patrons. Cada LED té un significat semàntic concret:
| LED | GPIO | Canal LEDC | Significat |
| Blanc | 25 | 0 | Estat del MCU (boot, WiFi, sistema preparat) |
| Blau | 26 | 1 | Estat GPS (qualitat del fix per nombre de satèl·lits) |
| Verd | 18 | 2 | Estat IMU/Mar (sea state index, calibració heading) |
| Vermell | 14 | 3 | Errors (WiFi, GPS, memòria, OTA, watchdog) |
3. Especificacions Tècniques
3.1 Especificacions de Programari
| Paràmetre | Valor |
| Versió Firmware | AquaPulse-2.0.9_UDP_MUTEX |
| Identificador del Dispositiu | aquapulse |
| Plataforma Build | PlatformIO + Arduino-ESP32 |
| Sistema d'Arxius | LittleFS |
| Logging | UDP a backend (LOG_DEBUG / INFO / WARNING / ERROR) |
| Comunicació | UDP (telemetria/logs) + HTTPS (comandes/login) |
| MQTT | Eliminat — substituït per UDP + HTTP polling |
3.2 Intervals i Temporitzacions
| Funció | Interval (ms) | Descripció |
| Telemetria UDP | 1000 | Per defecte 1 s (configurable: 500 ms a 10 s) |
| Mostreig IMU | 40 | 25 Hz per al càlcul de heave/sea state |
| Sondeig de comandes (API) | 30000 | Polling HTTPS cada 30 s |
| Flush de logs | 5000 | Buida el buffer de logs cada 5 s |
| Monitor de sistema | 15000 | Comprovació heap i salut |
| Avaluació geofences | 5000 | Comprova entrada/sortida de zones |
| Persistència geofences | 15000 | Guarda canvis a LittleFS |
| Comprovació Internet (no auth) | 45000 | HTTP HEAD a Google 204 |
| Comprovació Internet (auth) | 120000 | 2 min quan ja hi ha sessió activa |
| Publicació wave data UDP | 60000 | Configurable 10-3600 s |
| Recol·lecció heading cal | 5000 | Mostra cada 5 s si SOG ≥ 7 nusos |
| Auto-save deviation table | 300000 | Cada 5 minuts si hi ha noves mostres |
| Heartbeat loop principal | 60000 | LOG_D amb heap, WiFi, sys ready |
| Watchdog timeout | 120000 | Reinici si SysMon no s'alimenta en 2 min |
3.3 Llindars de Plausibilitat GPS
| Paràmetre | Valor | Descripció |
| Mínim de satèl·lits | 4 | Per acceptar un fix |
| Velocitat màxima plausible | 30 m/s | Filtre de salts impossibles |
| Tolerància base de salt | 30 m | + velocitat·temps |
| HDOP màxim acceptat | 5.0 | Per qualitat de fix |
| Mínim sentències bones consecutives | 3 | Per acceptar nou fix |
| Velocitat de detecció estàtica | 0.3 nusos | Llindar "parat" |
| Tolerància posició estàtica | 10 m | Marge en mode estàtic |
| Temps per entrar mode estàtic | 30 s | Sota llindar de velocitat |
| Speed deadband | 0.4 nusos | Sota aquest valor → 0.0 (filtra deriva) |
| Anys vàlids GPS | 2020-2030 | Validació de data |
3.4 Llindars de Memòria
| Llindar | Valor | Acció |
| Heap baix | < 20 KB | LED Vermell RED_MEMORY_WARNING + log [WARNING] |
| Heap crític | < 12 KB | LED Vermell RED_MEMORY_CRITICAL + reinici |
| OTA mínim | > 20 KB | Avortat si heap insuficient |
| Buffer de logs | 2048 bytes | FIFO amb truncament del més antic |
4. Connexions i Pinout
4.1 Mapa de Pins ESP32 (FireBeetle 2 ESP32-E)
| Component | Pin ESP32 | Funció |
| LED Blanc (MCU State) | GPIO25 | LEDC Canal 0 — PWM |
| LED Blau (GPS Status) | GPIO26 | LEDC Canal 1 — PWM |
| LED Verd (IMU/Wave) | GPIO18 | LEDC Canal 2 — PWM |
| LED Vermell (Errors) | GPIO14 | LEDC Canal 3 — PWM |
| GPS RX (cap a ESP32) | GPIO17 | UART1 RX — rep dades NMEA del BN-880 |
| GPS TX (cap al GPS) | GPIO4 | UART1 TX — opcional, per configuració |
| I2C SDA | GPIO21 | Dades I2C (ICM-20948) |
| I2C SCL | GPIO22 | Rellotge I2C (ICM-20948) |
| USB Serial Debug | USB | 115200 baud (logs locals) |
⚠️ ATENCIÓ pinout FireBeetle 2 ESP32-E:
GPIO16 i GPIO27 estan NC (Not Connected) al PCB — no els assignis a cap perifèric.
- Pins disponibles vàlids:
0, 1, 2, 3, 4, 12, 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26
- L'IMU verd (GPIO18) és una reassignació del disseny original (que usava GPIO27 — NC en aquest board).
4.2 Bus I2C
El bus I2C s'inicialitza dins de seaStateCalc.begin() via imu.begin() i és gestionat per la llibreria de SparkFun. Només hi ha un dispositiu I2C en aquest disseny:
| Dispositiu | Adreça I2C | Funció |
| ICM-20948 | 0x69 (configurable a 0x68) | IMU 9-DoF i magnetòmetre |
5. Funcionament i Arrencada
5.1 Seqüència de setup()
- Serial USB a 115200 baud + delay 2 s per estabilització.
- LittleFS mount (amb
format on fail). Carrega /wifi.txt si existeix.
- Mutexes FreeRTOS:
ledStateMutex, gpsDataMutex, seaStateMutex, logBufferMutex, geofencesMutex, systemReadyMutex, udpMutex.
- Estats LED inicials: Blanc=BOOTING (breathe 2 s), Blau/Verd/Vermell=OFF.
- Serial1 (GPS): 115200 baud, RX=GPIO17, TX=GPIO4, buffer 512 B.
- WiFi.onEvent: registra
WiFiEventHandler per a esdeveniments STA.
- Watchdog seed:
lastSysMonFeedMs = millis().
- Creació de tasques FreeRTOS (vegeu §15).
- Cua geofences:
xQueueCreate(16, sizeof(GeofenceEvent)).
- Càrrega de geofences des de
/geofences.json.
- Taula de tasques gestionades (per a comandes
task_status).
5.2 Estats del Sistema
El sistema utilitza un flag systemReadyForServices protegit per mutex. Aquest flag controla si:
- Es publiquen telemetria UDP, logs UDP, NMEA, wave data, geofence events.
- Es respon a comandes que requereixin connectivitat plena.
El flag s'activa només quan: WiFi connectat I (xarxa no captiva amb Internet OK O autenticació captiva exitosa).
5.3 Anuncia de Firmware
A la primera connexió WiFi+API, el dispositiu publica via UDP:
LOG,aquapulse,[INFO] Firmware: AquaPulse-2.0.9_UDP_MUTEX
6. Sistema d'Indicadors LED (4 canals)
Els 4 LEDs s'actualitzen en una única tasca ledTask (prioritat 1, stack 2 KB). Les transicions d'estat les fan altres tasques mitjançant les funcions setWhiteLedState(), setBlueLedState(), setGreenLedState(), setRedLedState(), totes thread-safe via ledStateMutex.
Els estats GPS i IMU s'auto-actualitzen cada 500 ms cridant updateGpsLedState() i updateImuLedState().
6.1 LED Blanc — Estat del MCU
| Estat | Patró | Significat |
WHITE_OFF | apagat | LED desactivat manualment |
WHITE_BOOTING | breathe 2 s | Boot inicial (PWM fade in/out) |
WHITE_WIFI_CONNECTING | heartbeat 2 s | Doble batec ràpid + pausa 2 s |
WHITE_WIFI_CONNECTED | 500 ms ON / 500 ms OFF | WiFi connectat però servei encara no llest |
WHITE_CAPTIVE_AUTH | 300 ms ON / 700 ms OFF | Autenticació al portal captiu en curs |
WHITE_SYSTEM_READY | sòlid ON | Sistema completament operatiu |
WHITE_STANDBY | 100 ms ON / 4 s OFF | Mode estalvi |
WHITE_OTA_PROGRESS | 2× 120 ms / pausa 500 ms | Actualització de firmware en curs |
6.2 LED Blau — Estat GPS
| Estat | Patró | Condició |
BLUE_OFF | apagat | Cap dada GPS rebuda (mòdul mort) |
BLUE_NO_FIX | 200 ms ON / 2 s OFF | Rep dades però sense fix vàlid |
BLUE_FIX_POOR | 2× 150 ms / pausa 1.5 s | < 5 satèl·lits |
BLUE_FIX_MODERATE | 3× 150 ms / pausa 1.2 s | 5-7 satèl·lits |
BLUE_FIX_GOOD | 250 ms ON / 250 ms OFF | 8-10 satèl·lits |
BLUE_FIX_EXCELLENT | sòlid ON | ≥ 11 satèl·lits |
BLUE_STATIC_MODE | breathe 3 s | Vaixell aturat (fondejat/amarrat) |
BLUE_MONITOR_ACTIVE | 5× 50 ms / pausa 2 s | Mode monitor GPS actiu (60 s) |
6.3 LED Verd — IMU i Estat de Mar
| Estat | Patró | Sea State (Douglas/WMO) |
GREEN_OFF | apagat | IMU no inicialitzat |
GREEN_IMU_INIT | 500 ms ON / 2 s OFF | Iniciant ICM-20948 |
GREEN_SEA_0_1 | 1 s ON / 1 s OFF | Calm / Rippled (0–0.1 m) |
GREEN_SEA_2_3 | 500 ms ON / 500 ms OFF | Smooth / Slight (0.1–1.25 m) |
GREEN_SEA_4_5 | 250 ms ON / 250 ms OFF | Moderate / Rough (1.25–4 m) |
GREEN_SEA_6_7 | 120 ms ON / 120 ms OFF | Very Rough / High (4–9 m) |
GREEN_SEA_8_PLUS | 80 ms strobe | Very High / Phenomenal (≥ 9 m) |
GREEN_HEADING_CAL | 2× 100 ms / pausa 800 ms | Calibració de rumb activa |
6.4 LED Vermell — Errors (alta prioritat)
| Estat | Patró | Causa |
RED_OFF | apagat | Sense errors |
RED_WIFI_FAILED | 1× 200 ms / pausa 2 s | No s'ha pogut unir a cap xarxa |
RED_GPS_UNHEALTHY | 2× 100 ms / pausa 1 s | 60 s sense fix vàlid |
RED_MEMORY_WARNING | 3× 100 ms / pausa 1 s | Heap < 20 KB |
RED_MEMORY_CRITICAL | 5× 80 ms / pausa 1 s | Heap < 12 KB (reinici imminent) |
RED_OTA_FAILED | sòlid ON (3 s) | Actualització fallida |
RED_WATCHDOG | SOS Morse | Watchdog disparat — reinici en 2 s |
RED_CAPTIVE_FAILED | strobe 50/50 ms | Totes les credencials captives han fallat |
6.5 Control de Brillantor i Master Enable
| Variable | Tipus | Descripció |
ledMaxBrightness | uint8_t (0-255) | Per defecte 127 (50%). Multiplicador global. |
ledsEnabled | bool | Per defecte true. Master switch global. |
Comandes relacionades: led_brightness <0-255>, led_on, led_off, led_status.
7. Connectivitat WiFi i Captives
7.1 Xarxes Suportades (en ordre d'intent)
- Credencials desades a LittleFS
/wifi.txt (línia 1: SSID, línia 2: password).
- Xarxa per defecte hardcodejada al firmware (privada).
- Crew (Stena Line) — captiu amb 3 credencials rotatives.
- Balearia guest — captiu basat en voucher (getwifi.no).
Configuració general WiFi:
- Mode:
WIFI_STA
- Power saving: desactivat (
WIFI_PS_NONE) — millor estabilitat en xarxes a bord
- Timeout per intent: 15 s (30 reintents × 500 ms)
- Re-scan: cada 60 s en cas de fallada
- Reset persistent + log de xarxes visibles cada cicle
7.2 Portal Captiu "Crew" (Stena Line)
| Paràmetre | Valor |
| SSID | Crew |
| Password | KerryLighthouse |
| URL portal | https://internet.stenaline.com/portal_api.php |
| Mètode | POST application/x-www-form-urlencoded |
| Credencials rotatives | 3 jocs (rotació automàtica per quota exhausted) |
| Timeout HTTP | 15 s (xarxa lenta) |
7.3 Portal Captiu "Balearia guest" (getwifi.no)
| Paràmetre | Valor |
| SSID | Balearia guest (minúscula 'g' — case-sensitive) |
| Password | (xarxa oberta) |
| Voucher | 38042784 (Surf Premium: 3 GB / 168 h) |
| API status | https://getwifi.no/api.php/GetClientStatus |
| API voucher | https://getwifi.no/api.php/UseVoucher?Code=... |
| URL auth | https://ac.getwifi.no:8003/index.php?zone=pax |
| Telemetria de quota | Cada 10 minuts (data% i time%) |
Flux d'autenticació Balearia: (A) Status pre-check → si MAC ja és activa, no es crema cap voucher; (B) UseVoucher → obté formulari; (C) Form POST a l'AC; (D) Status verify per confirmar.
7.4 Comprovació d'Internet
Es fa una petició HTTP HEAD a http://clients3.google.com/generate_204 amb timeout de 5 s. Es considera Internet OK si la resposta és 204 o 200.
8. Sistema GPS i Filtratge
8.1 Estructura de Dades GPS
struct GPSData {
double latitude; // Graus decimals (6 decimals)
double longitude; // Graus decimals (6 decimals)
double speed; // En nusos (per defecte) o km/h
int course; // 0-359° (COG)
int satellites; // 0-64 (clamped)
int day, month, year; // Data UTC
int hour, minute; // Hora UTC
bool isValid; // True si fix passa filtres
unsigned long lastUpdateMs;
};
8.2 Filtres Aplicats a Cada Sentència
- Coordenades sospitoses: rebutja punts coneguts com a falsos (e.g. 0.366667, 0.450000) i punts ambigus prop de l'origen.
- Rang vàlid: lat ∈ [-90, 90], lon ∈ [-180, 180], i no ambdós zero.
- Mínim de satèl·lits: ≥ 4.
- HDOP acceptable: < 5.0 (si vàlid).
- Validació data/hora: any 2020-2030.
- Mode estàtic: si està parat > 30 s, només accepta canvis < 10 m.
- Salt màxim: distància < 30 m + 30 m/s × dt entre fixes.
- Mínim sentències consecutives bones: 3 abans d'acceptar canvi.
- Speed deadband: velocitats < 0.4 nusos s'arrodoneixen a 0 (filtra deriva GPS).
8.3 Mode Estàtic
El sistema detecta automàticament si el vaixell està aturat (velocitat < 0.3 nusos durant > 30 s). En aquest mode:
- El LED Blau passa a
BLUE_STATIC_MODE (breathing).
- Es congela la posició base i només s'accepten canvis < 10 m.
- Es surt del mode quan la velocitat torna a superar el llindar.
8.4 Mode Monitor GPS
Comanda gps_monitor (o alias GPS_STATUS_MQTT): activa durant 60 s un mode on:
- El LED Blau parpelleja en patró
BLUE_MONITOR_ACTIVE.
- S'envia un log
[INFO] GPS Fix: lat,lon tan bon punt s'obté un fix vàlid.
9. IMU, Heave i Estat de Mar
9.1 Pipeline de Càlcul
L'AquaPulse utilitza un enfocament físic per estimar l'estat de mar (BBN wave period approach), basat en:
- Adquisició de l'ICM-20948 a 25 Hz (acc + gyro + mag).
- Madgwick AHRS: fusió quaterniònica per a orientació absoluta lliure de drift.
- Compensació de gravetat: extracció de l'acceleració vertical pura (eix mundial Z).
- Filtre passa-baixos sobre el senyal vertical i càlcul de RMS.
- Filtre Aranovskiy: estimació no-paramètrica del període dominant d'ona.
- Mapatge físic: conversió RMS → alçada d'ona → estat de mar segons llindars WMO.
9.2 Estructura SeaStateData
struct SeaStateData {
int seaStateIndex; // 0-9 codi WMO
float waveHeightM; // Alçada estimada en metres
float wavePeriodSec; // Període dominant (Aranovskiy)
float waveFrequencyHz; // Freqüència dominant
float rmsAccelG; // RMS de l'acceleració filtrada (g)
float filteredAccelG; // Acceleració filtrada actual (g)
float rawAccelG; // Magnitud crua (g)
float pitchDegrees; // Capcineig
float rollDegrees; // Balanceig
float headingDegrees; // Rumb magnètic
float verticalAccelMps2; // Acc. vertical en m/s²
float signalVariance; // Variància del senyal
bool hasWaveMotion; // True si hi ha moviment d'ona detectat
bool isInitialized; // IMU inicialitzat correctament
unsigned long sampleCount; // Comptador de mostres
};
9.3 Escala WMO / Douglas Sea Scale
| Codi | Descripció | Alçada d'ona (m) |
| 0 | Calm (glassy) | 0 |
| 1 | Calm (rippled) | 0–0.1 |
| 2 | Smooth | 0.1–0.5 |
| 3 | Slight | 0.5–1.25 |
| 4 | Moderate | 1.25–2.5 |
| 5 | Rough | 2.5–4 |
| 6 | Very rough | 4–6 |
| 7 | High | 6–9 |
| 8 | Very high | 9–14 |
| 9 | Phenomenal | > 14 |
Sortida Serial: Cada 30 s s'imprimeix una línia compacta amb l'estat de mar, i cada 2 minuts una sortida de debug completa (heave, pitch/roll, RMS, període, variància).
10. Brúixola i Calibració de Desviació
L'AquaPulse implementa dues estratègies de correcció de la brúixola magnètica:
10.1 Offset Simple (mode bàsic)
Un sol valor d'offset (-180° a +180°) que es sumarà al rumb magnètic cru. Suficient si la desviació és aproximadament constant.
Recol·lecció automàtica activada per heading_cal_start:
- Mostres preses cada 5 s quan SOG ≥ 7 nusos (per garantir fiabilitat del COG GPS).
- Compara rumb magnètic vs COG GPS.
- Es necessiten ≥ 10 mostres per aplicar (
heading_cal_apply).
- Es pot establir manualment amb
heading_offset <graus>.
10.2 Taula de Desviació de 36 Punts (mode avançat)
Una deviation card tradicional amb 36 buckets (cada 10°), com les que es porten al pont de comandament:
- Auto-recol·lecció en background mentre el vaixell navega (no requereix activació explícita).
- Cada bucket emmagatzema un offset específic per a aquell rang de rumbs.
- Persistència en NVS: auto-save cada 5 minuts si hi ha noves mostres.
- Es prioritza sobre l'offset simple si hi ha > 0 buckets calibrats.
- Velocitat mínima per mostra:
CompassDeviation::MIN_SPEED_KNOTS.
10.3 Càlcul del Rumb Final
A publishTelemetryOnce(), el rumb a enviar es decideix així:
- Si la taula de desviació està calibrada → s'usa el rumb corregit per bucket.
- Si només l'offset simple està calibrat → s'usa el rumb magnètic + offset.
- Altrament → s'usa el COG GPS directe.
11. Geofencing
11.1 Estructura
struct Geofence {
String category; // Ex: "port", "marina", "warning"
String name; // Identificador únic (case-insensitive)
double lat, lon; // Centre en graus decimals
float radius; // Radi en metres
bool notifyEnter; // Generar event en entrar
bool notifyExit; // Generar event en sortir
String alias; // Nom amigable opcional
bool isInside; // Estat actual (no es persisteix)
};
11.2 Persistència
Les geofences es guarden a /geofences.json al LittleFS. Format:
[
{
"category": "marina",
"name": "PortVell",
"lat": 41.376388,
"lon": 2.181111,
"radius": 200.0,
"notifyEnter": true,
"notifyExit": true,
"alias": "Port Vell de Barcelona"
}
]
11.3 Tasques de Geofencing
| Tasca | Interval | Funció |
geofenceEvalTask | 5 s | Avalua entrada/sortida amb fórmula haversine |
geofenceEventPublishTask | 250 ms (cua) | Envia events via UDP |
geofencePersistenceTask | 15 s | Guarda canvis si geofencesDirty |
11.4 Comandes
| Comanda | Descripció |
geofence_list | Llista totes les geofences |
geofence_add <cat> <name> <lat> <lon> <radius> <notifyEnter> <notifyExit> [alias] | Afegeix una nova geofence (mínim 7 args) |
geofence_remove <name> | Elimina per nom (case-insensitive) |
12. Telemetria UDP i Protocols
12.1 Configuració del Servidor
| Paràmetre | Valor |
| IP del servidor | 188.166.104.124 |
| Port UDP | 5052 |
| Sincronització | udpMutex (semàfor FreeRTOS) |
| Pre-condició | isSystemReadyForServices() == true |
12.2 Format de Telemetria GPS
Paquet UDP amb 16 camps separats per coma:
AquaPulse,<lat>,<lon>,<speed>,<unit>,<course>,<sats>,0,0.0,0,0.0,<day>,<month>,<year>,<hour>,<minute>,<seaState>
| Camp | Format | Descripció |
| 0 | AquaPulse | Identificador fix |
| 1, 2 | float (6 dec.) | Latitud i longitud |
| 3 | float (2 dec.) | Velocitat (arrodonida a centèsims) |
| 4 | kts / kmh | Unitat de velocitat |
| 5 | int | Rumb (0-359°), corregit per IMU si cal·librat |
| 6 | int | Nombre de satèl·lits |
| 7-10 | 0,0.0,0,0.0 | Reservats (compatibilitat) |
| 11-13 | int | Dia, mes, any UTC |
| 14-15 | int | Hora i minut UTC |
| 16 | int (0-9) | Sea State Index (WMO) |
12.3 Format de Logs
LOG,aquapulse,[LEVEL] message
On [LEVEL] ∈ [DEBUG], [INFO], [WARNING], [ERROR]. Filtre actiu via globalLogLevel (per defecte INFO).
12.4 Format de Wave Data
WAVE,aquapulse,<seaState>,<heightM>,<periodSec>,<freqHz>,<rmsG>,<filteredG>,<rawG>,<variance>,<hasMotion>,<sampleCount>
12.5 Format de Geofence Events
GEO,aquapulse,<event>,<fence>,<category>,<lat>,<lon>[,<alias>]
event = enter o exit.
13. NMEA 0183 per OpenCPN
L'AquaPulse genera sentències NMEA estàndard a partir de les dades GPS i les envia via UDP per integració amb plotters com OpenCPN. Es fan servir prefixos GN (multi-constel·lació).
13.1 Format del Paquet UDP
NMEA,aquapulse,$GNRMC,...,*XX|$GNGGA,...,*XX
Les dues sentències es separen per un caràcter |. El backend pot reconstruir-les amb \r\n i reenviar-les a OpenCPN.
13.2 $GNRMC (Recommended Minimum)
$GNRMC,hhmmss.00,A,llll.llll,N,yyyyy.yyyy,W,sss.s,ccc.c,ddmmyy,,,D*hh
- Status:
A (Active)
- Mode indicator:
D (Differential / SBAS)
- Velocitat sempre en nusos (conversió automàtica si està en km/h)
- Coordenades en format DDMM.MMMM (lat) / DDDMM.MMMM (lon)
13.3 $GNGGA (Fix Data)
$GNGGA,hhmmss.00,llll.llll,N,yyyyy.yyyy,W,2,ss,1.0,0.0,M,0.0,M,,*hh
- Fix quality:
2 (DGPS/SBAS)
- HDOP: 1.0 (placeholder)
- Altitud: 0.0 m (no estimada)
- Geoid separation: 0.0 m
Els checksums NMEA es calculen amb XOR de tots els caràcters entre $ i *.
14. API, Comandes i OTA
14.1 API GeoPulse Backend
| Paràmetre | Valor |
| URL Base | https://api.geopulse.systems |
| Login | POST /login amb { username, password } |
| Endpoint comandes | GET /api/device/aquapulse/commands |
| Autenticació | Authorization: Bearer <apiKey> |
| Polling | Cada 30 s (COMMAND_POLL_INTERVAL_MS) |
| Refresh API key | Automàtic en rebre HTTP 401 |
| TLS | WiFiClientSecure::setInsecure() (sense verificació de cert) |
14.2 OTA (Over-The-Air)
| Paràmetre | Valor |
| URL fixa | http://updates.geopulse.systems/aquapulse/firmware.bin |
| Buffer de descàrrega | 128 bytes |
| Timeout HTTP | 20 s |
| Heap mínim per iniciar | 20 KB |
| Suport HTTPS | Sí (setInsecure) |
| Redirects | Strict follow |
| Indicador visual | Blanc OTA_PROGRESS (2× 120 ms) |
| En cas d'error | Vermell OTA_FAILED sòlid 3 s |
14.3 Inventari Complet de Comandes
14.3.1 Sistema
| Comanda | Descripció |
reboot | Reinici immediat (sempre permès) |
set_standby / resume | Mode estalvi (sempre permès) |
get_standby_status | Consulta estat (sempre permès) |
status / connectivity_status | Imprimeix estat de WiFi i autenticació |
get_status | Resum DEVICE / NETWORK / GPS / WAVE / RUNTIME |
version | Versió firmware i data de build |
task_status | Estat i últim run de cada tasca |
force_reauth | Força re-autenticació al portal captiu |
set_log_level_<debug|info|warning|error> | Filtra el nivell de logs |
14.3.2 GPS i Telemetria
| Comanda | Descripció |
set_knots / set_kmh | Unitat de velocitat |
set_interval_500ms | Telemetria a 500 ms (alta precisió) |
set_interval_1s | Telemetria a 1 s (per defecte) |
set_interval_2s | Telemetria a 2 s (normal) |
set_interval_5s | Telemetria a 5 s (estalvi) |
set_interval_10s | Telemetria a 10 s (baix ample de banda) |
gps_monitor / GPS_STATUS_MQTT | Monitor GPS durant 60 s |
enable_gps_read | Reprèn la tasca GPS si està suspesa |
force_gps_send | Força un enviament de telemetria immediat |
14.3.3 Wave Data / IMU
| Comanda | Descripció |
wave_status / get_wave_data | Imprimeix dades d'ona detallades |
wave_debug | Debug complet a Serial |
wave_send / send_wave_data | Força enviament UDP de wave data |
wave_interval <seconds> | Estableix interval de publicació (10-3600 s) |
14.3.4 Calibració de Rumb (Offset Simple)
| Comanda | Descripció |
heading_cal_start / heading_calibrate | Activa recol·lecció automàtica |
heading_cal_stop | Atura recol·lecció |
heading_cal_status | Mostra mostres, offset i spread |
heading_cal_apply | Aplica calibració (mín. 10 mostres) |
heading_offset <deg> | Estableix offset manual (-180° a +180°) |
heading_cal_sample | Afegeix una mostra manual (req. SOG ≥ 7 kt) |
heading / get_heading | Mostra rumb cru i corregit + comparació COG |
14.3.5 Taula de Desviació (36 punts)
| Comanda | Descripció |
deviation / deviation_status | Estat de la calibració (X/36 buckets) |
deviation_table / deviation_card | Imprimeix la deviation card completa |
deviation_save | Guarda la taula a NVS |
deviation_clear | Esborra calibració de NVS |
deviation_enable / deviation_on | Activa auto-recol·lecció |
deviation_disable / deviation_off | Desactiva auto-recol·lecció |
deviation_sample | Mostra forçada (bypassa rate limit) |
14.3.6 LEDs
| Comanda | Descripció |
led_status | Estat actual dels 4 LEDs + brillantor |
led_brightness <0-255> | Brillantor global |
led_off | Master disable (PWM=0 a tots) |
led_on | Master enable |
14.3.7 OTA
| Comanda | Descripció |
ota_update | OTA des de la URL fixa |
remote_ota_update <url> | OTA des d'una URL arbitrària (http/https) |
14.3.8 Geofencing
| Comanda | Descripció |
geofence_list | Llista totes les geofences |
geofence_add <cat> <name> <lat> <lon> <radius> <enter> <exit> [alias] | Afegeix nova geofence |
geofence_remove <name> | Elimina geofence per nom |
Limitació en cas de memòria baixa: Si el heap és < 20 KB, només s'accepten reboot, set_standby, resume i get_standby_status. La resta es rebutgen amb [WARNING] Memory low - only critical commands.
15. Tasques FreeRTOS
El sistema executa 13 tasques concurrents sobre el dual-core de l'ESP32. Totes són monitoritzades per updateTaskRun() i visibles via task_status.
| Tasca | Stack | Prio | Funció |
LED | 2 KB | 1 | Patrons dels 4 LEDs (PWM hardware) |
WiFi | 8 KB | 1 | Connexió i reconnexió a 4 xarxes |
GPS | 4 KB | 2 | Lectura Serial1 + filtres TinyGPS++ |
CmdPoll | 8 KB | 1 | Telemetria UDP + polling de comandes HTTPS |
Accel | 4 KB | 2 | IMU 25 Hz + càlcul d'estat de mar |
LogFlush | 4 KB | 1 | Buidat periòdic del buffer de logs |
SysMon | 4 KB | 1 | Monitorització de heap + alimenta watchdog |
OTA | 8 KB | 1 | Descàrrega i flash del firmware |
Internet | 20 KB | 1 | TLS pesat: portal captiu + status checks |
GeoEval | 4 KB | 2 | Avalua geofences cada 5 s |
GeoPub | 4 KB | 3 | Envia events de geofence (cua FIFO) |
GeoPersist | 4 KB | 1 | Guarda geofences a LittleFS |
Watchdog | 2 KB | 1 | Reinici si SysMon no s'alimenta > 120 s |
15.1 Sincronització
Mutexes utilitzats per protegir estructures compartides:
| Mutex | Protegeix |
gpsDataMutex | Estructura currentGPSData |
seaStateMutex | Variable seaStateIndex |
ledStateMutex | Estats dels 4 LEDs |
logBufferMutex | Buffer de logs (FIFO 2 KB) |
geofencesMutex | Vector de geofences i flag dirty |
systemReadyMutex | Flag systemReadyForServices |
udpMutex | Client UDP (multi-tasca segur) |
16. Manteniment i Diagnòstic
16.1 Diagnòstic per Patró de LED
| Símptoma | LED | Causa Probable | Acció |
| Sense fix GPS prolongat | Blau parpelleja únic + Vermell 2× ràpid | Antena obstruïda o sense visió del cel | Verificar antena GPS |
| Boot infinit | Blanc breathe permanent | WiFi no connecta | Verificar credencials/abast |
| Estat de mar sempre 0 | Verd 1 s lent | IMU no detecta moviment o calibració | Esperar 2-5 minuts perquè el filtre estabilitzi |
| SOS Morse permanent | Vermell SOS | Watchdog disparat (bloqueig del SysMon) | El sistema es reiniciarà sol en 2 s |
| Strobe ràpid vermell | Vermell 50/50 ms | Totes les credencials captives han fallat | Provar force_reauth o canviar de xarxa |
| 5 flashes vermells | Vermell 5× | Heap < 12 KB — reinici imminent | Cap acció — auto-recuperació |
| Blanc parpelleja sense LED Verd | Blanc + Verd OFF | ICM-20948 no detectat al bus I2C | Verificar cablejat SDA=21, SCL=22, alimentació |
16.2 Logs i Debug
Els logs es poden veure simultàniament a:
- Sèrie USB @ 115200 baud (mostra també prefix
[LOG] dels paquets UDP enviats)
- Backend UDP via
LOG,aquapulse,... (parser del backend reconeix nivells)
- Heartbeat loop(): cada 60 s LOG_D amb heap, WiFi i sys ready
- IMU debug: cada 10 s LOG_D amb pitch/roll/heading/acc/RMS/SS
- Sea state compact: cada 30 s a Serial
- Sea state full: cada 2 minuts a Serial
16.3 Heartbeat del Loop Principal
[DEBUG] HEARTBEAT: Heap=<bytes> WiFi=<yes|no> SysReady=<yes|no>
[DEBUG] IMU: P=<pitch>° R=<roll>° H=<heading>° Acc=<raw>g RMS=<rms>g Vert=<vAcc>m/s² SS=<index>
16.4 Recuperació Automàtica
El sistema implementa diversos mecanismes de recuperació:
- Watchdog: reinici si
SysMon no s'executa en 120 s.
- Reinici per memòria crítica: heap < 12 KB →
ESP.restart().
- Reconnexió WiFi: event-driven via
WiFiEventHandler + reintent cada 60 s en cas de fallada.
- Re-fetch API key: automàtic en rebre HTTP 401.
- Rotació de credencials Crew: 3 jocs amb rotació en cas de quota.
- GPS unhealthy: marcat després de 60 s sense fix; auto-recuperació quan torna.
⚠️ ADVERTÈNCIES IMPORTANTS:
- NO connectar res als pins
GPIO16 i GPIO27 — són NC al FireBeetle 2 ESP32-E.
- El bus I2C es comparteix amb la llibreria de SparkFun — no instanciar altres dispositius I2C sense coordinar
Wire.
- L'OTA requereix > 20 KB de heap lliure; en cas contrari es cancel·la.
- El filtre Aranovskiy necessita 1-2 minuts per convergir després de moviments fortament canviants.
- La calibració de rumb només s'admet a SOG ≥ 7 nusos per garantir fiabilitat del COG.
- El voucher Balearia és únic i hardcodejat — un cop esgotat cal re-flashejar el firmware.
- Les credencials WiFi i les geofences es perden si es formatja el LittleFS.
✅ Bones Pràctiques d'Instal·lació:
- Munta l'IMU el més aprop possible del centre de gravetat del vaixell per millors lectures de heave.
- Orienta l'IMU amb l'eix X cap a proa per coherència en els valors de pitch/roll.
- Manté l'antena GPS amb visió clara del cel i lluny d'antenes VHF/HF actives.
- Realitza la calibració de la deviation card al llarg d'una navegació de mínim 30 minuts amb canvis de rumb variats.
- Verifica periòdicament la quota Balearia amb la telemetria de logs.
16.5 Suport Tècnic
API i actualitzacions: api.geopulse.systems
Servidor de telemetria UDP: 188.166.104.124:5052
OTA endpoint: http://updates.geopulse.systems/aquapulse/firmware.bin
AquaPulse Marine Tracker — Manual d'Usuari v2.0.9
Firmware: AquaPulse-2.0.9_UDP_MUTEX | Basat en FireBeetle 2 ESP32-E
Document generat: Maig 2026
© 2026 GeoPulse Systems — Tots els drets reservats