ubxconfig

ubxconfig è l’applicazione Android sviluppata per configurare in modo semplice il ricevitore MS2 direttamente da smartphone o tablet, senza necessità di PC e u-center.

Permette di:

  • applicare il profilo Rover
  • applicare il profilo Base (Survey-In o Fixed)
  • applicare il profilo Base Caster (Survey-In o Fixed)
  • abilitare l’output dei dati grezzi (RAW: RXM-RAWX / RXM-SFRBX)
  • monitorare in tempo reale il flusso seriale e — soprattutto — recuperare automaticamente la configurazione del ricevitore quando questa è stata corrotta da un factory reset accidentale (tipico dopo l’uso di u-center).

L’app è pensata come strumento da campo: tutto ciò che serve è il telefono e, in caso di problemi seri, un cavo USB-C OTG.

Schermata principale

La Home dell’app è organizzata come un’unica card che racchiude tutti i passaggi della procedura di connessione e configurazione.

  1. Status: indicatore in alto a destra con pallino colorato e testo:

    • Connected (verde) — connessione attiva e funzionante
    • Connecting… (arancione, con contatore secondi 1..5) — tentativo in corso. Allo scadere del 5° secondo se la connessione non è ancora stabilita, l’app aborta e segnala Not found
    • Not found (rosso) — l’ultimo tentativo non è andato a buon fine
    • Not Connected (grigio) — stato neutro a riposo
  2. Mode: dropdown per scegliere il canale di comunicazione

    • Bluetooth (Bluetooth Classic SPP) — il canale standard per uso quotidiano. Si appoggia ai dispositivi già abbinati nelle impostazioni Android. La lista mostra solo i ricevitori il cui nome inizia con MS2-XXXX
    • BLE Nordic (Bluetooth Low Energy con profilo Nordic UART Service) — alternativa a basso consumo, scansiona ogni volta i dispositivi MS2 visibili. La selezione non viene memorizzata: lo scan è sempre fresco

    La modalità USB non è esposta come Mode separato: è un canale di servizio attivato solo quando serve il recovery (vedi USB Recovery più sotto).

_images/home_mode_dropdown.png

Fig.1 Dropdown Mode

  1. Device: dropdown del dispositivo, dipendente dal Mode selezionato
    • In Bluetooth elenca solo i ricevitori già abbinati con nome MS2-…
    • In BLE Nordic apre lo scan al tap (durata 5 s); allo scadere se non viene trovato nulla mostra Non trovato. Ogni elemento riporta nome, indirizzo MAC e RSSI in dBm
  2. Receiver Configuration (visibile solo a connessione attiva): card cliccabile che porta alla schermata di configurazione (Rover, Base Survey-In, Base Fixed, Upload File personalizzato)
  3. Serial Monitor (visibile solo a connessione attiva): pulsante verde che apre la schermata terminale per ispezionare il flusso NMEA/UBX in arrivo dal ricevitore
  4. GNSS Status (visibile solo a connessione attiva e dopo lettura riuscita): card popolata automaticamente leggendo dal ricevitore i parametri principali via UBX-CFG-VALGET:
    • Mode: ROVER, SURVEY-IN, FIXED BASE, UNKNOWN
    • Rate: frequenza di aggiornamento in Hz
    • UART1 / UART2: protocolli di output abilitati con baudrate fra parentesi
    • Elev. Cutoff: angolo minimo di elevazione satelliti in gradi
_images/home_gnss_status.png

Fig.2 Card GNSS Status popolata

  1. Communication Error (card gialla, visibile solo a connessione attiva ma con problemi): appare quando l’app non riesce a leggere la configurazione del ricevitore o quando rileva UART1 a un baud diverso da 115200. Il testo invita a collegare il cavo USB OTG. Una volta collegato, la card sparisce e al suo posto compare il bottone arancione USB RECOVERY
_images/home_communication_error.png

Fig.3 Card Communication Error

In questo stato l’app è connessa via Bluetooth ma rileva un problema di comunicazione col ricevitore — tipicamente un baud mismatch dopo un factory reset da u-center. Per recuperare basta collegare un cavo USB-C OTG fra telefono e MS2: la card gialla scompare e al suo posto compare il bottone arancione USB RECOVERY, descritto nel paragrafo dedicato più sotto.

_images/home_usb_recovery_button.png

Fig.4 Bottone USB RECOVERY

  1. Connect / Disconnect: pulsante verde/rosso in fondo che avvia o chiude la connessione del Mode selezionato

