Avere una variabile int sempre delle stesse dimensioni

Salve a tutti,
sto creando un traker gps con piattaforma inerziale che invia i dati via LoRa con un Arduino MKR 1310 ad un altro Arduino MKR 1310 che ha il compito di prendere tutti i dati e salvarli su una scheda sd.
per la visualizzazione dei dati in tempo reale e per controllare il sistema l'arduino che riceve i dati via LoRa spedisce i dati via seriale ad un Arduino MKR 1010 (che ha Wifi integrato).
L'arduino wifi mi crea un AP dove con il telefono mi collego e mi visualizza tutti i dati in tempo reale (lo so non è la soluzione migliore ma avevo solo questo materiale).
ho un problema enorme, per suddividere tutti i dati salvo i vari caratteri in un array che con un ciclo for vado a scaricare il una variabile String per la visualizzazione ma sfortunatamente, i dati della piattaforma inerziale non hanno una dimensione costante quindi all'interno dell'array non riesco mai a prendere gli indici giusti per isolare il dato.
avrei bisogno in sostanza di avere:

1--->+001
-12--->-012
300--->+300

vi allego il codice con il controllo dell'array (lo so è scritto con i piedi, ma funziona):

 while (Serial1.available()  && test1 == false) {
      c = Serial1.read();
      if (c == '\n') {
        test1 = true;
        break;
      }
      dati[i] = c;
      i++;
      if (i == 65) {
        i = 0;
      }
    }
    if (test1 == true) {
      test1 = false;
      i = 0;
      for (int j = 36; j <= 39; j++) {
        prova += dati[j];
        delay(1);
      }
      speed = prova;
      prova = "";    
      
       for (int j = 41; j <= 65; j++) {
        prova += dati[j];
        
        delay(1);
      }
      stazmeteo = prova;
      prova="";
      
      for (int j = 0; j <= 65; j++) {
        prova += dati[j];
        dati[j] = 0;
        delay(1);
      }
      stringati = prova;
      prova = "";
    }

vi allego inoltre l'acquisizione dei dati inerziali che utilizza la libreria MKRIMU e come HW l'MKRIMU di arduino.

if (IMU.eulerAnglesAvailable()) {
    IMU.readEulerAngles(heading, roll, pitch);
    }
    int rotta= heading;
    int inclinazione=roll;
    int beccheggio=pitch;

Se non puoi controllare il tuo input come immagino che sia, devi cambiare approccio.

Ad esempio con un "classico" approccio con l'istruzione strtok() per realizzare un "tokenizer".

La stringa che ottieni dal GPS è coerente con lo standard NMEA?
Se riesci a mettere una riga completa della lettura GPS si può abbozzare un algoritmo completo.

il problema non è il gps, quello mi da sempre un numero di caratteri finito, il problema è la lettura degli angoli di inclinazione e la direzione della bussola magnetica che ha larghezza variabile.
comunque in ogni caso i valori ottenuti dal gps sono stringhe NMEA che elaboro con la libreria Arduino_MKRGPS.
vi allego il codice per completezza

if (GPS.available()) {
    latitudine   = GPS.latitude();
    longitudine  = GPS.longitude();
    tempo= GPS.getTime();
    speed = GPS.speed()/1.852;
    read_IMU();
    }

Vabbè, non cambia molto a livello concettuale.
Non hai una stringa completa di esempio?

ecco una stringa di esempio che ha dimensioni diverse

type desc,time,latitude,longitude,altitude (m),speed (km/h),course,pitch,roll
T,1653140256,44.0752182,9.9014883,0,7.77,100,4,11
T,1653140257,44.0752106,9.9015102,0,6.66,95,0,6

gli ultimi 4 valori separati da virgola dovrebbero diventare

95--->095
0--->+000
6--->+006
6.66--->06.66

Scusa il ritardo, ho avuto un contrattempo.
Ho abbozzato questo esempio con una possibile implementazione basata su strtok() per la suddivisione dei valori separati dalla virgola ',' ed usando invece l'istruzione snprintf() per la formattazione delle stringhe a lunghezza fissa.

Edit:
Per uno dei valori float (speed) ho usato l'istruzione dtostrf() perché snprintf, con le schede dotate di poca memoria non supporta il tipo dati float;
Commentato c'è un possibile workaround per questo inconveniente.

Il mio è solo un esempio su come si possono utilizzare le istruzioni che ho citato e non la soluzione al tuo problema :wink:

Per fare quello di cui hai bisogno basta che leggi tutto quello che ti arriva via seriale riga per riga (usando il terminatore di fine linea '\n' oppure '\r'), salvare in un array di caratteri abbastanza capiente, modificare la stringa secondo la formattazione che ti serve ed infine inviare tutto al destinatario.

Fondamentalmente la stessa cosa che gli avevo scritto 6 mesi fa:
https://forum.arduino.cc/t/problemi-con-array-e-cicli-for/1004211/49?u=standardoil

E che è stato fondamentalmente ignorato...

scusami tanto se non ho visto il tuo post, avevo risolto il problema in quel momento per le attuali esigenze (che ora sono cambiate).
se sei disposto ad approfondire l'argomento ulteriormente a me fa solo che piacere!
ti rinnovo le mie scuse!

