SCreen flickering in Arduino GC9A01 library

Hi I am using 1.28 inch tft display and pms with dht sensor. Can you tell why my screen flicker and how to remove the flickering? Does this display flicker like this? This is my code.:

#include <Adafruit_GFX.h>
#include <Adafruit_GC9A01A.h>
#include <Fonts/FreeSansBold12pt7b.h>
#include <Fonts/britanic55pt7b.h>
#include <PMS.h>
#include <DHT.h>

// Pin definitions for ESP32
#define TFT_CS 15  // Chip select control pin
#define TFT_DC 22  // Data Command control pin
#define TFT_RST 4  // Reset pin

// Display dimensions
const int DISPLAY_WIDTH = 240;
const int DISPLAY_HEIGHT = 240;

#define DHTPIN 5       // Pin for DHT sensor
#define DHTTYPE DHT11  // DHT 11

#include "robo.h"  // Bitmap image data

// Create instances
Adafruit_GC9A01A tft = Adafruit_GC9A01A(TFT_CS, TFT_DC, TFT_RST);
DHT dht(DHTPIN, DHTTYPE);
PMS pms(Serial1);
PMS::DATA data;

// Timing variables
const unsigned long imageDisplayDuration = 4000;  // Display image for 4 seconds
unsigned long lastUpdateTime = 0;
unsigned long lastSensorReadTime = 0;
unsigned long sensorReadInterval = 100; // Read sensor data every 100 milliseconds
bool showImage = true;

// Store previous values to avoid unnecessary screen updates
int lastPMSValue = -1;
float lastTemperature = -1;
float lastHumidity = -1;

// Forward declarations
void clearScreen(uint16_t color);
void displayImage();
void drawPMSDisplay(int pmsValue, float temperatureValue, float humidityValue);

void setup() {
  Serial.begin(115200);

  // Initialize the display
  tft.begin();
  tft.setRotation(4);  // Adjust rotation if needed

  // Initialize DHT sensor
  dht.begin();

  // Initialize PMS sensor
  Serial1.begin(9600, SERIAL_8N1, 26, 27);  // Adjust pins to your setup if necessary

  // Set PMS to active mode for continuous data updates
  pms.wakeUp();
  pms.passiveMode();

  // Display initial image
  displayImage();

  Serial.println("Setup complete, displaying image.");
}

void loop() {
  unsigned long currentTime = millis();

  if (showImage) {
    if (currentTime - lastUpdateTime >= imageDisplayDuration) {
      showImage = false;
      lastUpdateTime = currentTime;
      Serial.println("Image display duration complete, switching to PMS display.");
      clearScreen(GC9A01A_BLACK); // Clear the screen once before switching to sensor data
    }
  } else {
    if (currentTime - lastSensorReadTime >= sensorReadInterval) {
      lastSensorReadTime = currentTime;

      // Request data from PMS sensor
      pms.wakeUp();
      if (pms.readUntil(data)) {
        int pmsValue = data.PM_AE_UG_2_5;  // PM2.5 value from the PMS sensor
        Serial.print("PMS Value: ");
        Serial.println(pmsValue);

        float temperature = dht.readTemperature();
        float humidity = dht.readHumidity();

        if (isnan(temperature) || isnan(humidity)) {
          Serial.println("Failed to read from DHT sensor!");
          return;
        }

        // Only update the screen if the values have changed
        if (pmsValue != lastPMSValue || temperature != lastTemperature || humidity != lastHumidity) {
          drawPMSDisplay(pmsValue, temperature, humidity);

          lastPMSValue = pmsValue;
          lastTemperature = temperature;
          lastHumidity = humidity;
        }
      }

    }
  }
}

unsigned long lastClearTime = 0;
const unsigned long clearInterval = 50;  // Interval to wait for the screen update

void clearScreen(uint16_t color) {
  tft.fillScreen(color);
  lastClearTime = millis();  // Update the last clear time
}


void displayImage() {
  clearScreen(GC9A01A_WHITE);

  // Draw the bitmap image on the screen
  tft.drawBitmap(0, 0, robo, DISPLAY_WIDTH, DISPLAY_HEIGHT, GC9A01A_MAROON);

  // Update the last time check
  lastUpdateTime = millis();
}

void drawPMSDisplay(int pmsValue, float temperatureValue, float humidityValue) {
  // Clear only the area where the PMS value is displayed
  int centerX = DISPLAY_WIDTH / 2;
  int centerY = DISPLAY_HEIGHT / 2;

  // Set text properties
  tft.setTextColor(GC9A01A_WHITE);
  tft.setFont(&britanic55pt7b);

  // Calculate the position for the PMS value based on its number of digits
  int pmsXPos = centerX - 60;
  if (pmsValue >= 100) {
    pmsXPos = centerX - 95;
  } else if (pmsValue < 10) {
    pmsXPos = centerX - 30;
  }

  tft.fillRect(pmsXPos-30, centerY - 80, 200, 140, GC9A01A_BLACK);
  // Print the PMS value as a large number
  tft.setCursor(pmsXPos, centerY - 5);
  tft.print(pmsValue);

  // Draw a small line separating DHT and PMS values
  tft.drawLine(75, 126, DISPLAY_WIDTH - 65, 126, GC9A01A_WHITE);

  // Set font size for smaller text
  tft.setFont(&FreeSansBold12pt7b);

  // Print the temperature and humidity as integers
  tft.setCursor(centerX - 40, centerY + 27);
  tft.print((int)temperatureValue);
  tft.print("°C ");
  tft.print((int)humidityValue);
  tft.print("%");

  // Determine the color based on the PMS value
  uint16_t circleColor;
  if (pmsValue < 20) {
    circleColor = GC9A01A_GREEN;
  } else if (pmsValue >= 20 && pmsValue < 40) {
    circleColor = GC9A01A_YELLOW;
  } else {
    circleColor = GC9A01A_RED;
  }

  // Draw a small circle at the bottom of the screen
  tft.fillCircle(centerX, DISPLAY_HEIGHT - 40, 15, circleColor);

  // Draw a thicker circle towards the outer edge of the display
  int outerRadius = min(DISPLAY_WIDTH, DISPLAY_HEIGHT) / 2 - 10; // Adjust radius for outer placement
  int thickness = 7;  // Thickness of the circle

  // Draw multiple concentric circles for thickness
  for (int i = thickness; i > 0; i--) {
    tft.drawCircle(centerX, centerY, outerRadius + i, GC9A01A_WHITE);
  }
}

Your topic has been moved. Please do not post in "Uncategorized"; see the sticky topics in https://forum.arduino.cc/c/using-arduino/uncategorized/184.

It looks like you are clearing the whole screen to a background color. Have you tried clearing only the changed pixels? (text or graphic)

If text -

  1. store location of new text
  2. print the text
  3. store new text
  4. set old cursor location of old text
  5. print old text in background color.
  6. goto 1

if graphics

  1. store graphic, size and location
  2. print the graphic
  3. get new graphic, size, location
  4. clear old graphic, size, location
  5. goto 1