Connettività e baud rate

Il modulo Bluetooth integrato nell’MS2 è configurato lato seriale a 115200 baud, e la comunicazione corretta col ricevitore u-blox interno richiede che anche UART1 del ricevitore sia a 115200. La Rover applicata dall’app imposta esattamente questo baud, oltre ad abilitare UART1OUTPROT_UBX = 1 (necessario perché le risposte UBX-CFG-VALGET — e quindi la card GNSS Status — siano correttamente trasmesse al telefono via Bluetooth).

Se si fa un factory reset del ricevitore da u-center, il baud cambia (default u-blox = 38400, oppure 9600 in alcuni casi) e la comunicazione Bluetooth si rompe: il modulo BT a 115200 legge byte campionati al baud sbagliato → solo immondizia, nessun NMEA né UBX leggibile. È questo lo scenario per cui esiste USB Recovery.

USB Recovery

Operazione one-shot dedicata al ripristino della comunicazione quando il ricevitore è «fuori sincronia». L’utente:

  1. Si connette via Bluetooth come al solito
  2. Vede comparire la card gialla Communication Error (segnale che il baud del ricevitore è sbagliato)
  3. Collega il cavo USB OTG fra telefono e MS2
  4. La card gialla viene sostituita dal bottone arancione USB RECOVERY
  5. Tappa il bottone

A questo punto l’app esegue automaticamente, senza intervento dell’utente:

  • Disconnessione del Bluetooth attivo
  • Apertura della porta USB-C OTG (richiede l’autorizzazione di sistema al primo collegamento)
  • Scansione del baud reale del ricevitore provando in sequenza 9600 / 38400 / 115200 / 230400 / 460800 baud, inviando un poll UBX-MON-VER per ciascuno
  • Una volta identificato, manda il comando UBX-CFG-VALSET per riportare UART1_BAUDRATE = 115200 in RAM+Flash, riallinea la propria porta seriale al nuovo baud e attende l’ACK
  • Verifica post-cambio inviando un secondo MON-VER a 115200 per confermare che il ricevitore risponde
  • Applica l”intera configurazione Rover (9 frame UBX-CFG-VALSET, layer RAM+BBR+Flash) frame per frame, con attesa di UBX-ACK-ACK fra l’uno e l’altro
  • Chiude la porta USB

Durante tutta l’operazione un dialog centrato a schermo mostra in tempo reale lo stato («Provo X baud…», «Ricevitore trovato a X baud», «Applicazione Rover N/9…»). Al termine compare un secondo dialog di conferma con l’esito.

_images/recovery_success_dialog.png

Fig.5 Dialog di conferma recovery

L’utente clicca OK, scollega il cavo USB, riconnette via Bluetooth e la connessione torna funzionante.

Nota importante: durante il recovery l’app non resta «connessa USB» persistentemente. È un’operazione atomica: aprire, riparare, chiudere. La modalità USB non compare nemmeno nel dropdown Mode — è un automatismo nascosto dietro al bottone Recovery.

Receiver Configuration

Schermata raggiungibile dalla card omonima sulla Home (visibile a connessione attiva). Permette di applicare uno dei tre profili principali — Rover, Base Survey-In o Base Fixed — oppure di caricare un file di configurazione UBX personalizzato. Il layout della pagina si adatta automaticamente alla modalità scelta dal dropdown Receiver Mode in alto: appaiono solo i campi pertinenti al profilo selezionato.

In modalità Rover il layout è essenziale: dropdown Receiver Mode = Rover, dropdown Frequency per scegliere il rate di aggiornamento (1, 2, 5 o 10 Hz), poi il bottone collassabile Advanced. Espandendolo (icona ingranaggio in verde, freccia verso l’alto) si accede ai parametri meno frequenti — Cutoff (angolo minimo di elevazione satelliti, range 0–40°, modificabile via stepper −/+ o digitando il numero direttamente), lo switch RAW data (abilita RXM-RAWX e RXM-SFRBX su UART1) e Save to Flash (commit definitivo in flash oltre che in RAM). In fondo, il bottone verde Send Configuration invia la configurazione al ricevitore.

_images/receiver_configuration_rover.png

Fig.6 Rover (Advanced)

