/esp-idf-parallel-tft

8bit parallel TFT & 4-line resistance touch screen Driver for esp-idf using i2s paralell mode

Primary LanguageCMIT LicenseMIT

esp-idf-parallel-tft

8 bit parallel TFT & 4-line resistance touch screen Driver for esp-idf.
You can use such a TFT-Shield with esp32.

TFT-Shield

Support driver

Generic Shield

  • ILI9225
  • ILI9226(Same as ILI9225)
  • ILI9320
  • ILI9325
  • ILI9341
  • ILI9342
  • ILI9481
  • ILI9486
  • ILI9488
  • SPFD5408(Same as ILI9320)
  • R61505U(Same as ILI9320)
  • R61509V
  • LGDP4532
  • ST7775(Same as ILI9225)
  • ST7781
  • ST7783(Same as ST7781)
  • ST7793(Same as R61509)
  • ST7796(Same as ILI9486)
  • HX8347A(*2)
  • HX8347D(Almost the same as HX8347A)(*2)
  • HX8347G(Same as HX8347D)(*2)
  • HX8347I(Same as HX8347D)(*2)

OPEN-SMART Products

  • OPEN-SMART ILI9225 TFT-Shield(176x220)(*5)
  • OPEN-SMART ILI9327 TFT-Shield(240x400)(*3)(*5)
  • OPEN-SMART ILI9340 TFT-Shield(240x320)(*5)
  • OPEN-SMART S6D1121 16Pin-Parallel(240x320)(*1)(*5)
  • OPEN-SMART ST7775 16Pin-Parallel(176x220 Same as ILI9225)(*1)(*5)
  • OPEN-SMART ST7783 16Pin-Parallel(240x320)(*1)(*5)
  • OPEN-SMART R61509V 16Pin-Parallel(240x400)(*1)(*5)
  • OPEN-SMART ILI9488 16Pin-Parallel(320x400 Color inversion)(*1)(*4)(*5)

(*1)
I2S parallel does not work.
I don't know why.
GPIO parallel or REGISTER I/O parallel works.
LED pins connect to GND instead of 3.3V.

(*2)
Very Slow.
Most drivers require three commands to display one Pixel.
This driver require 9 commands to display one Pixel.
For some reason, the color of 0xFFFF does not appear.

(*3)
It has a GRAM offset.
See below.

(*4)
Need RGB inverstion.

(*5)
4-line resistance touch screen available.
See below.

These are all 2.4 inch, 320x240 TFTs. TFT-SHIELD-2

3.95 inches is almost twice as large as 2.4 inches. TFT-SHIELD-3

These are OPEN-SMART 16Pin-Parallel Products. OPEN-SMART-16Pin

Software requirements

esp-idf v4.4 or later.
The i2s driver for esp32s2 is supported.

Installation for ESP32

git clone https://github.com/nopnop2002/esp-idf-parallel-tft
cd esp-idf-parallel-tft/
idf.py set-target esp32
idf.py menuconfig
idf.py flash

Installation for ESP32-S2

git clone https://github.com/nopnop2002/esp-idf-parallel-tft
cd esp-idf-parallel-tft/
idf.py set-target esp32s2
idf.py menuconfig
idf.py flash

Note

  • tjpgd library does not exist in ESP32-S2 ROM. Therefore, the JPEG file cannot be displayed.
  • PNG file cannot be displayed because the SRAM is small.

Configuration

