Caratteri non voluti su display

Una buona giornata a tutti.

Ho un problema con la visualizzazione su display grafico dei dati ricevuti,

mi spiego:

ho realizzato un barometro con l’integrato BME280, montato su PCB con un Arduino nano ed un HC05,

il tutto all’interno di un contenitore il legno, posizionato in cantina.

La parte ricevente (Slave) sempre con un Arduino nano, una RTC_DS3231, un sensore DS_18B20, ed un HC05,

anche questo montato in un contenitore in legno e posizionato all’interno di casa ad una distanza di 20m circa,

il tutto funziona quasi sempre bene, salvo avvolte sul display vengono visualizzati dei caratteri non voluti, cioè

su display mando Temperatura, Pressione, Umidita,(BME280) a volte al posto (per esempio temperatura = 25.3) mi stampa 25.ò,

oppure Umidita FF, anche in Pressione mi stampa 10ff.

Penso che l’inghippo sia sul programma, pero non so, dove possa essere,

perciò vi chiedo cortesemente se potete dare uno sguardo ai programmi che posto,

ed avere un suggerimento su dove possa essere l’eventuale l’errore.

Ringrazio anticipatamente chi mi può aiutare
Barometro_HC05_Master.cpp (2.0 KB)
Barometro_HC05_Slaiv.cpp (7.6 KB)

Quell'errore esatto non lo trovo.
Trovo però un'altra serie di errori e cose che sinceramente non capisco.
Dal programma master:

  1. dataOut lo dichiari grande 13, poi hai la funzione clr_dataOut che fa un bel ciclo fino a i<17
    Fai una cosa, dichiara una costante per la dimensione 13 e poi usa quella in giro
#define K_LENOUT 13
char dataOut[K_LENOUT];
...
void clr_dataOut() 
{ for (i = 0; i < K_LENOUT; i++)  dataOut[i] = 0x00;
}
  1. chiami nella loop la senddata e poi un delay(2000), ma dentro a senddata c'e' alla fine un ulteriore delay(100). Metti un solo delay() nel loop a 2100
    e poi nella senddata a che servono quei vari delay(10) tra le conversione float/stringa ?

  2. Quando fai le conversioni float/stringa, DEVI considerare il carattere fine stringa, quindi aggiungi sempre un carattere TEMPERATURA,PRESSIONE a 5 e non a 4 e UMIDITA a 3
    Quindi semplifica la sendData, porta le conversioni dentro alle rispettive funzioni e adegua la stringa, portandola dentro la funzione stessa:

void setTemperatura() 
{  // converte un float in char (float,  num.cifre intere, num cifre decimali, vettore)
  char TEMPERATURA[5];   // 4+fine stringa
  dtostrf(temperatura, 2, 1, TEMPERATURA);
  dataOut[0] = 0xF1;
  dataOut[1] = TEMPERATURA[0];
  dataOut[2] = TEMPERATURA[1];
  dataOut[3] = TEMPERATURA[2];
  dataOut[4] = TEMPERATURA[3];
}

Slave:

  1. un Serial.available(); buttato in mezzo al loop() non capisco che senso ha
  2. sintassi "strana" non credevo compilasse: char DO[] { "Domenica " };
    dovrebbe essere char DO[]={ "Domenica " }; o ancora meglio char DO[]="Domenica ";
    ma in generale puoi semplificarlo con una matrice:
char giorni[] { "Domenica ", "Lunedi   " ,"Martedi  ","Mercoledi","Giovedi  ","Venerdi  ","Sabato   " };

e quindi

  _day_G = now.dayOfTheWeek();
  u8g2.setFont(u8g2_font_7x13B_tr);
  u8g2.drawStr(20, 48,  giorni[_day_G] );
  1. spedisci 13 caratteri (in esadecimale ?? perchè ? , HEX in master ??) ma anche un 13 prima delle serial.println, quindi in tutto 14 caratteri, iniziando con un write(13) ma tu leggi poi con ciclo 13, mi pare manca nel conto un carattere (nel ciclo for int i da 0 a i<13)
    Inoltre:
if (Serial.available() > 0) {
  for (int i = 0; i < 13; i++) {
	DATAIn[i] = Serial.read();
	delay(50);
    } 
   Serial.end();
   Serial.begin(9600);
}else {
  Serial.end();
  Serial.begin(9600);
}