Selezionando Base dal dropdown Receiver Mode la schermata cambia: appare un sotto-dropdown Base Mode con due voci, Survey-In e Fixed Position. La modalità Survey-In è la più rapida: il ricevitore esegue un auto-posizionamento progressivo accumulando misure finché due condizioni non sono soddisfatte simultaneamente — la Minimum duration in secondi (default 60 s) e la Minimum accuracy in metri (default 5.0 m). Per setup di precisione tipici di NTRIP server fissi, ha senso aumentare drasticamente questi valori (es. 600+ s e 1.0 m) per garantire una posizione di base con incertezza sub-metrica.

_images/receiver_configuration_base_survey.png

Fig.7 Base Survey-In

La modalità Fixed Position è dedicata a installazioni in cui le coordinate del punto base sono già note — tipicamente perché ottenute da un caposaldo geodetico, da una Survey-In precedente memorizzata, o da un rilievo topografico tradizionale. Il dropdown Coordinates permette di scegliere il sistema di riferimento: LLH (latitudine/longitudine in gradi decimali, altezza in metri) come nello screenshot, oppure ECEF (X/Y/Z in metri, sistema cartesiano geocentrico). Una volta inserite le tre coordinate, il bottone Send Configuration le invia al ricevitore che entra immediatamente in TMODE = 2 (fixed) e inizia a generare correzioni RTCM3 sui canali configurati (UART2 di default, oppure UART1 in modalità Caster).

_images/receiver_configuration_base_fixed.png

Fig.8 Base Fixed (LLH)

In tutte le modalità, il pannello Advanced viene collassato automaticamente quando si cambia Receiver Mode: questo evita che la pagina diventi troppo lunga quando si passa da Rover — compatto — a Base Fixed che ha già 4 campi visibili. L’utente riapre Advanced manualmente al bisogno.

  1. Rover

    Profilo per uso come ricevitore mobile a una frequenza configurabile (1, 2, 5, 10 Hz):

    • Output NMEA su UART1 (GGA, GSA, GSV, RMC, GST, GNS attivi; GLL e VTG off)
    • UBX off (a meno di RAW abilitato — vedi sotto)
    • Tutti i messaggi RTCM disabilitati su entrambe le UART
    • TMODE off
    • Cutoff elevation 10°
    • UART1_BAUDRATE = 115200, UART2_BAUDRATE = 57600
    • Spunta opzionale RAW data: abilita RXM-RAWX e RXM-SFRBX su UART1, e attiva UART1OUTPROT_UBX = 1 (necessario per il flusso UBX RAW)
  2. Base Survey-In

    Profilo per stazione base con auto-posizionamento progressivo:

    • Durata minima di sopravvivenza in secondi (configurabile)
    • Accuratezza target in mm (configurabile)
    • Output RTCM3 (1005, 1077, 1087, 1097, 1127, 1230) su UART2 verso radio o NTRIP caster
    • Modalità Caster selezionabile: l’output RTCM passa su UART1 anziché UART2 (utile per integrazione con bridge che ripubblica su NTRIP server)
    • Spunta RAW data come per la Rover
  3. Base Fixed

    Profilo per stazione base con coordinate note (LLH o ECEF):

    • Coordinate inserite manualmente o ricavate dall’ultima Survey-In
    • Stesso schema RTCM3 della Survey-In
  4. Upload File

    Carica un file di configurazione UBX in formato testuale (.txt con coppie chiave-valore esadecimali) e applica i comandi al ricevitore. Utile per pre-set personalizzati o forniti dal supporto Solutop.

Per ciascun profilo l’utente sceglie il target layer su cui scrivere la configurazione:

  • RAM — temporaneo, perso al reboot
  • BBR — battery-backed RAM, sopravvive al reboot ma non al taglio dell’alimentazione
  • Flash — persistente
  • Tutti — RAM + BBR + Flash (raccomandato per modifiche definitive)

L’invio avviene a batch di 64 chiavi, con attesa ACK su ciascuno. Una progress bar mostra l’avanzamento.

Serial Monitor

Schermata terminale che mostra in tempo reale il flusso seriale dal ricevitore. Tre modalità di visualizzazione:

  • ASCII: solo testo stampabile, non-printable sostituiti con .
  • HEX: byte per byte in esadecimale
  • Auto (default): rileva NMEA e UBX, formatta NMEA come testo e UBX in hex con header decodificato ([UBX cls id])

Toolbar in alto:

  • Indietro (← chiude e ferma la lettura)
  • Pause / Play (sospende/riavvia il flusso)
  • Clear (pulisce il buffer)

Le righe sono colorate per tipo: verde per ACK UBX, rosso per NAK, blu per altri UBX, grigio chiaro per NMEA.