You have to set this config value with menuconfig.

  • CONFIG_DRIVER

    The information provided by sellers on Ebay or AliExpress is largely incorrect.
    You waste time if you don't choose the right driver.
    There are many variations of the 2.4 inch shield.
    You can use this to find out your driver.
    This is for Arduino UNO.
    Do not use this on the ESP32 as the GPIO on the ESP32 is not 5V tolerant.
    Never believe the seller's information.
  • CONFIG_INTERFACE
    Most drivers work using I2S parallel.
    However, some drivers only work using GPIO parallels or REGISTER I/O parallels.
    I2S parallel is the fastest when drawing to consecutive addresses.
    However, REGISTER I/O parallel is the fastest when drawing to non-contiguous addresses.
    When using REGISTER I/O parallel, GPIO from D0 to D7 is 1 to 31.(GPIO0 is boot mode pin)
    GPIO parallel is most slow.
  • CONFIG_WIDTH
  • CONFIG_HEIGHT
    Specifies the resolution of the TFT.
  • CONFIG_OFFSETX
  • CONFIG_OFFSETY
    You can specify the GRAM offset.
    You must specify Y offset = 32 for OPEN-SMART-ILI9327.
  • CONFIG_INVERSION
    For some TFTs, the BGR may be inverted.
    Specify if the colors are inverted.

config-menu

config-app1

config-app2

config-app4

Wireing

TFT ESP32 ESP32S2/S3
LDC_RST -- GPIO32 GPIO45 *1
LDC_CS -- GPIO33 GPIO42 *1
LDC_RS -- GPIO15 GPIO41 *1
LDC_WR -- GPIO4 GPIO40 *1
LDC_RD -- GPIO2 GPIO39 *1
LDC_D0 -- GPIO12 GPIO1 *1 *2
LDC_D1 -- GPIO13 GPIO2 *1 *2
LDC_D2 -- GPIO26 GPIO3 *1 *2
LDC_D3 -- GPIO25 GPIO4 *1 *2
LDC_D4 -- GPIO17 GPIO5 *1 *2
LDC_D5 -- GPIO16 GPIO6 *1 *2
LDC_D6 -- GPIO27 GPIO7 *1 *2
LDC_D7 -- GPIO14 GPIO8 *1 *2
5V -- 5V 5V *3
3.3V -- 3.3V 3.3V *3
GND -- GND GND

(*1)
You can change any GPIO using menuconfig.

config-app3

(*2)
When using REGISTER I/O parallel, GPIO from D0 to D7 is 1 to 31.(GPIO0 is boot mode pin)

(*3)
With a regulator (mostly AMS1117) is on the back, the supply voltage is 5V.
With a regulator is NOT on the back, the supply voltage is 3.3V.

Back

Note
My R61509V has a regulator on the back.
Normally, a TFT with a regulator works at 5V, but my R61509V doesn't work unless I supply both 5V and 3.3V.

Note
ESP32 development board cannot supply too much current.
It is more stable when supplied from an external power source.

All

Circuit

Graphic support

Graphic1 Graphic2 Graphic3 Graphic4 Graphic5 Graphic6 Graphic7 Graphic8

Fonts support

Font1 It's possible to text rotation and invert.
Font2 Font3 Font4 It's possible to indicate more than one font at the same time.
Font5

Image support

BMP file
Image1 JPEG file(ESP32 only)
Image2 PNG file(ESP32 only)
Image3

Using Wemos D1 ESP32

I bought this for $4.
WeMos-R32-11

I have changed some pin assignments.
Attached the TFT shield.
The TFT shield worked fine.
WeMos-R32-12

It's very smart.
WeMos-R32-13

WeMos-R32-1

WeMos-R32-2

WeMos-R32-3

WeMos-R32-4

If you use OPEN-SMART TFT-Shield Products, you have to use Custom GPIO.

WeMos-R32-OpenSmart

JPEG Decoder

The ESP-IDF component includes Tiny JPEG Decompressor.
The document of Tiny JPEG Decompressor is here.
This can reduce the image to 1/2 1/4 1/8.

PNG Decoder

The ESP-IDF component includes part of the miniz library, such as mz_crc32.
But it doesn't support all of the miniz.
The document of miniz library is here.

And I ported the pngle library from here.
This can reduce the image to any size.

Font File

You can add your original font file.
The format of the font file is the FONTX format.
Your font file is put in font directory.
Your font file is uploaded to SPIFFS partition using meke flash.

Please refer this page about FONTX format.

