In many projects, you see the use of the ESP32 Cheap Yellow Display Board. This is a how-to guide on getting started with the ESP32 Cheap Yellow Display Board (ESP32-2432S028R) using the Platform.io framework in Visual Studio Code. The ESP32 Cheap Yellow Display Board (ESP32-2432S028R) is a development board that combines an ESP32 with a TFT touchscreen. This allows you to easily add a graphical user interface (GUI) to your IoT projects, instead of designing and creating a PCB or wiring your hardware setup first.

When working with a standalone TFT Touchscreen Display 2.8 inch with an ILI9341 or ST7789 driver, this guide can be a helpful starting point for your project.
The ESP32 Cheap Yellow Display Board – CYD (ESP32-2432S028R)
The ESP32-2432S028R is one of several options available from Yellow Display Boards, a popular choice among makers and hobbyists. The specific model used in this guide features a 2.8-inch TFT display with touch functionality, but other sizes are also available online, including 4.3″, 5.0″, and 7.0″ variants. These boards have gained recognition within the maker community as “Cheap Yellow Display” or CYD develop board, because of their affordability and versatility.
These boards are particularly convenient because they seamlessly integrate a TFT display with touch capabilities
and a popular developer microcontroller board, eliminating the need for manual wiring or creating a PCB. They have
proven to be extremely useful in my own projects and testing—thanks to their display and processing power, as well
as access to additional IO pins, which allows adding extra hardware as needed.
Next is shown the ESP32-2432S028R version 3 develop board

Back side

Front side
ESP32-2432S028R features
- Dimensions
- Module size 50.0×86.0mm
- Product weight: approximately 50g
- Connections
- Serial
- USB micro
- USB-C (only on the v3)
- Power
- Operating Voltage: 5V
- Power consumption: approximately 115mA
- Microcontroller ESP-WROOM-32
- Dual-core MCU, integrated WI-FI and Bluetooth functions
- Frequency can reach 240MHz
- 520KB SRAM, 448KB ROM, Flash size is 4MB
- TFT display ILI9341(v1,v2) or ST7789(v3)
- 2.8-inch color screen, support 16 BIT RGB 65K color display, display rich colors
- 240X320 resolution
- Backlight control circuit
- Onboard peripherals
- TF card interface for external storage
- RGB LED
- built-in LDR (light-dependent resistor)
- Speaker interface
- Extended IO
⚠️Different versions
There are different version of ESP32-2432S028R available on the marked. Version 3 has another type of display and an extra USB C port. See for details on the page about the Pinout ESP32 Cheap Yellow Display Board(CYD) ESP32-2432S028R
Where to buy?
There are several stores where you can buy the ESP32-2432S028R the most common is Aliexpress. (By using my link you support Kafkar)
Creating an example application with Platform.io
Create a new Platform.io project
To begin this project, we created a new empty Platform.io project in Visual Studio Code. Ensure that Visual Studio Code is installed with Platform.IO
For this guide, we named the project “ESP32-2432S028-Tutorial.” The board type selected was NodeMCU-32S, and the framework used was Arduino.