_images/serial_monitor.png

Fig.9 Serial Monitor (Auto)

Aggiornamenti automatici

L’app verifica automaticamente — al massimo una volta ogni 24 ore — se è disponibile una nuova versione sul repo pubblico delle release via GitHub API. Il timestamp dell’ultimo controllo viene salvato in SharedPreferences; entro le 24h successive l’app non interroga più GitHub, così l’avvio resta veloce anche su rete lenta e si rispetta il rate limit dell’API GitHub (60 req/h per IP non autenticato).

Se viene trovato un tag più recente di BuildConfig.VERSION_NAME, l’app mostra un dialog con il numero di versione disponibile, le note di rilascio (estratto dei primi 300 caratteri) e due opzioni: Scarica (apre direttamente il download dell’APK dalla release) o Più tardi.

Lo stesso check può essere lanciato manualmente in qualunque momento dall’About dialog (icona ℹ︎ in alto a destra) tramite il pulsante Verifica aggiornamenti. Il check manuale ignora il rate limit e fornisce sempre un esito visibile (anche «App aggiornata» o eventuale errore di rete).

_images/about_dialog.png

Fig.10 About dialog

Resilienza alle disconnessioni

La rilevazione di una disconnessione fisica non sollecitata (modulo BT spento, cavo USB staccato, fuori portata) è notoriamente delicata su Android: BluetoothSocket.isConnected non viene aggiornato dal kernel quando il radio link cade, e outputStream.write può essere bufferizzato silenziosamente. L’app combina più meccanismi in parallelo per garantire che lo stato dell’UI corrisponda sempre alla realtà:

  • Bluetooth SPP — tre meccanismi indipendenti:

    1. BroadcastReceiver per ACTION_ACL_DISCONNECTED registrato in connect(): cattura l’evento di sistema appena la radio link cade (latenza ~1 s)
    2. Heartbeat write da 256 byte (32× UBX-MON-VER concatenati) ogni 2.5 s sul polling thread: satura il buffer kernel BlueZ e forza l’arrivo di Broken pipe se il modulo è scomparso
    3. Stream-frozen detector: se inputStream.available() resta a 0 per 3 cicli consecutivi (~7.5 s) — nonostante il ricevitore in stato Connected dovrebbe sempre emettere NMEA in continuazione — il socket viene dichiarato morto

    Servono 2 fallimenti consecutivi dell’heartbeat prima che l’app cambi stato (evita falsi positivi su glitch transient). Il polling gira su Dispatchers.IO quindi continua a operare anche con app in background.

  • BLE — il BluetoothGattCallback riceve STATE_DISCONNECTED immediatamente alla perdita del link e aggiorna l’UI

  • USB — polling ogni 1.5 s su UsbManager.findDevice(). Se il cavo viene staccato fisicamente, l’app resetta solo lo stato USB; la card GNSS Status sul Bluetooth resta visibile se la connessione BT è ancora attiva

  • Crash safety — un Thread.UncaughtExceptionHandler globale assorbe le IOException dei trasporti che dovessero sfuggire ai try/catch dei singoli manager, impedendo all’eccezione di killare l’app. I polling loop hanno inoltre try/catch interni per non morire silenziosamente in caso di errore inatteso

  • Lettura GNSS post-connect con backoff esponenziale — alla prima connessione l’app legge la configurazione del ricevitore tramite tre tentativi di UBX-CFG-VALGET con timeout 2 s / 3 s / 4.5 s e pause 0 ms / 300 ms / 800 ms tra l’uno e l’altro. Maschera i glitch transient di Bluetooth (jitter, NMEA che riempie il buffer prima della risposta UBX) — la card GNSS Status viene popolata anche con un singolo frame perso, e la card gialla Communication Error compare solo quando tutti e tre i tentativi sono falliti

Permessi richiesti

Al primo avvio l’app chiede:

  • BLUETOOTH_CONNECT — necessario per connettersi a dispositivi appaiati (Android 12+)
  • BLUETOOTH_SCAN — necessario per scansionare BLE
  • INTERNET — necessario per il check aggiornamenti via GitHub API
  • Accesso al dispositivo USB OTG — viene chiesto al sistema solo quando si tenta la USB Recovery

Installazione

L’APK è disponibile qui. Su Android occorre abilitare l’installazione da origini sconosciute per il browser o il file manager utilizzato.

Video

Tutorial completo disponibile qui.