Zonnestroompanelen in Nederland

duurzaamheid achter de meter

(49) ESP32-WROOM-32 and Uno-shield parallel TFT displays

By Floris Wouterlood – The Netherlands – June 1, 2021 –


Many Arduino projects require adequate display of what is being monitored. Think of time, temperature, humidity, pressure, sound, light, voltages, or combinations of recorded data in a weather station. With the addition of fast and capable ESP32 microcontroller boards to my personal ‘fleet’ my collection of good old Arduino Unos with their TFT display shields seemed prone to gather dust. The ESP32 combines well with TFT displays through a 4-pin SPI interface* while the Uno shields have parallel interfaces that feature 28 pins of which a minimum of 13 is necessary for the daily display business (see figure 2). A parallel interface is generally faster than a SPI interface. The prospect of a bunch of shield displays with fast parallel interface parked forever in a deep drawer was a stimulus for me to start a project to connect these shields to an ESP32. Fortunately there are several solutions available of which I selected the one proposed by Alberto Iriberri Andrés at https://www.pangodream.es/ili9341-esp32-parallel. However, the nightmarish prospect of connecting shield after shield with an ESP with unwieldy Dupont jumper wires inspired me to create a Uno-shield compatible parallel ESP32 TFTdisplay workbench for the purpose of checking all my Uno TFT shields, one by one. Here follows the design, wiring, and the results with a collection of parallel Uno shield type displays.

figure 1. Parallel 320*240 2.8 inch ILI9341 TFT display Uno shield and an ESP32WROOM-32 board on the completed bench, up & running!

Uno TFT display shields
The market is swamped with TFT shields that can be placed directly on the pin sockets of an Arduino Uno. These shields feature parallel interfaces. They have in common that there are four pin header blocks through which one can stick such a shield very handy right onto a Uno (fig. 2). The displays mounted on these shields have different pixel dimensions and, more important, different controller chips. Most commonly used are ILI9341, ILI9481 and ILI 9486 chips. The best performing TFT shields are equipped with 3V-5V voltage converters (e.g. the shield shown in fig 2) but there are plenty of cheap shields available that lack a voltage regulator and therefore accept only 3V.

figure 2. Wiring scheme to connect a 30-pin ESP32WROOM-32 board to a 3.5 inch, parallel 320*480 Uno TFT shield. The 3.3V and 5V power lines are equipped with jumpers because some TFT shields are exclusively 3.3V. The display depicted here has an AMS1117 voltage regulator on board and is 3.3V-5V compliant.

Controllers need their own specific driver to make the display work correctly. A major effort to supply the Arduino world with adequate drivers for ESP8266 and ESP32 microprocessors running smoothly with the above ILI controllers has been undertaken in recent years by the electronics engineer known as Bodmer: the TFT_e_SPI.h library.

Considerations for a bench design
So what I needed is a board that accomodates an ESP32 and that has enough space to accommodate a variety of small (2.4 inch) and large (3.95 inch) Uno TFT shields.

figure 3. Wiring scheme, part I: power wires and GND. Top view.

Base board
The base board consists of a doule-sided soldering board fastened with four nylon spacers on a piece of cardboard. Mounted on this base are two 15-pin parallel socket headers to accommodate an ESP32 microcontroller board and the four socket headers to accommodate the Arduino Uno TFT shields to be tested. As screen diagonals of TFT shields in my ‘arsenal’ vary between 2.4 inch and 3.95 inch, a 12080 mm double-sided soldering board with 4230 holes was selected for this purpose. The positioning of the socket headers is shown in figure 3. There are also two 2-pin pin headers to allow to select the proper voltage to power the display being tested (with jumpers).

Electronic parts needed
12080 mm double-sided soldering board featuring 4230 holes, two 15-pin socket headers, two 6-pin socket headers, two 8-pin socket header, one 3-pin socket header, one black 2-pin socket header (black), two 2-pin headers (red), four nylon bolts, four nylon spacers and four nylon nuts, ESP32-WROOM32 microcontroller board with 30 pins, wire, two jumpers.

