problema refresh su display tft della temperatura misurata

Salve ragazzi,
ho un problema.. Stò usando una sonda DS18B20 con un display tft.
Vorrei visualizzare in un rettangolo la temperatura misurata dalla sonda aggiornata in tempo reale.
Questo però causa un flash continuo sullo schermo,nel senso che (secondo la logica del mio programma) ad ogni iterazione deve riempire il rettangolo del colore dello sfondo e poi riscrivere la nuova temperatura (metodo che ho pensato per cancellare la vecchia temperatura).
purtroppo senza di questo,i caratteri della vecchia e della nuova temperatura si vanno a sovrapporre creando una macchina colorata.

vi posto qui la porzione di codice e un video:

tft.drawRect(20,20,80,60,RED);
   tft.fillRect(20,20,80,60,colInterno); //non ci siamo....
   
   tft.setCursor(25,25);
   tft.setTextSize(2); // Dimensione testo
   tft.setTextColor(RED); // Colore del testo
   Serial.print(" Requesting temperatures..."); //DEBUG
   sensors.requestTemperatures(); //invia comando per prendere il dato della temperatura
   Serial.println("DONE");
   Serial.print("Temperature for Device 1 is: ");
   temp1b = sensors.getTempCByIndex(0);
   Serial.print(temp1b);
   tft.println(temp1b); // Temperatura stampata

VIDEO

la soluzione al problema è più semplice di quanto pensi: è sufficiente stampare la temperatura aggiungendo 2/3 spazi in coda.

In questo modo eviti il lampeggio dovuto al clear/painting dell'area dello schermo.

cyberhs:
la soluzione al problema è più semplice di quanto pensi: è sufficiente stampare la temperatura aggiungendo 2/3 spazi in coda.

In questo modo eviti il lampeggio dovuto al clear/painting dell'area dello schermo.

Ciao cyberhs,
ti ringrazio per la risposta.
Io ho già provato la soluzione che tu mi suggerisci,ma purtroppo non sembra avere effetto.
Infatti la prima soluzione era:

tft.setCursor(25,25);
   tft.setTextSize(2); // Dimensione testo
   tft.setTextColor(RED); // Colore del testo
   Serial.print(" Requesting temperatures..."); //DEBUG
   sensors.requestTemperatures(); //invia comando per prendere il dato della temperatura
   Serial.println("DONE");
   Serial.print("Temperature for Device 1 is: ");
   temp1b = sensors.getTempCByIndex(0);
   Serial.print(temp1b);
   tft.println(temp1b); // Temperatura stampata 
tft.setCursor(25,25);
tft.println("    ");

Infatti le scritte continuavano a sovrapporsi.
Forse ho sbagliato interpretazione alla tua soluzione

   tft.setCursor(25,25);
   tft.setTextSize(2); // Dimensione testo
   tft.setTextColor(RED); // Colore del testo
   Serial.print(" Requesting temperatures..."); //DEBUG
   sensors.requestTemperatures(); //invia comando per prendere il dato della temperatura
   Serial.println("DONE");
   Serial.print("Temperature for Device 1 is: ");
   temp1b = sensors.getTempCByIndex(0);
   Serial.print(temp1b, 1);
   tft.print(temp1b, 1); // senza ritorno a capo
   tft.print("  "); // senza ritorno a capo

cyberhs:

   tft.setCursor(25,25);

tft.setTextSize(2); // Dimensione testo
  tft.setTextColor(RED); // Colore del testo
  Serial.print(" Requesting temperatures..."); //DEBUG
  sensors.requestTemperatures(); //invia comando per prendere il dato della temperatura
  Serial.println("DONE");
  Serial.print("Temperature for Device 1 is: ");
  temp1b = sensors.getTempCByIndex(0);
  Serial.print(temp1b, 1);
  tft.print(temp1b, 1); // senza ritorno a capo
  tft.print("  "); // senza ritorno a capo

Devi invertire l'operazione di scrittura e "pulizia"

[...]
  tft.print("  "); // senza ritorno a capo <-- Cancelli la precedente scrittura con spazi sufficienti
  tft.print(temp1b, 1); // senza ritorno a capo

Devi invertire l'operazione di scrittura e "pulizia"

Facendo come dici, potrebbe esserci comunque un effetto flash.

