Too Slow SPI TFT Screen

I'm controlling a 2.8 inch ILI9341 driven SPI_5P TFT screen breakout board. Most of the time I want to display large text on the screen and sometimes few images. I want the text to update based on sensor input but the screen prints pixel by pixel, it is really slow like 0.3 fps.

The full code:

#include <UTFT.h>

// Declare which fonts we will be using
extern uint8_t BigFont[];

UTFT myGLCD(ILI9341_S5P, 11, 13, 10, 12, 9); //(Model, SDA, SCL, CS, RST, Rs)

void setup() {
  // Setup the LCD
  myGLCD.InitLCD();
  myGLCD.setFont(BigFont);

  pinMode(8, OUTPUT);
  digitalWrite(8, HIGH); // For backlight
  myGLCD.clrScr();
}

void loop() {

  // Clear the screen and draw the frame
 // myGLCD.clrScr();

  myGLCD.setColor(255, 255, 255);
  myGLCD.print("Hello!", CENTER, 30);
  myGLCD.print("Look How Slow I Am", CENTER, 60);
  myGLCD.print("This is SPI_5P", CENTER, 120);
  myGLCD.print("Wanna get faster ", CENTER, 150);
  myGLCD.print("HEEELP!", CENTER, 180);

  delay(2000);

  myGLCD.setColor(0, 0, 0);
  myGLCD.print("Hello!", CENTER, 30);
  myGLCD.print("Look How Slow I Am", CENTER, 60);
  myGLCD.print("This is SPI_5P", CENTER, 120);
  myGLCD.print("Wanna get faster ", CENTER, 150);
  myGLCD.print("HEEELP!", CENTER, 180);
}

I tried both with UTFT and LCDWIKI libraries and they had the same speed. The demo plays really slow, clear screen command takes ages to wipe whole screen pixel by pixel. What am I doing wrong? I don't need super speed, 10 fps is enough. Maybe I couldn't use Hardware SPI and I am accidentally using software SPI. Because even though I connected reset pin to pin12 it doesn't interfere with SPI, I used other pins for reset and results didn't change. In hardware SPI maybe I shouldn't be able to use pin12 for other purposes and leave it floating.

Which Arduino are you using?

Arduino Pro Mini 3.3V 8MHZ

I'm connecting the screen from SPI pins (I use pin12 for reset but it works weirdly) although most of the libraries come with random pins as default. I don't understand why.

What does the library documentation say ?

On a Pro Mini when using hardware SPI you cannot specify which pins SCK, MOSI and MISO are on, they are fixed, which suggests the above config is for a software SPI instance.

All libraries I've seen (Adafruit, LCDWIKI, UTFT) define SPI pins in the example codes. In the manual I haven't seen anything about hardware SPI. If you have a working library I'm ready to switch to it.

My library: UTFT - Rinky-Dink Electronics

may be ILI9341_Fast coud help ?

You have paired a relatively high-resolution, colour LCD with a small, slow, limited memory Arduino.

The library you choose doesn't seem to have the ability to use hardware SPI, it is software only. The lower 8MHz speed of the Arduino makes that even slower.

The display would require a memory buffer too large for this model of Arduino, so all updates require a read from the display's memory followed by a write to update it, slowing things down even further.

You created a "perfect storm" of slowness!

The library suggested by @J-M-L will give improvement but I doubt it will reach 10 updates per second.

I think you need to consider upgrading the Arduino or downgrading the display.

2 Likes

Here is the setup of an Adafruit library for hardware SPI;

#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h" 

int8_t DISPCS = 10;                            
int8_t DISPDC = 8;

Adafruit_ILI9341 disp = Adafruit_ILI9341(DISPCS, DISPDC);

No definitions in sight for SCK, MOSI and MISO

1 Like

In terms of upgrading the Arduino, you need something with fast hardware SPI (which most do, but higher clocked Arduino will have higher maximum SPI speed), ideally with DMA to relieve the CPU of the burden of updating the display, and copious amounts of RAM and flash memory, to allow a full-frame buffer and storage for all your images.

The display is 320x240 with 2 bytes per pixel, so the RAM buffer would need to be over 150KB! The Pro Mini has 2KB, in case you didn't know.

Something based on RP2040 or ESP32 or a Teensy 4.0?

@J-M-L @PaulRB
ILI9341_Fast has an acceptable speed. I can print the previously printed text in black in order to delete thus I don't need to modify many pixels. Do you know any other tips to make it seem faster? I searched for the fastest libraries and I came across 3 more but I have problems.

https://github.com/Bodmer/TFT_ILI9341

https://github.com/XarkLabs/PDQ_GFX_Libs: Compile error "PDQ_GFX.h: No such file or directory"

https://github.com/PaulStoffregen/ILI9341_t3: I guess it doesn't work with Atmega328p because it gives complier error: "Sorry, ILI9341_t3 does not work with Teensy 2.0 or Teensy++ 2.0. Use Adafruit_ILI9341."

Do you have experience with these. Which one do you recommend me to use? I need speed-flash memory balance. So far Bodmer's library and Fast ILI9341 seems similar speed.

@srnet the image you showed is about flash memory not RAM but I learned that UTFT is slow so I dumped it anyway.

I don't have experience with those. If I need something to really go fast then I would adjust the MCU to take that into account

1 Like

I'm really surprised that it's achieving 10 FPS with an 8MHz Pro Mini! That's at least 30x faster than with that other library. How many FPS are you actually getting?

It is not 10 FPS definitely less but I don't need to update whole screen I can only update changed text so fps is virtually higher. I tried with 16MHZ Pro Mini supplied with 3.3V and it was twice as fast it was great, I need to update screen once every 5 seconds so I don't need tons of speed. Now I will decide weather I will risk reliability by using 16MHZ Arduino with 3.3V or I will use level shifters. In the future I will use other MCUs but for now I want to finish this project ASAP because I am bored of it.

My test code by using PDQ_GFX Library (printing is nearly instant, the fillScreen takes time only):

for (int i = 0; i<15; i++){
  tft.fillScreen(ILI9341_BLACK);
  tft.setCursor(0, 0);
	tft.print(F("Hello World"));
  tft.setCursor(0, 30);
  tft.print(F("Hello World"));
  tft.setCursor(0, 60);
  tft.print(F("Hello World"));
  tft.setCursor(0, 90);
  tft.print(F("Hello World"));
  tft.setCursor(0, 120);
  tft.print(F("Hello World"));
  tft.setCursor(0, 150);
  tft.print(F("Hello World"));
  tft.setCursor(0, 180);
  tft.print(F("Hello World"));
  tft.setCursor(0, 210);
  tft.print(F("Hello World"));
  tft.setCursor(0, 240);
  tft.print(F("Hello World"));
  tft.setCursor(0, 270);
  tft.println(F("Hello World"));
  }
 tft.print(millis());// 8MHZ: 6283ms, 16MHZ:  3204ms
 delay(2000);

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