Parametrizzare Stringa

Ciao a tutti,
ho un quesito SW da risolvere e vorrei creare un funzione.
Dovrei creare una stringa ben definita dove vanno inseriti dei dati da letture, poi mandarla sulla seriale.

Es.
Formato stringa :
-->Stringa1,[temp1],[temp2],[temp3],[temp4]*

Durante l'esecuzione del programma leggo es. 4 temperatura differenti. Es. 20 , 101 , 1, 5 °C.
Quindi dovrei creare una funzione che mi dia la seguente stringa:
-->Stringa1,20,101,1,5*
Avete qualche idea su come affrontare il problema?

Sulla seriale puoi spedire anche con Serial.print successive e diverse.

Serial.print("Stringa1");    
Serial.print(",");
Serial.print(temp1);   //variabile che contiene 20
Serial.print(",");
Serial.print(temp2);   //variabile che contiene 101
etc.

per il ° come * non puoi. Manda semplicemente il valore, lo sai tu che è una temperatura in °C

Oppure puoi usare snprint() ma è più complicato. Devi avere un buffer abbastanza capiente, "stampi" dentro al buffer e poi spedisci il buffer

char buf[50];
snprintf(buf,50,"%s,%d,%d,%d,%d",stringa,num1,num2,num3,num4);
Serial.println(buf);

Visto che usi molti float a che su piattaforma AVR lo snprintf non ha supporto per questo tipo di dati, la cosa più semplice è il primo suggerimento che ti ha dato @nid69ita

Si potrebbe provare 0xb0 che è standardizzato da anni (circa 35)

Io avevo una necessità simile e l'ho, felicemente, risolta così:

// nota: celsius, pressure, humidity e altitude sono tutti valori float
// status è un uint8 ,  unix è un uint32
// energyVal e  distanceVal sono uint16

void MakeRecord() {
  char st[6], sp[5], sh[3];
  dtostrf(celsius, 3, 1, st);
  dtostrf(pressure, 4, 0, sp);
  dtostrf(humidity, 2, 0, sh);

  uint32_t unix = now.unixtime();
  sprintf(record, "Record: %d,%d,%d,%d,%s,%s,%s", status, unix, energyVal, distanceVal, st, sp, sh);
  Serial.println(record); // o usalo come vuoi :-)

Con 'sprintf' puoi anche decidere quale separatore usare e con 'dtostrf' hai il vantaggio di formattare i valori come preferisci; il tutto diventa anche più leggibile.
L'array 'record' si presenta così (con valori fittizi):

Record: 1,167453768,1534,16,25.4,997,53

Grazie delle idee. Ci lavoro un attimo e poi aggiorno

Puoi trasmettere solo i singoli valori e aggiungere un valore impossibile, per esempio 255, come sincronismo prima del primo o dopo l'ultimo.

Io vi consiglio SEMPRE di usare snprintf
Occhio perchè stiamo lavorando in C e non viene fatto nessun controllo se state scrivendo oltre allo spazio allocato per il buffer che riceve la stringa (in questo caso record)
Se per esempio hai fatto char record[100]; e quello che scrivi va oltre i 100 caratteri, sprintf lo fa (senza controllare) ed è un problema.
snprintf invece gli passi la dimensione di record (in questo esempio 100) e il comando NON scrive oltre quella dimensione.

Ho provato a scrivere la funzione sono riuscito a passargli il parametro mancante e far uscire la stringa Grazie a tutti! :+1:

Ciao a tutti,
mi sono ancora bloccato con la scrittura di una funzione, che sto provando a scrivere in C ma non ci sto riuscendo. Sto sempre lavorando con stringe.

Ho un stringa A di n caratteri. A= "FR,D1,D2,D3,D4,D5*Checksum"
Vorrei fare una funzione che calcoli il Checksum (Xor) della stringa FR,D1,D2,D3,D4,D5

Quindi dovrei passare alla funzione un vettore di caratteri e mila funzione dovrebbe darmi un vettore di 2 caratteri.

Mi sembra di aver capito che non posso passare il vettore alla funzione me devo utilizzare i puntatori.
Qualcuno saprebbe aiutarmi?

Grazie

Non è obbligatorio lavorare con puntatori. Il C poi quando compila ragiona con puntatori.
Puoi passare tranquillamente il vettore tra quadre (come se fosse un array), esempio:

int SommaVet( int vet[], int numelem)
{ int som=0;
  for(int i=0;i<numelem;i++) { som=som+vet[i]; }
  return(som);
}

usato cosi:
int v[]={10,3,4,5,3,7,5,5,44,3};
int tot=SommaVet(v, 10);

Il problema è farsi restituire un vettore di 2 caratteri. Te lo sconsiglio. Scusa ma non è al tuo livello.
Io ti consiglio o ritorni un intero e poi separi i due byte/char oppure lavori su un array globale di 2 char che "sporchi" dentro la funzione (puoi anche passarlo come altro parametro, magari settandolo prima con valori nulli/0)

char vret[2];
vret[0]=0; vret[1]=0;
void CalcolaChksum( stringa , vret );      // calcola checksum e "sporca" vret con risultato di 2 char

Come dice nid69ita, è molto più semplice ritornare un numerico di due bytes (... e, se invece del tipo "unsigned int" usi il tipo "uint16_t", sarai sicuro che, indipendentemente dalla MCU, sia essa ad 8 bit, sia essa a 32 bit, il valore di ritorno sarà sempre un intero non segnato che occupa due bytes). Se poi ti servono due caratteri corrispondenti al primo MSB (byte più significativo) ed al LSB (byte meno significativo) potrai sempre prendere i 16 bit e ricavare le due metà a 8 bit :wink:

Guglielmo

P.S.: ... se sei curioso di sapere da dove salta fuori quel tipo "uint16_t "ti dico che sono "tipi" definiti in <stdint.h>.