Notifications
Clear all

[Solved] Text flickering on ILI9341 TFT Displays

7 Posts
4 Users
4 Reactions
5,617 Views
Zoltar358
(@zoltar358)
Member
Joined: 4 years ago
Posts: 4
Topic starter  

Hello,

I am struggling with text flickering on my TFT display. Especially when I try to display sensor data in the loop.

Perhaps you know a good way to avoid flickering. Please make a video about that.


   
Quote
codecage
(@codecage)
Member Admin
Joined: 6 years ago
Posts: 1048
 

@zoltar358

Not sure that this issue is worthy of a video to explain.  So perhaps these two posts should be moved to a more appropriate thread.

While I have not used the exact display you mention, the displays I have used can have a "flicker" issue if you are writing to them more often than needed.  This is a programming issue that I have used a variable to determine if the data to be displayed has changed since the last time I wrote information to the display and if the data hasn't changed then no write occurs.  Only write when needed.  This has worked fairly well fo the displays I have used, but don't know if it will for sure solve your issue.

As you can now see these two posts have been move to a more appropriate thread.  Please do not take the fact that it got moved as you have done something wrong on the forum!  I myself still struggle from time to time in trying to decide the best place to post a comment.

And this could still not be the "best" place for this topic.  But "Components and Programming -- I/O Devices - Sensors - Modules" seemed like a good fit.

SteveG


   
ReplyQuote
(@yurkshirelad)
Member
Joined: 4 years ago
Posts: 498
 

Do TFT displays have a specified "refresh rate"? I.e. how long it takes for it to update the display and the time until it's ready to be updated again?


   
ReplyQuote
Zoltar358
(@zoltar358)
Member
Joined: 4 years ago
Posts: 4
Topic starter  

@yurkshirelad

I couldn't find any info about refresh rates, but I suspect they must have some response time.


   
YurkshireLad reacted
ReplyQuote
Zoltar358
(@zoltar358)
Member
Joined: 4 years ago
Posts: 4
Topic starter  

In the meantime I found a solution to my problem. TFT_eSPI library includes Sprite.h extension.

TFT_eSPI tft = TFT_eSPI(); // Invoke TFT library
TFT_eSprite spr = TFT_eSprite(&tft); // Invoke Sprite class

I have just used spr.drawString(STRING, 115, 67); and flickering is gone.

Here is my entire sketch, for those interested:

 

/*

Clock-Temp-Humid-TFT-ESP32

==========================

Displays current date and time using ntp sync via internal WI-FI.

Measures temperature and humidity using DHT22 sensor.

Data is displayed on KMRTM28028-SPI - 2.8" TFT SPI 240x320.

Data is also sent to Blynk.

Also, a LED is added to play with Blynk on smartphone.

Circuit:

Humidity & temperature sensor/module DHT22

1) + --> ESP32 +5V

2) OUT --> ESP32 26

3) GND --> ESP32 GND

2.8' TFT SPI 240*320:

1) VCC --> ESP32 +3.3V

2) GND --> ESP32 GND

3) CS --> ESP32 15

4) RESET --> ESP32 4

5) D/C --> ESP32 2

6) SDI (MOSI) --> ESP32 23

7) SCK --> ESP32 18

8) LED --> ESP32 +3.3V

9) SDO (MISO) --> ESP32 19

10) T_CLK --> SCK --> ESP32 18

11) T_CS --> ESP32 21

12) T_DIN --> SDI (MOSI) --> ESP32 23

13) T_OUT --> SDO (MISO) --> ESP32 19

14) T_IRQ --> not connected

Capacitor:

ESP32 CN --> Capacitor --> GND // No need to press Boot button to upload sketch

LED:

ESP32 13 --> 1kΩ resistor --> GND // For fun. Turn LED on/off with Blynk app on smartphone

Created: 2021-01-11 by Zoltar358.

Modified: 2021-01-22 by Zoltar358.

Compiled and tested with VS-Code (PlatformIO) on ESP32-WROOM-32D.

https://www.aliexpress.com/item/4001050278803.html // Or just search for ESP32-WROOM-32D

Special thanks to XTronical for his video

on how to wire up ILI9341 TFT LCD to ESP32.

Give him some love and subscribe to his YouTube channel.

https://www.xtronical.com

https://youtu.be/rq5yPJbX_uk

*/

#include "Arduino.h" // Required by PlatformIO

#include "WiFi.h" // WiFi library

#include <WiFiClient.h> // WiFi Client library

#include <BlynkSimpleEsp32.h> // Blynk library

#include "Time.h" // Time library

#include "Wire.h" // Wire library

