Dati differenti tra monitor seriale e nextion

Buongiorno a tutti,
sto cercando di inviare dato VOLT da arduino a nextion .
la lettura del voltmetro in ingresso su pin analogico A0 , viene correttamente inviata al monitor seriale. ho usato una batteria da 9v e ottengo una lettura corretta.
quando pero invio il dato alla casella di testo su nextion il dato non e' coerente e viene visualizzato un numero senza senso (almeno per me).
suggerimenti?

grazie mille

void updateVolt() {
  adc_value = analogRead(ANALOG_IN_PIN);
  adc_voltage  = (adc_value * ref_voltage) / 1024.0;
  in_voltage = adc_voltage / (R2 / (R1 + R2));
  char str2[4];
  sprintf(str2, "%02i", in_voltage);
  volt.setText(str2);
  
  Serial.println(in_voltage);
}

Secondo me il problema è dalle parti della sprintf()...

Inizializza a zero la stringa che usi

E falla stampare sulla seriale, per controllo

in che senso indirizza a zero la stringa? intendi str invece che str2 ?

comunque il problema e' sicuramente dalle parti di sprintf()
ho provato anche a cambiare "%02i" con "%02d" ma rimane lo stesso

Ma se mandi sulla seriale str2 (oltre che in_voltage) cosa ti stampa? E la variabile in_voltage come è definita (che tipo è) ?

Guglielmo

mi stampa 20402 esattamente come sul nextion.....quindi il problema e' li.
ammetto che non ho idea di come procedere

la variabile in_voltage e' float

float adc_voltage = 0.0;
float in_voltage = 0.0;
float R1 = 30000.0;
float R2 = 7500.0;
float ref_voltage = 5.0;
int adc_value = 0;

Beh ... se è un float perché cerchi di stamparlo come un intero ? E' chiaro che i valori binari vengono mal interpretati ... :roll_eyes:

sprintf(str2, "%02f", in_voltage);

Guglielmo

si questo l' avevo gia provato (intuizione) ma mi stampa in seriale un "?"

... scusa, metti anche che vuoi 0 decimali:

sprintf(str2, "%02.0f", in_voltage);

... non vorrei che li tira fuori tutti altrimenti.

Guglielmo

Ahhhh ... aspetta, NO, su Arduino, per ragioni di occupazione di memoria, la sprintf() NON è implementata per i float! Non la puoi usare!

Guglielmo

ah cavolo questo , come tante altre cose, non lo sapevo.
pero perche il dato e' corretto se lo imposto come intero ? almeno sulla seriale e' corretto

QUI c'è il trucco se si deve veramente stampare un float con i decimali, ma se non ti servono, lo puoi trasformare in intero e stampare un intero :slight_smile:

Guglielmo

grazie mille. adesso vedo se riesco ad usarlo correttamente

perfetto!!! ti ringrazio molto.
ho usato il trucco cosi

void updateVolt() {
  adc_value = analogRead(ANALOG_IN_PIN);
  adc_voltage  = (adc_value * ref_voltage) / 1024.0;
  in_voltage = adc_voltage / (R2 / (R1 + R2));
  char str2[4];
  //sprintf(str2, "%02f", in_voltage);
  sprintf(str2, "%d.%02d", (int)in_voltage, (int)(in_voltage*100)%100);
  volt.setText(str2);
  
  Serial.println(str2);

Inizializza...

Che non è vuota

Come tutte le variabili locali in C

Anche se la cosa è vera normalmente, dato che non sai mai cosa c'è dentro, in questo caso ...
... NON serve, la sprintf() la riempie dall'inizio ed aggiunge il terminatore ... :wink:

Guglielmo

Un char array di 4 elementi?

Dove sarebbe il terminatore?

Edit

Con questo intendo che esiste comunque qualcosa di non chiaro sulle lunghezze stringa...

Poi...

Proprio perché stampa quel numero la sprintf() ha messo il 0x00 finale altrimenti sai cosa avrebbe stampato ... :roll_eyes:

Ovviamente ha sforato di memoria ed ha sovrascritto quello che segue, ma questo è un errore di dimensionamento, NO di riempimento iniziale.

E' compito di chi usa la sprintf() dimensionare bene l'array di char ... altrimenti ... sfora, ma lo 0x00 lo mette :wink:

Guglielmo

... aggiungo che, per ovviare a questo, basta usare la snprintf() che ... richiede anche il parametro della lunghezza massima, così non ci sono problemi:

int snprintf ( char * __s,
size_t __n,
const char * __fmt,
...
)

no more than n characters (including the trailing NUL character) will be converted to s .

Guglielmo

1 Like