Affichage écran tft

Bonjour,
je commence à utiliser un écran TFT.
Mon problème est de savoir si il est possible d'avoir un rafraichissement instantané.
Car actuellement , ce n'est pas joli à voir.
Voici mon programme

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C
unsigned long delayTime;

#include <SPI.h>
#include "Adafruit_GFX.h"
#include "Adafruit_HX8357.h"

#ifdef ESP32
   #define STMPE_CS 32
   #define TFT_CS   15
   #define TFT_DC   33
   #define SD_CS    14
#endif


#define TFT_RST -1

// Use hardware SPI and the above for CS/DC
Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, TFT_RST);


void setup() {
  Serial.begin(115200);
  
    while(!Serial);    // time to get serial running
    Serial.println(F("BME280 test"));
    unsigned status;
    status = bme.begin();  
     if (!status) {
        Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
        Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
        Serial.print("        ID of 0x60 represents a BME 280.\n");
        while (1) delay(10);
    }    
    Serial.println("-- Default Test --");
    delayTime = 1000;
    Serial.println();

  
  Serial.println("HX8357D Test!"); 
  tft.begin();

  // read diagnostics (optional but can help debug problems)
  uint8_t x = tft.readcommand8(HX8357_RDPOWMODE);
  Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(HX8357_RDMADCTL);
  Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(HX8357_RDCOLMOD);
  Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(HX8357_RDDIM);
  Serial.print("Image Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(HX8357_RDDSDR);
  Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX); 
  
  Serial.println(F("Benchmark                Time (microseconds)"));

  Serial.println(F("Done!"));
}


void loop(void) {

   Serial.print("Temperature = ");
   Serial.print(bme.readTemperature());
   Serial.println(" °C");

  tft.setRotation(1);
  tft.fillScreen(HX8357_WHITE);
  
  tft.setCursor(0,25);
  tft.setTextColor(HX8357_BLUE);
  tft.setTextSize(3);
  tft.println("Temperature :");
  tft.setCursor(0, 50);
  tft.setTextColor(HX8357_BLUE);
  tft.setTextSize(3);
  tft.println(bme.readTemperature());
  
  tft.setCursor(300, 175);
  tft.setTextColor(HX8357_GREEN);
  tft.setTextSize(3);
  tft.println("Humidite :");
  tft.setCursor(300, 200);
  tft.setTextColor(HX8357_GREEN);
  tft.setTextSize(3);
  tft.println(bme.readHumidity());

  delay(5000);
  


}

Vous remerciant

Quel type d'écran TFT utilisez-vous ?

Définissez pas joli…

Adafruit GFX Library | Adafruit 3.5" 480x320 TFT FeatherWing | Adafruit Learning System
En gros j'affiche les valeurs de mon capteur,
Moi j'aimerais que ça soit instantané les changements de valeur.
Avec mon programme j'ai du mettre un delay. Si j'en mettais pas l'image clignotais.

L’image clignote parce que vous re-ecrivez tout… il ne faut repeindre que ce que vous modifiez

D'accord , savez vous comment je peux faire pour faire celà ?
Je dois faire des boucles ?

la loop() suffit comme boucle généralement
pour rafraichir uniquement ce qui a changé, il faut conserver en mémoire l'ancienne valeur et faire un truc du genre

if (nouvelleValeur != ancienneValeur) {
  effacerLaZoneDeCetteValeur(); // par exemple récrire l'ancienne valeur avec la couleur de fond ou dessiner un rectangle plein sur la zone englobante
  ecrireLaNouvelleValeur();
  ancienneValeur = nouvelleValeur;
}

Slt désolé de l'absence, ducoup je comprend pas trop ce que tu me dit :
j'ai fait ça : if (bme.readTemperature() != bme.readTemperature()) { effacerLaZoneDeCetteValeur(); // par exemple récrire l'ancienne valeur avec la couleur de fond ou dessiner un rectangle plein sur la zone englobante ecrireLaNouvelleValeur(); ancienneValeur = nouvelleValeur; } Je ne comprend pas ce que je dois mettre dans les autres case, ça te dérangerait de me faire un exemple ?
Vous remerciant

Quelqu'un pourrait me guider ducoup ?

Il y a la fonction

  virtual void fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
                        uint16_t color);

qui permet de colorier un rectangle. Si tu lui passes la couleur du fond (peut-être du blanc) en dernier argument, ça revient à effacer ce qui se trouve dans le zone de ce rectangle.

Ensuite, il y a cette fonction

  void getTextBounds(const String &str, int16_t x, int16_t y, int16_t *x1,
                     int16_t *y1, uint16_t *w, uint16_t *h);

qui normalement te donne les dimensions et position du rectangle dans lequel tu écris un texte (contenu dans la String en argument). Je connais mal cette fonction, mais utiliser les deux permet d'effacer la zone autour d'un texte.