Ciao a tutti,innanzitutto grazie dell'aiuto.

cyberhs:

   tft.setCursor(25,25);

tft.setTextSize(2); // Dimensione testo
  tft.setTextColor(RED); // Colore del testo
  Serial.print(" Requesting temperatures..."); //DEBUG
  sensors.requestTemperatures(); //invia comando per prendere il dato della temperatura
  Serial.println("DONE");
  Serial.print("Temperature for Device 1 is: ");
  temp1b = sensors.getTempCByIndex(0);
  Serial.print(temp1b, 1);
  tft.print(temp1b, 1); // senza ritorno a capo
  tft.print("  "); // senza ritorno a capo

Purtroppo questa soluzione non ha portato nessun beneficio: nel quadrante,i caratteri della temperatura aggiornata si sovrappongono a quella vecchia creando la "macchia di colore".

CoreZilla:
Devi invertire l'operazione di scrittura e "pulizia"

[...]

tft.print("  "); // senza ritorno a capo <-- Cancelli la precedente scrittura con spazi sufficienti
  tft.print(temp1b, 1); // senza ritorno a capo

Questa soluzione mi stampa nel quadrante la prima temperatura,poi spostata di qualche carattere la seconda temperatura aggiornata,anche questa a sovrapporsi.

  temp1b = sensors.getTempCByIndex(0);
   
   tft.setTextSize(2); // Dimensione testo
   tft.setTextColor(RED); // Colore del testo
   tft.setCursor(25,25);
   tft.print(temp1b, 1); // senza ritorno a capo
   tft.setCursor(25,25);
   tft.print("  "); // senza ritorno a capo - La lunghezza della stringa di spazi >= del valore scritto

Prova questo modo brutale ..

(che librerie stai usando?)

CoreZilla:

  temp1b = sensors.getTempCByIndex(0);

tft.setTextSize(2); // Dimensione testo
  tft.setTextColor(RED); // Colore del testo
  tft.setCursor(25,25);
  tft.print(temp1b, 1); // senza ritorno a capo
  tft.setCursor(25,25);
  tft.print("  "); // senza ritorno a capo - La lunghezza della stringa di spazi >= del valore scritto




Prova questo modo brutale ..

(che librerie stai usando?)

Avevo già provato questa soluzione ma purtroppo non funziona,sembra non avere effetto.
Uso le librerie grafiche di adafruit.
Appena arrivo a casa le posto

   temp1b = sensors.getTempCByIndex(0);
   
   tft.setTextSize(2); // Dimensione testo
   tft.setTextColor(RED, BLACK); // Colore del testo + background
   tft.setCursor(25,25);
   tft.print(temp1b, 1); // senza ritorno a capo
   tft.setTextColor(RED, BLACK); // Colore del testo + background <- RINDONDANTE ????
   tft.setCursor(25,25);
   tft.print("--------"); // senza ritorno a capo - La lunghezza della stringa di spazi >= del valore scritto

Prova a usare la versione con il BACKGROUND e sostituisci gli spazi con '-' per vedere se dove inizia a scrivere o meno.

CoreZilla:

   temp1b = sensors.getTempCByIndex(0);

tft.setTextSize(2); // Dimensione testo
  tft.setTextColor(RED, BLACK); // Colore del testo + background
  tft.setCursor(25,25);
  tft.print(temp1b, 1); // senza ritorno a capo
  tft.setTextColor(RED, BLACK); // Colore del testo + background <- RINDONDANTE ????
  tft.setCursor(25,25);
  tft.print("--------"); // senza ritorno a capo - La lunghezza della stringa di spazi >= del valore scritto




Prova a usare la versione con il BACKGROUND e sostituisci gli spazi con '-' per vedere se dove inizia a scrivere o meno.

Allora,le librerie che uso sono
#include <Adafruit_GFX.h> // Libreria grafiche
#include <Adafruit_TFTLCD.h> // Libreria LCD
#include <OneWire.h> // Librerie delle sonde
#include <DallasTemperature.h> // di temperatura

Il comportamento che ha ora è questo:

VIDEO

Da notare che ora la temperatura non viene aggiornata,si fissa sul primo valore utile e poi non la legge piu'.

Ciao,

forse potresti provare a cancellare solo il contenuto del rettangolo senza cancellare il suo bordo.