Solution for pin header block pitch unorthodoxy of Uno TFTshields
The positioning of pins on the original Arduino Uno does not follow the uniform 2.54 mm (0.1 inch) pitch rule. Any Uno parallel TFT shield therefore will not immediately fit a standard soldering board. On the back of each shield are jumper blocks labeled J1 through 4 (figure 2). We call J1 here the ‘SD jumper block’, J2 the ‘parallel jumper block’, J3 the ‘control jumper block’ and J4 the ‘power block’. Part of the SD jumper block is occupied by the parallel data interface. Some manoevering makes it clear trhat the J2-J3-J4 blocks fit the holes of the soldering board while the parallel jumper block (J1) is the outlier. Fortunately, the pins in all blocks follow the 2.54 mm pitch rule. It is J1 as a whole that is half a unit positioned ‘out of pitch’. Through this unorthodoxy, say asymmetry, a TFT shield fits an Arduino in only one way. Very clever. The present soldering board was adapted to this configuration by cutting a narrow sleeve where the pins of the J1 parallel jumper block should be, just wide enough to let the pins of the corresponding socket header through. Then an extra piece of soldering board was prepared and fastened with wire and solder under the sleeve, taking care that the J1 accepting socket header would exactly match jumper block J1.

Bench design
The design is quite simple: two parallel rows of 15-pin socket headers serve as a mounting point for the ESP32 (figures 2,3). These sockets are positioned in the upper left corner of the board to leave as much area as possible to position the TFT shields. Here, TFT shields are oriented landscape. The bench is designed only for displaying data and graphs only, with no SD card reader support.
All Uno TFT shields have three pins that deal with power (3V3, 5V, GND), five pins that are necessary for display control and eight pins connected with the parallel data transfer interface, i.e., there is a total of 16 pins that need to be wired (figure 2). In addition I planned three ‘free’ pins of the ESP32 available via pin sockets for input-output puposes: pins D2, D5 and D15 (figure 4).

figure 4. Wiring scheme, additional wiring to access unoccupied pins with input-output devices. Top view.

Pin wiring: four groups
With so many wires it is necessary to bring order in the assembly of the bench. One can distinguish (1) power wires, (2) TFT control wires, (3) parallel interface wires, (4) additional wiring. One by one the groups of wires were mounted on the soldering board.

Power wires
These are shown schematically in figure 3.

Additional wiring
These are shown schematically in figure 4.

TFT control wires
The group of control wires originates from pins D26, D27, D14, D12 and D13 and connect to the socket header that accomodates TFT shield jumper J1 (figure 5).

figure 5. Wiring scheme, TFT control wires. Top view.

Parallel interface wires
There are eight data pins on the TFT shields, marked LCD_D0 through LCD_D07. LCD-00 and LCD_01 are pins on jumper block J3 while the remaining LCD_nn pins can be found on jumper block J2. These pins must be connected to, respectively, pins RX2, D4, D23, D22, D21, D19, D18 and TX2 (figure 6).
For the sake of completeness and oversight the pin connectivity is presented below as a Table.

figure 6. Wiring scheme, parallel interface wires. Top view.

Pin connectivity table

According to the scheme published by Alberto Iriberri Andrés at https://www.pangodream.es/ili9341-esp32-parallel

The complete wiring diagram is shown in figure 7.
figure 7. Complete wiring scheme. Top view


Pin connectivity table

According to the scheme published by Alberto Iriberri Andrés at https://www.pangodream.es/ili9341-esp32-parallel

Sketch – User_Setup.h in the TFT_eSPI library
Bodmer’s TFT_eSPI library is different than other libraries, e.g. Adafruit_GFX and U8G2 in the sense that there is no ‘constructor’. Pin definitions for each type of controller are in TFT_eSPI systematics stored in a separate Setup_nn.h file that is placed in a folder with the name ‘User_Setups’. In turn, the specific Setup_nn.h is called in another stetup file named User_Setup_Select.h. Consider the systematics as a kind of two-stage rocket. Both stages need to be edited befor launch. The first stage is User_Setup_Select.h and the second stage is Setup_nn.h.

