Greed for Speed

One of my first Arduino peripherals was this 3.5″ touchscreen from Adafruit. It has a 480×320 resolution, an SD card reader and two interfaces (SPI and 8-bit parallel).

However, after first connecting it to my Arduino Uno, this absolutely beautiful display turned out to be rather slow, even in parallel mode. Back then, there were no fast libraries for its HX8357D chip, so I soon bought a smaller 320×240 ili9341 display for projects that required fast graphics (fractals, cellular automata etc.). But I never stopped looking for a faster way to drive my 480×320 ‘Ferrari’.

New hope arose when ESP8266 entered the market, especially after ‘Bodmer’ added support for the HX8357D chip to his amazing TFT_eSPI library on Github. With the ESP8266’s clock speed set to 180 MHz, cellular automata now grew considerably faster, but still noticeably slower than on ili9341 displays (with half the amount of pixels, that is).

Then came ESP32. The cpu-hungry algorithms that generate complex graphics proved to run much faster on this dual core board. Finally, some of my math visualisations started looking acceptable on my beloved 480×320 display.

A decisive breakthrough was the arrival of the WROVER variant of ESP32. It came with PSRAM, more than enough for (multi) buffering a 480×320 display (4 MB, or even 8 MB on model B). Writing pixel values to a buffer in PSRAM first, and then push (part of) this buffer to the display in one transaction, is much faster than writing to individual pixels.

A welcome dessert was the speed gain after increasing the SPI frequency from 27 MHz to 40 MHz (a setting in the TFT_eSPI library’s user_setup.h file), which finally made my Adafruit display fully competitive. And, as the proverbial cherry on the cake, controlling it over its 8-bit parallel interface made it even faster again!

This video shows the display at top speed. If you’ve ever seen this standard graphic test on an Arduino Uno, you’ll know that I’ve made some progress here. My smartphone’s camera had some trouble filming the display (it even turned yellow into white…).

Benchmark sketch on an ESP32, driving the 480×320 display over its 8-bit parallel interface

Guess this is where my Speed Quest has its happy ending. Below are the benchmark results (in microseconds) for the 320×240 ili9341 and the 480×320 HX8357D displays, both driven by an ESP32 (LOLIN D32 Pro). Output is from the library’s graphicstest.ino sketch, running on a single core, without the use of display buffering.