8 bit parallel TFT & 4-line resistance touch screen Driver for esp-idf.
You can use such a TFT-Shield with esp32.
- 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 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.
3.95 inches is almost twice as large as 2.4 inches.
These are OPEN-SMART 16Pin-Parallel Products.
esp-idf v4.4/v5.0.
Note for ESP-IDF V5.0
ESP-IDF V5.0 gives this warning, but work.
#warning "legacy adc driver is deprecated, please migrate to use esp_adc/adc_oneshot.h and esp_adc/adc_continuous.h for oneshot mode and continuous mode drivers respectively"
Presumably, ESP-IDF V5.1 will completely obsolete the legacy ADC driver.
git clone https://github.com/nopnop2002/esp-idf-parallel-tft
cd esp-idf-parallel-tft/
idf.py set-target {esp32/esp32s2/esp32s3}
idf.py menuconfig
idf.py flash
Note for ESP32-S2
The tjpgd library is not present in ESP32-S2 ROM.
With ESP-IDF Ver5, the JPEG decode library is now provided from the IDF Component Registry, and the JPEG decode library is now available for ESP32-S2.
However, since the ROM is small, a large image cannot be displayed.
With ESP-IDF Ver4.4, you cannot be displayed JPEG files because the IDF Component Registry cannot be used.
PNG file cannot be displayed because the SRAM is small.
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.
I'll say it again.
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.
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.
(*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.
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.
It's possible to text rotation and invert.
You can specify multiple fonts at the same time.
I have changed some pin assignments.
Attached the TFT shield.
The TFT shield worked fine.
It's great because it doesn't require any wiring.
If you use OPEN-SMART TFT-Shield Products, you have to change Custom GPIO.
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.
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.
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);
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 with two wires.
(Y+) and ESP32 are connected with 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)
- 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/S3 has 10 channels: GPIO01 - GPIO10.
Refer to the ESP32 data sheet for the relationship between ADC channels and GPIOs.
When using ADC1_6(ADC1 Channel#6) and ADC1_7(ADC1 Channel#7), the following wiring is additionally required.
TFT | ADC1 | ESP32 | ESP32S2/S3 |
---|---|---|---|
LCD-WR(Y+) | Channel#6 | GPIO34 | GPIO07 |
LCD-RS(X-) | Channel#7 | GPIO35 | GPIO08 |
- GPIO number
It uses four GPIOs, but the GPIOs differ depending on the TFT model.
X(+) | X(-) | Y(+) | Y(-) |
---|---|---|---|
LCD_D6 | LCD_RS | LCD_WR | LCD_D7 |
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 |
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 the combination of GPIO and ADC does not match.
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 |
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.
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 |
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.
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 |
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 the combination of GPIO and ADC does not match.
I don't know which pin is X(+), X(-), Y(+), Y(-).
If you find, please tell me.
Keep touching the corner point.
If there is no touch for 20 seconds, it will end.
If there is no touch for 20 seconds, it will end.
I borrowed the icon from here.
https://www.sparkfun.com/datasheets/LCD/HOW%20DOES%20IT%20WORK.pdf
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 |
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 |
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 - for esp32s3
8080_lcd_esp32s3.c - Common header
i2s_lcd_driver.h