Je pense que tu lui donnes le texte (str) et sa position (coin en haut à gauche aux coordonnées x et y) et elle te renvoie les valeurs de taille (width w et heigth h) et position (x1, y1) du rectangle qui englobe ton texte si tu l'écrivais à cet endroit (selon la police et sa taille).
Tu peux alors passer ces valeurs dans fillRect directement, avec la couleur du fond pour effacer la zone.

... A tester ...

Plus d'infos ici :

To replace previously-drawn text when using a custom font, either:

  • Use getTextBounds() to determine the smallest rectangle encompassing a string, erase the area using fillRect(), then draw new text:

int16_t x1, y1; uint16_t w, h; tft.getTextBounds(string, x, y, &x1, &y1, &w, &h);

getTextBounds expects a string, a starting cursor X&Y position (the current cursor position will not be altered), and addresses of two signed and two unsigned 16-bit integers. These last four values will then contain the upper-left corner and the width & height of the area covered by this text — these can then be passed directly as arguments to fillRect().

Avec la librairie GFX, si la couleur de fond est définie et qu'elle est différente de la couleur du texte le fond est effacé automatiquement lorsqu'on fait un print.
Si on utilise une police à chasse fixe je pense que cela fonctionne correctement par contre si on utilise une police proportionnelle je ne sais pas ce qu'il se passe car les chaînes n'ont pas toujours la même taille (je ne sais même pas si c'est géré dans ce mode).
Il faut utiliser

setTextColor(uint16_t c, uint16_t bg)

à la place de

setTextColor(uint16_t c)

J'ai toujours le même problème, si je met pas de delay l'écran s'actualise en permanence donc clignote,
Ce que je souhaite, c'est que l'écran ne s'actualise plus mais simplement les valeurs de ma température.
Je vous ai peut être mal compris
Voici mon programme :

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C
unsigned long delayTime;

#include <SPI.h>
#include "Adafruit_GFX.h"
#include "Adafruit_HX8357.h"

#ifdef ESP32
   #define STMPE_CS 32
   #define TFT_CS   15
   #define TFT_DC   33
   #define SD_CS    14
#endif


#define TFT_RST -1

// Use hardware SPI and the above for CS/DC
Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, TFT_RST);


void setup() {
  Serial.begin(57600);
  
    while(!Serial);    // time to get serial running
    Serial.println(F("BME280 test"));
    unsigned status;
    status = bme.begin();  
     if (!status) {
        Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
        Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
        Serial.print("        ID of 0x60 represents a BME 280.\n");
        while (1) delay(10);
    }    
    Serial.println("-- Default Test --");
    delayTime = 1000;
    Serial.println();

  
  Serial.println("HX8357D Test!"); 
  tft.begin();

  // read diagnostics (optional but can help debug problems)
  uint8_t x = tft.readcommand8(HX8357_RDPOWMODE);
  Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(HX8357_RDMADCTL);
  Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(HX8357_RDCOLMOD);
  Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(HX8357_RDDIM);
  Serial.print("Image Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(HX8357_RDDSDR);
  Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX); 
  
  Serial.println(F("Benchmark                Time (microseconds)"));

  Serial.println(F("Done!"));
}


void loop(void) {

   Serial.print("Temperature = ");
   Serial.print(bme.readTemperature());
   Serial.println(" °C");

  tft.setRotation(1);
  tft.fillScreen(HX8357_WHITE);
  
  tft.setCursor(0,25);
  tft.setTextColor(HX8357_BLUE);
  tft.setTextSize(3);
  tft.println("Temperature :");
  tft.setCursor(0, 50);
  tft.setTextColor(HX8357_BLUE);
  tft.setTextSize(3);
  tft.println(bme.readTemperature());
  
  tft.setCursor(300, 175);
  tft.setTextColor(HX8357_GREEN);
  tft.setTextSize(3);
  tft.println("Humidite :");
  tft.setCursor(300, 200);
  tft.setTextColor(HX8357_GREEN);
  tft.setTextSize(3);
  tft.println(bme.readHumidity());

  delay(5000);
  


}

Ceci doit aller dans le setup

Ca aussi ça va dans le setup
Et ça aussi :

Pas besoin de le faire plusieurs fois, si tu ne changes jamais la taille : fais le une fois pour toutes au début, dans le setup

Enfin, je pense que la lecture du capteur n'est pas très rapide. Or tu lis d'abord la température puis l'humidité mais tu affiches des choses entre les deux.
Réorganise ton code :

  • Lecture température, humidité
  • Comparer avec les valeurs précédentes
  • Si pas de changement, ne rien faire
  • Si changement, afficher la valeur ou les valeurs qui change(nt)
  • delay(5000)

Vraiment super sympa sur tous les côtés,
Je regarderai ça demain, merci

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