After pressing Finish, the project will be created. If the project is successfully created, you will find the file platform.ini
in the root directory of the project folder. This file will contain the necessary environment settings.
[env:nodemcu-32s]
platform = espressif32
board = nodemcu-32s
framework = arduino
Adding Libraries to the project
The next step is to add the needed libraries To control the TFT Display and the Touchscreen using SPI communication protocol, we have to add the following Liberarys:
TFT_eSPI created by Bodmer [https://github.com/Bodmer/TFT_eSPI]
This is a TFT library optimized for the Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different driver chips
XPT2046_Touchscreen created by Paul Stoffregen [https://github.com/PaulStoffregen/XPT2046_Touchscreen]
This is a Touchscreen Library for XPT2046 Touch Controller Chip.
Adding these libraries can be done using the Platform.io library import function or by adding these libraries direct to your platform.ini
file
lib_deps =
bodmer/TFT_eSPI@^2.5.43
https://github.com/PaulStoffregen/XPT2046_Touchscreen.git#v1.4
⚠️XPT2046_Touchscreen wrong version
The moment of writing this tutorial, the wrong version of the XPT2046_Touchscreen library is defined in Platform.io environment when installing this library via the library install function of platform.io.
To ensure that you install version 1.4. Adding the line: https://github.com/PaulStoffregen/XPT2046_Touchscreen.git#v1.4
to your platform.ini file will ensure that the correct version is downloaded form github direct.
Configure TFT_eSPI
To control the TFT display, the TFT_eSPI library need to be configured correct to control the TFT screen and enable display functionality.
The TFT_eSPi library offers predefined user setups, but currently not support for the ESP32-2432S028R board. To address this, I have prepared specific setup files that can be used. Download these files on GitHub Setup_ESP32_2432S028R_ILI9341.h
, Setup_ESP32_2432S028R_ST7789.
h
Place the configuration files in the same folder as the main.cpp These files contain the correct IO ports configuration for the TFT display.
Depending on the version of the used ESP32-2432S028R development board, you have to select the correct configuration file. For v1 and v2 use Setup_ESP32_2432S028R_ILI9341.h
For v3 use Setup_ESP32_2432S028R_ST7789.h
See more details on Pinout ESP32 Cheap Yellow Display Board(CYD) ESP32-2432S028R
For this selection, you need to add the following lines to your platform.io
and un-comment the one needed for your setup
build_flags =
;###############################################################
; TFT_eSPI library setting here (no need to edit library files):
;###############################################################
-D USER_SETUP_LOADED=1 ;Set this settings as valid
;-include src/Setup_ESP32_2432S028R_ILI9341.h ;for version 1 and version 2
-include src/Setup_ESP32_2432S028R_ST7789.h ;for version 3
Add serial port speed to Platform.IO
The test application reports touch positions over the serial port at a speed of 11520 Baud. To monitor this data within Platform.IO, you need to set the same speed in the platform.ini
file.
monitor_speed = 115200
Adding the test application
Final step is to add the application code to the project therefore you have to replace the main.cpp or copy the code from main.cpp to the main.cpp in your project.
Or you can download the complete project from GitHub: https://github.com/Kafkar/ESP32_2432S028R-tutorial
Now you can build and upload your application to your ESP32_2432S028R and test it.
After startup, it will show the Welcome screen with the Kafar.com logo.

After touching the screen it will change to the touch test screen where you can test the touch function of the ESP32_2432S028R.

Example Application Explained (main.cpp)
Includes
The application starts with including the needed liberaries. beside the TFT_eSPI.h and the XPT2046_Touchscreen.h needs also the generic SPI.h to be include. This liberary is used by the TFT_eSPI.h and the XPT2046_Touchscreen.h.
#include <Arduino.h>
#include <SPI.h>
// include the installed "TFT_eSPI" library by Bodmer to interface with the TFT Display - https://github.com/Bodmer/TFT_eSPI
#include <TFT_eSPI.h>
// include the installed the "XPT2046_Touchscreen" library by Paul Stoffregen to use the Touchscreen - https://github.com/PaulStoffregen/XPT2046_Touchscreen
#include <XPT2046_Touchscreen.h>
Instance TFT_eSPI
To use the TFT_eSPI in the application, it should be instantiated. This uses the configured setup file.
If you are not using the ESP32_2432S028R but another display, then you have to check in the setup file if the correct IO ports are used to connect to the display
// Create a instance of the TFT_eSPI class
TFT_eSPI tft = TFT_eSPI();
Instance XPT2046 touchscreen
To use the touchscreen function, the driver should be configured. Therefore, the IO ports used by the touchscreen have to be defined. See for more IO details the Pinout ESP32 Cheap Yellow Display Board(CYD) ESP32-2432S028R
// Set the pius of the xpt2046 touchscreen
#define XPT2046_IRQ 36 // T_IRQ
#define XPT2046_MOSI 32 // T_DIN
#define XPT2046_MISO 39 // T_OUT
#define XPT2046_CLK 25 // T_CLK
#define XPT2046_CS 33 // T_CS
After the configuration, the driver has to be instantiated.
// Create a instance of the SPIClass and XPT2046_Touchscreen classes
SPIClass touchscreenSPI = SPIClass(VSPI);
XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);
Global definitions and variables
The test program is using some global variable. IT start with the defines of the screen size and the font type to use.
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
#define FONT_SIZE 2
The next set of variables are needed for transferring data between some functions.
// Global Variables
int posX; // x position of the touch
int posY; // y position of the touch
int pressure; // pressure of the touch
// Set X and Y coordinates for center of display
int centerX;
int centerY;
Also the Kafkar.com logo is global defined. a black white image of 1 bit with a size of 116 x 100 pixels. You can tis replace by your own image.

There are online tools to transform your image to bytes.
const unsigned char bitmap_kafkar_logo[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
...
0x00, 0x00, 0x00, 0x0c, 0x00, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
function logTouchData
The logTouchData
function is triggered when the screen is touched. It sends the current measured position and pressure of the touch over the serial port. If the terminal port in Platform.IO is open, you will see the output.
void logTouchData(int posX, int posY, int pressure)
{
Serial.print("X = ");
Serial.print(posX);
Serial.print(" | Y = ");
Serial.print(posY);
Serial.print(" | Pressure = ");
Serial.print(pressure);
Serial.println();
}
function displayTouchData
The function displayTouchData
is triggered after a touch on the touchscreen. This function begins by clearing the screen. It then writes the touch position (X and Y coordinates) and pressure in the center of the screen. Additionally, it draws boxes as markers to help visualize whether the touch position matches the corresponding position on the screen. Finally, it places a dot at the pressed position, with the size of the dot proportional to the pressure level.
void displayTouchData(int posX, int posY, int pressure)
{
// Clear TFT screen
tft.fillScreen(TFT_WHITE);
tft.setTextColor(TFT_BLACK, TFT_WHITE);
// Draw text
int textY = 100;
String text = "X = " + String(posX) + "Y = " + String(posY);
tft.drawCentreString(text, centerX, textY, FONT_SIZE);
textY += 20;
text = "Pressure = " + String(pressure);
tft.drawCentreString(text, centerX, textY, FONT_SIZE);
tft.drawCentreString("Kafkar.com", centerX, 200, FONT_SIZE);
// Draw touch box
tft.drawRect(20, 20, 280, 200, TFT_BLUE);
tft.drawRect(50, 50, 10, 10, TFT_BLUE);
tft.drawRect(260, 50, 10, 10, TFT_BLUE);
tft.drawRect(50, 180, 10, 10, TFT_BLUE);
tft.drawRect(260, 180, 10, 10, TFT_BLUE);
tft.fillSmoothCircle(posX, posY, pressure/200, TFT_YELLOW);
}
Function Setup
This function should also be available in an Audino-based program. It will be triggered at the start of the application and used for initializing and configuring components during startup.
The first step is initializing the serial communication, which allows us to send data to a computer or other devices. We set the baud rate to 115200 for reliable high-speed communication.
void setup()
{
Serial.begin(115200);
Next, we configure and start the touchscreen component. This involves initializing the SPI interface and setting up the touchscreen in landscape mode.
// Start the touchscreen component and init the touchscreen
touchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
touchscreen.begin(touchscreenSPI);
// Set the Touchscreen rotation in landscape mode
touchscreen.setRotation(1);
Now, let’s initialize the TFT display. After initialization, the screen will be cleared and prepared for displaying content.
// Start the tft display
tft.init();
// Set the TFT display rotation in landscape mode
tft.setRotation(1);
// Clear the screen and display a message
tft.fillScreen(TFT_WHITE);
tft.setTextColor(TFT_BLACK, TFT_WHITE);
// Set X and Y coordinates for center of display
centerX = SCREEN_WIDTH / 2;
centerY = SCREEN_HEIGHT / 2;
With the display ready, we can now add some welcoming text to inform users about the functionality of the touchscreen.
tft.drawCentreString("Hello, Kafkar.com!", centerX, 30, FONT_SIZE);
tft.drawCentreString("Touchscreen to test", centerX, 200, FONT_SIZE);
Finally, we’ll add the Kafkar logo to the center of the screen.
int x = (tft.width() - 116) / 2;
int y = (tft.height() - 110) / 2;
// Draw the Kafkar logo bitmap
tft.drawBitmap(x, y, bitmap_kafkar_logo, 116, 100, TFT_BLACK);
}
Function Loop
Once the setup function is complete, it will automatically start the loop function. This behavior is predefined in the Arduino framework.
The loop continuously checks for two conditions: touchscreen.tirqTouched()
and touchscreen.touched()
. If both return true
, it proceeds to capture the touchpoint’s position. Once a valid touch is detected, the system uses a mapping function to convert the raw touchscreen coordinates into screen-relative positions.
void loop()
{
// Checks if Touchscreen is touched
if (touchscreen.tirqTouched() && touchscreen.touched())
{
// Get Touchscreen points
TS_Point p = touchscreen.getPoint();
// Calibrate Touchscreen points with map function to the correct width and height
posX = map(p.x, 200, 3700, 1, SCREEN_WIDTH);
posY = map(p.y, 240, 3800, 1, SCREEN_HEIGHT);
pressure = p.z;
If there is a position and pressure detected, it will call the logTouchData
and the displayTouchData
.
logTouchData(posX, posY, pressure);
displayTouchData(posX, posY, pressure);
delay(100);
}
}