#include "DHTesp.h" // DHT Temperature and Humidity Sensor

#include "SoftwareSerial.h" // Serial library

#include "TFT_eSPI.h" // Hardware-specific library for TFT display

#include "auth.h" // Credentials (in seperate auth.h file)

// const char *ssid = "SSID";

// const char *password = "PASSWORD";

// char auth[] = "BLYNK_AUTH_TOKEN";

// const char *ntpServer = "pool.ntp.org";

DHTesp dht; // Invoke DHTesp

// Define fonts

#define FF21 FreeSansBold9pt7b // Free Sans Bold 9pt

#define FF22 FreeSansBold12pt7b // Free Sans Bold 12pt

#define FF23 FreeSansBold18pt7b // Free Sans Bold 18pt

#define FF24 FreeSansBold24pt7b // Free Sans Bold 24pt

#define TFT_DARKNAVY 0x0004 // Backround color

TFT_eSPI tft = TFT_eSPI(); // Invoke TFT library

TFT_eSprite spr = TFT_eSprite(&tft); // Invoke Sprite class

const long gmtOffset_sec = 3600; // Offset for Europe/Warsaw (GMT+1)

const int daylightOffset_sec = 3600; // Daylight offset for Europe/Warsaw (GMT+1)

unsigned long targetTime = 0;

void plotCalendar() // Function to draw calendar data

{

struct tm timeinfo;

if (!getLocalTime(&timeinfo)) // Check if time is set

{

String errorMessage = "Failed to obtain time"; // Error message to variable

tft.setTextColor(TFT_YELLOW, TFT_DARKNAVY); // Set text color and background

tft.setFreeFont(&FF21); // Set font

tft.drawString(errorMessage, 115, 8); // Print error message

return; // Return to main

}

char weekDay[9]; // Define char for weekDay value

char fullYear[11]; // Define char for fullYear value

char fullTime[9]; // Define char for fullTime value

strftime(weekDay, 9, "%A", &timeinfo); //

strftime(fullYear, 11, "%F", &timeinfo); // Configure display formats

strftime(fullTime, 9, " %R ", &timeinfo); //

spr.setTextColor(TFT_GREEN, TFT_DARKNAVY); // Set text color and background

spr.setFreeFont(&FF23); // Set font

spr.drawString(weekDay, 115, 6); // Print weekDay

spr.setTextColor(TFT_LIGHTGREY, TFT_DARKNAVY); // Set text color and background

spr.setFreeFont(&FF22); // Set font

spr.drawString(fullYear, 115, 40); // Print fullYear

spr.setTextColor(TFT_ORANGE, TFT_DARKNAVY); // Set text color and background

spr.setFreeFont(&FF23); // Set font

spr.drawString(fullTime, 115, 67); // Print fullTime

}

void plotTemperature() // Function to draw temperature data

{

float temperature = dht.getTemperature(); // Get temperature value from sensor

Blynk.virtualWrite(V5, temperature); // Send temperature value to Blynk virtual pin V5

String celcius = " C"; // Define Celsius unit

String fahrenheit = " F"; // Define Fahrenheit unit

String kelvin = " K"; // Define Kelvin unit

spr.setFreeFont(&FF22); // Set font

spr.setTextColor(TFT_GREEN, TFT_DARKNAVY); // Set text color and background

spr.drawString("TEMPERATURE", 115, 7, 4); // Print title

spr.setTextColor(TFT_ORANGE, TFT_DARKNAVY); // Set text color and background

char bufT[6]; // Define char for Celcius temperature value

dtostrf(temperature, 2, 1, bufT); // Convert Celsius temperature value to string

strcat(bufT, celcius.c_str()); // Add Celsius sign to temperature value

spr.setFreeFont(&FF23); // Set font

spr.drawString(bufT, 115, 35); // Print temperature value

float temperatureF = dht.toFahrenheit(temperature); // Convert Celsius to Fahrenheit

spr.setTextColor(TFT_DARKGREY, TFT_DARKNAVY); // Set text color and background

char bufTF[7]; // Define char for Fahrenheit temperature value

dtostrf(temperatureF, 2, 2, bufTF); // Convert Fahrenheit temperature value to string

strcat(bufTF, fahrenheit.c_str()); // Add Fahrenheit sign to temperature value

spr.setFreeFont(&FF22); // Set font

spr.drawString(bufTF, 56, 71); // Print Fahrenheit temperature value

float temperatureK = temperature + 273.15; // Convert Celsius to Kelvin

spr.setTextColor(TFT_DARKGREY, TFT_DARKNAVY); // Set text color and background

char bufTK[7]; // Define char for Kelvin temperature value

dtostrf(temperatureK, 2, 2, bufTK); // Convert Kelvin temperature value to string

strcat(bufTK, kelvin.c_str()); // Add Kelvin sign to temperature value

spr.setFreeFont(&FF22); // Set font

spr.drawString(bufTK, 170, 71); // Print Kelvin temperature value

}