Tu facevi:

   tft.drawRect(20,20,80,60,RED);
   tft.fillRect(20,20,80,60,colInterno); //non ci siamo....

prova a disegnare invece il rettangolo un volta per tutte (fuori dalle iterazioni di aggiornamento) usando la drawRect e poi ad aggiornare solo l'interno ad ogni iterazione usando la fillRect:

   tft.fillRect(21,21,78,58,colInterno);

Ho supposto che il bordo abbia 1 px di spessore e che i parametri della fillRect siano rispettivamente coordinate x, y e larghezza, altezza del rettangolo.

Ciao.
Vittorio.

vittorio68:
Ciao,

forse potresti provare a cancellare solo il contenuto del rettangolo senza cancellare il suo bordo.

Tu facevi:

   tft.drawRect(20,20,80,60,RED);

tft.fillRect(20,20,80,60,colInterno); //non ci siamo....




prova a disegnare invece il rettangolo un volta per tutte (fuori dalle iterazioni di aggiornamento) usando la drawRect e poi ad aggiornare solo l'interno ad ogni iterazione usando la fillRect:



tft.fillRect(21,21,78,58,colInterno);




Ho supposto che il bordo abbia 1 px di spessore e che i parametri della fillRect siano rispettivamente coordinate x, y e larghezza, altezza del rettangolo.

Ciao.
Vittorio.

Ciao Vittorio,grazie del suggerimento.
Modificando la parte del codice in questo modo:

sensors.requestTemperatures();
   temp1b = sensors.getTempCByIndex(0);
   
   tft.setTextSize(2); // Dimensione testo
   tft.setTextColor(RED, YELLOW); // Colore del testo + background
   tft.setCursor(25,25);
   tft.fillRect(21,21,78,58,colInterno);
   tft.print(temp1b); // senza ritorno a capo
   Serial.println(temp1b);

Ho ottenuto un netto miglioramento,il flash rimane ma da meno fastidio e permette di leggere la temperatura.
Per minimizzare ancora di più il flash sto pensando di : leggere la variabile temp1b,dividere la parte a sinistra della virgola e quella a destra ed effettuare 2 controlli: se quella a destra varia,allora fillrect solo sulla metà destra del rettangolo,altrimenti se quella sinistra varia faccio fillrect su tutto il rettangolo.
Sapete se float ha un metodo che permette di fare questo?
Per spiegarmi meglio,quello che voglio fare è l'equivalente del substring() su una stringa.
Grazie mille a tutti

OK, ho visto il video è tutto chiaro!

aggiungi la variabile temp1b_old e l'inizializzazione in setup()

void setup() {
   ...
  
   delay(1000); // Ritardo per avere una lettura valida
   temp1b_old = 0.0;

}

e modifichi il loop (dichiara la var unsigned long TempoPrecedente=0;) e

var unsigned long TempoPrecedente=0;
#define INTERVALLO 1000 //controllo la temperatura ogni secondo

[...]

   

   if (if (millis() - TempoPrecedente > INTERVALLO) {
      temp1b = sensors.getTempCByIndex(0);
      TempoPrecedente = millis();

     if (temp1b_old != temp1b ) {   // aggiorno solo se il nuovo valore è diverso
       tft.setTextSize(2); // Dimensione testo
       tft.setTextColor(RED, BLACK); // Colore del testo + background
       tft.setCursor(25,25);   
       tft.print(temp1b, 1); // senza ritorno a capo
       temp1b_old = temp1b; 
     }
  }

minimanimo:
Per minimizzare ancora di più il flash sto pensando di : leggere la variabile temp1b,dividere la parte a sinistra della virgola e quella a destra

In pratica vuoi la parte intera e la parte decimale del numero...

float parteIntera = (int)temp1b;
float parteDecimale = temp1b - parteIntera;

Mi è venuto in mente anche che in effetti il rettangolo disegnato intorno al valore è molto più grande del numero (presumo per ragioni estetiche...). Potresti anche provare a ridurre le dimensioni della fillRect allo stretto necessario per cancellare il numero. In questo modo probabilmente l'esecuzione della fillRect avviene in un tempo leggermente inferiore sufficiente però a ridurre la percezione dello sfarfallio.

Ciao.
Vittorio.

Il flash è dato dal continuo scrivere sul display .....