Perchè quel serial end e poi begin ? per pulire buffer ? esiste la Serial.flush()
che poi quell'if !! mamma mia, o è vero o è falso sempre end e begin fai:

if (Serial.available() > 0) 
{  for (int i = 0; i < 13; i++) 
   { DATAIn[i] = Serial.read();
     delay(50);
    } 
}
Serial.end();
Serial.begin(9600);

Ciao nid69ita grazie di avermi risposto
ora grazie ai tuoi suggerimenti vedo di sistemare il tutto,
quel for su clr_dataOut me nero scordato, perché ero partito con 17,
poi facendo i conti (ovviamente sbagliati) sono arrivato a 13,
ora sistemo il codice, provo poi ti dico come va
mille grazie

Eccomi ho fatto le modifiche suggeritemi, solo quelle riguardanti la trasmissione dati,
le altre per l'orologio le faccio dopo aver risolto il problema della trasmissione,
posto i due file solo parte modifiche, (spero di aver fatto giusto), ma se serve posso postare tutto.
Con queste modifiche un certo miglioramento c'è, più raramente si verificano dati errati,
magari ci sono ancora cose da aggiustare?
Intanto mille grazie per il tempo che mi dedicate.

Una domanda fuori programma, non trovo più il modo di assegnare un Karma, come si fa ora?
Barometro_HC05_Master_Modifiche.cpp (1.2 KB)
Barometro_HC05_Slaiv_Modifiche.cpp (1.1 KB)

Io commenterei la spedizione dei dati in HEX quando effettivamente

Io fossi in te cambierei la logica.
versione A. lo slave quando serve manda via seriale la richiesta dei dati e quindi il master spedisce solo quando serve
versione B. lo slave legge sempre (quando Serial.available) e mette in DATAin, quando serve lo visualizza
Inoltre manderei nella spedizione 2 char aggiuntivi; un inizio spedizione (es. '#') e un fine spedizione (es. '@')
perciò invio dati:

  Serial.print('#');         //inizio
  Serial.write(dataOut, K_LENBUF);         //Invio dati
  Serial.print('@');         //fine
  // for (i = 0; i < K_LENBUF; i++) Serial.print(dataOut[i],HEX);   // per debug

Scusami se rispondo in ritardo, impegni famigliari (e questi vengono prima)
delle tue proposte (A B) opterei per la B,
che (scusami) mi sembra che e quello che sta facendo, sbaglio

manderei nella spedizione 2 char aggiuntivi; un inizio spedizione (es. '#') e un fine spedizione (es. '@')

Ok non e un problema, basta che modifico i due for in lettura, ma questi due dati come vanno gestiti

No nello slave leggi solo se da menu tu entri in quella voce "seconda pagina" mi pare.

No nello slave leggi solo se da menu tu entri in quella voce "seconda pagina" mi pare.

Si hai visto giusto,
in sostanza dovrei leggere i dati anche in prima pagina,

No, io farei un pezzo di codice, magari una funzione, che richiami sempre ad inizio loop() che verifica se arrivano dati con Serial.available(), ma legge solo un carattere alla volta e li mette in ordine dentro a dataIN, con un conta posizione, e verifichi che arrivi il fine trasmissione '@'
Quando quella arriva attivi un flag che dice dati Okay, mentre mentre leggi lo metti a falso
Solo quando è okay, sai che puoi dare il valore. Eventualmente se sta ricevendo un valore puoi fare il display del valore precedente. E' solo una idea.

Perché a me pare normale che, mentre fai il display della pagina, proprio in quel momento il master sta già spedendo. E quindi lo slave sta ricevendo solo una parte dei dati.

Finalmente ho trovato il tempo per provare quello che mi hai suggerito,
in effetti (non avevo dubbi) fatto una funzione che legge continuamente e mando a display solo dopo la verifica che sia arrivato l'ultimo dato (inserito opportunamente) ora funziona benissimo
mille grazie per i preziosi suggerimenti,
una volta si aveva la possibilità di dare un Karma, ma ora non so come si fa,
se puoi dirmi come si fa ti sarei molto grato.

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