An example of the specific Setup_nn.h file for one of my ILI9341 shields (the one shown in figure 1) is named ‘Setup_FW_WROOM32_ILI9341_parallel_TFT_016.h’. This is a file editable with any ASCII editor.

Content of the specific ‘Setup_FW_WROOM32_ILI9341_parallel_TFT_016.h’

// See SetupX_Template.h for all options available
// name: Setup_FW_WROOM32_ILI9341_parallel_TFT_016.h
// prepared June 1, 2021
// TFT 016 = 320*240 ILI 9341 3.5 inch display Uno shield Velleman
// for Bodmer's TFT_eSPI librray
// Floris Wouterlood
// public domain
   #define ESP32_PARALLEL
   #define ILI9341_DRIVER 

// ESP32 pins used for the parallel interface TFT
   #define TFT_CS   27 // Chip select control pin
   #define TFT_DC   14 // Data Command control pin - must use a pin in the range 0-31
   #define TFT_RST  26 // Reset pin
   #define TFT_WR   12 // Write strobe control pin - must use a pin in the range 0-31
   #define TFT_RD   13
   #define TFT_D0   16 // Must use pins in the range 0-31 for the data bus
   #define TFT_D1   4  // so a single register write sets/clears all bits
   #define TFT_D2   23
   #define TFT_D3   22
   #define TFT_D4   21
   #define TFT_D5   19
   #define TFT_D6   18
   #define TFT_D7   17
   #define LOAD_GLCD  // Font 1-Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
   #define LOAD_FONT2 // Font 2-Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
   #define LOAD_FONT4 // Font 4-Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
   #define LOAD_FONT6 // Font 6-Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 
   #define LOAD_FONT7 // Font 7-7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 
   #define LOAD_FONT8 // Font 8-Large 75 pixel font needs ~3256 bytes in FLASH, only characters 
   #define LOAD_GFXFF // FreeFonts-Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom 
   #define SMOOTH_FONT
figure 8. Bottom of the board, after completion of the wiring. Note the extra piece of soldering board that supports the ‘out of pitch’ J1 pin socket of the TFT shield. The nylon spacers mounted onto the board that stick here towards the viewpoint, together with a piece of cardboard, protect the bottom of the test bench. Also visible is a TFT shield present on the bench’s top.

Bench at work: testing and running sketches
Figure 1 shows one of my Uno TFT shields mounted on the bench, running the example ‘TFT_graphicstest_one_lib,’ that can be found in the Arduino IDE under File, Examples, TFT_eSPI, 320×240, of course after correct installation of Bodmer’s TFT_eSPI library. With an ESP32. My own ‘ESP32_parallel_Uno_shield_TFT_radar_scope.ino’ runs fine: the downloadable demo sketch which mimics an aviation traffic controller’s radar scope with a sweeping beam. I created this sketch in 2017 as a demo for one of my first Arduino Uno TFT shields**. The body of that demo was used for the present demo sketch.

Testing my complete collection showed marked differences between shields. I tested shields with ILI341, ILI9481, ILI8486 and ILI9488 controllers, with mixed results. Best performance was achieved with ILI9341 controller equipped shields. Shields that lack a voltage regulator appeared to be dedicated 3V3 shields as they would not perform, or produce an upload error, if the 5V jumper was closed. One 3V3 shield needed the 3V3 jumper closed during upload while after upload it needed 5V to lighten up the screen. Some but not all shields accepted closed 3V3 and 5V jumpers during uploading and running sketches. One ILI9481-powered shield behaved very peculiar: only if both 3V3 and 5V jumpers were open during upload the sketch would be accepted and then be visible on screen only with the 5V jumper closed.
The experiences with the TFT shields lead to the following rule of thumb: first try to figure out the correct controller (this on an Arduino Uno with David Prentices’ ‘MCUFRIEND_kbv.h’), then checking the User_Setup_nn.h file icreated for this shield n the TFT_eSPI library system, and then try to upload first with the 3V3 jumper closed, then again (if necessary) with the 5V jumper closed, and finally with both jumpers closed.

figure 9. Bench ready for action. The socket supporting input-output and the 3V3 – 5V pin headers are labeled and jumpers are set.

Downloadable sketch


packed in a zip file