void plotHumidity() // Function to draw humidity data in desired position

{

float humidity = dht.getHumidity(); // Get humidity value from sensor

Blynk.virtualWrite(V6, humidity); // Send humidity value to Blynk virtual pin V6

String percent = "%"; // Define percent sign (%)

spr.setFreeFont(&FF22); // Set font

spr.setTextColor(TFT_GREEN, TFT_DARKNAVY); // Set text color and background

spr.drawString("HUMIDITY", 115, 20, 4); // Print title

char bufH[5]; // Define char for humidity value

dtostrf(humidity, 2, 1, bufH); // Convert humidity value to string

strcat(bufH, percent.c_str()); // Add percent sign to humidity value

spr.setFreeFont(&FF23); // Set font

spr.setTextColor(TFT_ORANGE, TFT_DARKNAVY); // Set text color and background

// spr.setTextPadding(120); // Set text padding to avoid overlapping

spr.drawString(bufH, 115, 50); // Print humidity value

}

void setup() // Setup (runs only once)

{

Serial.begin(115200); // Initialize serial port

Blynk.begin(auth, ssid, password); // Connect to Blynk

tft.init(); // Initialize TFT display

tft.setRotation(2); // Set rotation to portrait

tft.fillScreen(TFT_RED); // Fill screen red

tft.fillRect(0, 122, 239, 3, TFT_RED); // Draw red horizontal line

tft.fillRect(0, 245, 239, 3, TFT_RED); // Draw red horizontal line

spr.setTextDatum(1); // Set text alignment: center

dht.setup(26, DHTesp::DHT22); // Connect DHT sensor to GPIO 26

Serial.printf("Connecting to %s ", ssid); // Print connection message on serial monitor

WiFi.begin(ssid, password); // Connect to WiFi

while (WiFi.status() != WL_CONNECTED) // Check if connection is established

{

delay(500); // Set delay to 0.5s

Serial.print("."); // Print dots on serial monitor until connection is established

}

Serial.println(); // Print empty line on serial monitor

Serial.println("Connected to Wi-Fi"); // Inform about established connection on serial monitor

configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); // Initialize and get the time

targetTime = millis() + 1000;

//WiFi.disconnect(true); // Disconnect from WiFi

//WiFi.mode(WIFI_OFF); // Switch WiFi module off

}

void loop() // Loop (runs continuosly)

{

Blynk.run(); // Run Blynk applet

delay(dht.getMinimumSamplingPeriod()); // Delay before getting sensor data

if (targetTime < millis()) {

targetTime = millis() + 100;//10000;

spr.createSprite(230, 100); // Create sprite

spr.fillSprite(TFT_DARKNAVY); // Fill sprite area with (TFT_DARKNAVY)

plotCalendar(); // Draw calendar section

spr.pushSprite(5, 5); // Push sprite to its position

spr.createSprite(230, 100); // Create sprite

spr.fillSprite(TFT_DARKNAVY); // Fill sprite area with (TFT_DARKNAVY)

plotTemperature(); // Draw temperature section

spr.pushSprite(5, 110); // Push sprite to its position

spr.createSprite(230, 100); // Create sprite

spr.fillSprite(TFT_DARKNAVY); // Fill sprite area with (TFT_DARKNAVY)

plotHumidity(); // Draw humidity section

spr.pushSprite(5, 215); // Push sprite to its position

}

}

// #################################### EOF ####################################

 

 


   
wwjd777 and YurkshireLad reacted
ReplyQuote
wwjd777
(@wwjd777)
Member
Joined: 3 years ago
Posts: 20
 

@zoltar358 Wow, thank you for sharing your sketch!  I became a member of this forum to thank you for that.  I had much trouble getting the TFT_ESPI library running on platformio but it's working now. 🙂

You use the Sprite option which seems great!  I hope to adapt it for my use and your sketch is a great help as an example how to implement it.

 


   
ReplyQuote
Zoltar358
(@zoltar358)
Member
Joined: 4 years ago
Posts: 4
Topic starter  

@wwjd777 I'm glad to be helpful. Honestly, I did not expect that kind of response. Well, I did not expect any response... It was a nice surprise 🙂

Have fun with coding. Cheers!


   
wwjd777 reacted
ReplyQuote