FontxFile yourFont[2];
InitFontx(yourFont,"/spiffs/your_font_file_name","");
uint8_t ascii[10];
strcpy((char *)ascii, "MyFont");
lcdDrawString(dev, yourFont, x, y, ascii, color);

4-line resistance touch screen

Some TFT has 4-line resistance touch screen.
The 4-line resistor touch screen uses 4 pins.

  • X(+):Digital Output
  • X(-):Digital Output/Analog Input
  • Y(+):Digital Output/Analog Input
  • Y(-):Digital Output

When using GPIO Parallel Interface or REGISTER Parallel Interface, you can enable 4-line resistance touch screen using menuconfig.

ESP-IDF cannot simultaneous both digital output and analog input using a single gpio.
Two GPIOs are required for simultaneous digital output and analog input.
(X-) and ESP32 are connected by two wires.
(Y+) and ESP32 are connected by two wires.

(X-) ----+---- Gpio for Digital Output(Using GPIO number)
         +---- Gpio for Analog Input(Using ADC1 Channel number)

(Y+) ----+---- Gpio for Digital Output(Using GPIO number)
         +---- Gpio for Analog Input(Using ADC1 Channel number)

OPEN-SMART 16Pin-Parallel Products

X(+) X(-) Y(+) Y(-)
LCD_D6 LCD_RS LCD_WR LCD_D7

Touch0 config-touch-open-smart

  • ADC Channel
    When reading analog values, ESP-IDF can use ADC1 and ADC2.
    This project use ADC1 to read analog value.
    ESP32 has 8 channels: GPIO32 - GPIO39.
    ESP32S2 has 10 channels: GPIO01 - GPIO10.
    Refer to the ESP32 data sheet for the relationship between ADC channels and GPIOs.

  • Touch position accuacy
    The coordinates read from Y(+) and X(-) are analog values.
    The difference between the coordinates read last time and the coordinates read this time is determined, and if it is within this range, it is regarded as a valid coordinate.
    Decreasing this value will make the position more accurate, but less responsive.
    Increasing this value will make the position more inaccurate but more responsive.