Sono andato a guardare anche il vecchio post e se devo essere sincero, non mi è molto chiaro perché vuoi che la tua stringa abbia una dimensione fissa.

Ho un po' la sensazione che tu stia affrontando il problema in modo più complesso di quanto realmente necessario perché immagino tu voglia rendere la riga sempre della stessa dimensione in modo da semplificare l'estrazione dei dati contenuti (se non sbaglio).

Il punto della questione è rendere la riga di lunghezza fissa o l'estrazione dei dati da questa riga?
Perché nel secondo caso, non è mica necessario questa manipolazione aggiuntiva (e il primo esempio ne è la prova).

si, voglio estrarre un dato da una stringa a dimensione variabile che mi arriva via seriale.
se hai qualche soluzione io sono tutto orecchie.

ho anche pensato a una soluzione semplice ma poco elegante che va ad elaborare il dato prima di essere inviato.
in particolare in questa zona qua.

in sostanza faccio questo (ho fatto una prova attualmente non ho sotto mano l'arduino)

int num;
String dato="";

void setup(){
  Serial.begin(9600);
}

void loop(){
  num= random(-300,+300);

  if (num<100 && num>0){
    dato = "+0";
    dato += num;
  } else if (num<0 && num> -100 ){
    dato= "-0";
    num=num*-1;
    dato +=num;
  } else if (num>100){
        dato="+";
        dato +=num;
  } else {
    num=num*-1;
    dato="-";
    dato+= num;
    
  }
  Serial.println(dato);

  delay(1000);
}

alla fine la variabile "dato" viene inviata via LoRa e tutto ciò che ci sta a valle riceve sempre una dimensione fissa del carattere.
è un modo molto poco elegante, sono aperto a nuove soluzioni.

Guarda che l'esempio di cui ti ho messo il link fa esattamente questo!

Ok, manca la parte della seriale, ma quella è una cretinata aggiungerla (appena fatto la modifica)

Chiaramente tutti i Serial.println() presenti nella funzione parseLine() sono solo a scopo "dimostrativo" e puoi ometterli senza problemi.
Inoltre, non essendoci più l'esigenza di formattare a dimensione fissa i valori puoi anche rimuovere tutto il codice relativo.

Ti rigrazio delle tue scuse
Ma non sono interessato alla cosa
Tutto quello che avevo da dire sull'argomento lo ho già detto 6 mesi fa
Se questo tempo non ti è bastato per recepirlo è inutile che io prosegua

Mah, perdonami ma non mi è ben chiaro lo scopo della richiesta (e neanche l'esempio). Se ho capito bene, via BT ricevi da un Arduino una stringa di valori separati da virgola, quindi CSV, ma per quale ragione vuoi mandare al telefono quei dati ma con una dimensione fissa?
Sul telefono non puoi fare un parsing della stringa e splittarla per separare i singoli valori, quindi convertirli in quello che ti pare (interi, float, o quello che ti occorre)?
Visto che, immagino, tu non possa/voglia fare queste modifiche (perché il telefono deve essere solamente come un "terminale stupido" diciamo?), dovresti splittarli nell'Arduino es. con strtok() (come diceva @cotestatnt dal post #2) metterli in un array di appoggio dove avrai i singoli valori, e poi convertire quelli che richiedono un formato specifico (aggiungendo il segno, se richiesto, e gli eventuali zeri iniziali), che poi impacchetti nuovamente in CSV e lo mandi al telefono. Mi sfugge forse qualcosa ma non ci vedo problemi particolari.

ho risolto come detto da @cotestatnt e ora tutto funziona!

sfortunatamente non sono un programmatore e non saprei sviluppare un'applicazione per telefonino. le mie conoscenze sono molto limitate come ben potete vedere.
in più non ho trovato applicazioni già fatte per iPhone che si interfaccino ad arduino in nessun modo.
la cosa più semplice per visualizzare i dati e avere un minimo di controllo sul sistema (interrompere e riprendere la registrazione del file e creare un nuovo file) è utilizzare il wifi e creare una pagina in html che mi permette la visualizzazione dei dati.
per ordinare questi dati contenuti in un array ho bisogno di avere una grandezza fissa di questo array, in modo che con i puntatori potevo cavarmela.
come giustamente ha detto @Standardoil bastava anche semplicemente ricercare le virgole ed estrapolare i dati in quel modo, intanto l'ordine dei dati è costante.

Eh, hai voluto la bicicletta?... :sunglasses:
Comunque hai mai dato un'occhiata ad App Inventor? Puoi creare facilmente (piccole) app per Android ed anche (bleah) iPhone...

Ma pure con Javascript si possono fare tante cose, volendo, sai... :wink:

In ogni caso se non vuoi studiarti il javascript (ma non è mica tanto complicato...) la soluzione più semplice è usare strtok() come ti dicevamo (senza stare tu a cercare "a manella" le virgole), quindi avere in un array i singoli elementi, che poi andrai a convertire prima di "impacchettarli" nuovamente in una unica stringa.
Ti consiglierei di provare, poi posta qui il codice se hai problemi e proviamo ad aiutarti.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.