When using ADC1_6(ADC1 Channel#6) and ADC1_7(ADC1 Channel#7), the following wiring is additionally required.

TFT ESP32 ESP32S2
LCD-WR(Y+) ADC1_6(GPIO34) ADC1_6(GPIO07)
LCD-RS(X-) ADC1_7(GPIO35) ADC1_7(GPIO08)

OPEN-SMART TFT-Shield Products

There is no marking about 4-line resistance touch screen.
But 4-line resistance touch screen available.

X(+) X(-) Y(+) Y(-)
LCD_D6 LCD_RS LCD_WR LCD_D7

Touch-OpenSmart-Sheild-1 config-touch-open-smart

When using ADC1_6(ADC1 Channel#6) and ADC1_7(ADC1 Channel#7), the following wiring is additionally required.

TFT ESP32 ESP32S2
LCD_WR(Y+) ADC1_6(GPIO34) ADC1_6(GPIO07)
LCD_RS(X-) ADC1_7(GPIO35) ADC1_7(GPIO08)

4-line resistance touch screen cannot be used with the Wemos D1 ESP32.
Because LCD_WR (GPIO4) is ADC2_0.

ELEGOO TFT-Shield Products

There is no marking about 4-line resistance touch screen.
But 4-line resistance touch screen available.

X(+) X(-) Y(+) Y(-)
LCD_D0 LCD_RS LCD_CS LCD_D1

Touch-Elegoo-1 config-touch-elegoo

When using ADC1_6(ADC1 Channel#6) and ADC1_7(ADC1 Channel#7), the following wiring is additionally required.

TFT ESP32 ESP32S2
LCD_CS(Y+) ADC1_6(GPIO34) ADC1_6(GPIO07)
LCD_RS(X-) ADC1_7(GPIO35) ADC1_7(GPIO08)

No additional wiring is required when using the Wemos D1 ESP32.
LCD_CS is assigned to ADC1_6 and LCD_RS is assigned to ADC1_7.

ILI9341 2.4inch TFT-Shield with Yellow Pin-header

There is no marking about 4-line resistance touch screen.
But 4-line resistance touch screen available.

X(+) X(-) Y(+) Y(-)
LCD_D0 LCD_RS LCD_CS LCD_D1

Touch-ILI9341-1 config-touch-ili9341

When using ADC1_6(ADC1 Channel#6) and ADC1_7(ADC1 Channel#7), the following wiring is additionally required.

TFT ESP32 ESP32S2
LCD_CS(Y+) ADC1_6(GPIO34) ADC1_6(GPIO07)
LCD_RS(X-) ADC1_7(GPIO35) ADC1_7(GPIO08)

No additional wiring is required when using the Wemos D1 ESP32.
LCD_CS is assigned to ADC1_6 and LCD_RS is assigned to ADC1_7.

ILI9486 3.5inch TFT-Shield

There is no marking about 4-line resistance touch screen.
But 4-line resistance touch screen available.

X(+) X(-) Y(+) Y(-)
LCD_D6 LCD_RS LCD_WR LCD_D7

Touch-ILI9486-1 config-touch-open-smart

When using ADC1_6(ADC1 Channel#6) and ADC1_7(ADC1 Channel#7), the following wiring is additionally required.

TFT ESP32 ESP32S2
LCD_WR(Y+) ADC1_6(GPIO34) ADC1_6(GPIO07)
LCD_RS(X-) ADC1_7(GPIO35) ADC1_7(GPIO08)

Other TFT

I don't know which pin is X(+), X(-), Y(+), Y(-).
If you find, please tell me.

Calibration

Keep touching the point.
TouchCalib-1 TouchCalib-2

Draw with touch

If there is no touch for 10 seconds, it will end.
Touch-OpenSmat-16pin Touch-OpenSmart-Shield-2 Touch-Elegoo-2 Touch-ILI9341-2 Touch-ILI9486-2

How dose it works

https://www.sparkfun.com/datasheets/LCD/HOW%20DOES%20IT%20WORK.pdf

Application layer

LibraryLayer

Performance comparison using ILI9488(320x480)

Test GPIO parallel REGISTER I/O parallel I2S parallel
AddressTest 1300 430 70
FillTest 5320 2810 1680
ColorBarTest 1290 460 110
ArrowTest 1360 460 210
LineTest 3190 1280 3650
CircleTest 3030 1230 3310
RoundRectTest 3060 1220 3400
RectAngleTest 4110 1890 11480
TriangleTest 4700 2110 13290
DirectionTest 1440 530 340
HorizontalTest 1750 640 740
VerticalTest 1750 640 730
FillRectTest 2340 890 280
ColorTest 2630 970 400
BMPTest 3350 2190 1370
JPEGTest 3870 2990 2630
PNGTest 4310 3450 3050

Performance comparison using ILI9341(240x320)

SPI used this.

Test SPI GPIO parallel REGISTER I/O parallel I2S parallel
FillTest 1620 2700 1920 1560
ColorBarTest 80 420 160 50
ArrowTest 250 460 170 140
LineTest 2690 1040 420 1530
CircleTest 2400 980 410 1370
RoundRectTest 2400 980 400 1390
RectAngleTest 5960 2010 940 6720
TriangleTest 6550 2120 990 7630
DirectionTest 420 520 200 240
HorizontalTest 990 720 300 580
VerticalTest 990 710 300 580
FillRectTest 160 730 300 120
ColorTest 240 850 330 190
BMPTest 1600 1930 1320 960
JPEGTest 2540 2940 2650 2530
PNGTest 2830 3210 2940 2810

Reference about I2S driver

https://github.com/espressif/esp-iot-solution/tree/master/components/bus

  • for esp32
    i2s_lcd_esp32_driver.c
  • for esp32s2
    i2s_lcd_esp32s2_driver.c
  • Common header
    i2s_lcd_driver.h