In this guide, we’ll take a look at the ESP32 Cheap Yellow Display Pinout. We’ll see which pins are used to control the display, touchscreen, and microSD card, and which pins you have available to connect external peripherals.
![ESP32 Cheap Yellow Display (CYD) Pinout (ESP32-2432S028R)](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2024/05/cheap-yellow-display-pinout-thumbnail.jpg?resize=828%2C466&quality=100&strip=all&ssl=1)
The ESP32 Cheap Yellow Display (ESP32-2432S028R) is a TFT Touchscreen display LCD with an ESP32 development board included, which is great to build graphical user interfaces for your IoT projects.
Table of Contents
- Introducing the CYD
- Display Pins
- Touchscreen Pins
- RGB LED
- MicroSD Card Pins
- LDR (Light Dependent Resistor – Light Sensor)
- Speaker
- BOOT Button
- Extended IO
- TX/RX Connector
Introducing the ESP32 Cheap Yellow Display – CYD (ESP32-2432S028R)
The ESP32-2432S028R development board has become known in the maker community as the “Cheap Yellow Display” or CYD for short. This development board, whose main chip is an ESP32-WROOM-32 module, comes with
- 2.8-inch TFT touchscreen LCD
- microSD card interface
- RGB LED
- built-in LDR (light-dependent resistor)
- all the required circuitry to program and apply power to the board.
This is a very versatile board to build GUIs for your IoT projects and is much more convenient and practical than using a separate ESP32 board with a TFT screen.
![ESP32 Cheap Yellow Display CYD Board ESP32-2432S028R back labeled](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2024/03/ESP32-Cheap-Yellow-Display-CYD-Board-ESP32-2432S028R-back-labeled.jpg?resize=828%2C420&quality=100&strip=all&ssl=1)
New to the ESP32 CYD board? Read our detailed getting-started guide: Getting Started with ESP32 Cheap Yellow Display Board – CYD (ESP32-2432S028R).
Where to buy?
You can click on the link below to check where to buy the ESP32 Cheap Yellow display and its price on different stores.
Display Pins
The TFT display communicates with the board using SPI communication protocol (HSPI). In our guides, we use the following pin assignment for the TFT display (set up in the User_Setup.h of the TFT_eSPI library).
SPI Pin | GPIO |
MISO (TFT_MISO) | GPIO 16 |
MOSI (TFT_MOSI) | GPIO 13 |
SCKL (TFT_SCLK) | GPIO 14 |
CS (TFT_CS) | GPIO 15 |
DC (TFT_DC) | GPIO 2 |
RST (TFT_RST) | GPIO 12 |
Backlight Pin | GPIO 21 |
Learn more about ESP32 SPI communication: ESP32 SPI Guide with Arduino IDE
Touchscreen Pins
The touchscreen also uses SPI protocol to communicate with the ESP32. These are the VSPI pins for the touchscreen:
SPI Pin | GPIO |
IRQ (XPT2046_IRQ) | GPIO 36 |
MOSI (XPT2046_MOSI) | GPIO 32 |
MISO (XPT2046_MISO) | GPIO 39 |
CLK (XPT2046_CLK) | GPIO 25 |
CS (XPT2046_CS) | GPIO 33 |
RGB LED
The board comes with an RGB LED at the back that might be useful for debugging.
![ESP32 Cheap Yellow Display RGB LED](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2024/06/Cheap-Yellow-Display-ESP32-RGB-LED-pinout.jpg?resize=750%2C421&quality=100&strip=all&ssl=1)
Here’s the RGB LED pinout:
RGB LED | GPIO |
Red LED | GPIO 4 |
Green LED | GPIO 16 |
Blue LED | GPIO 17 |
Important: The RGB LEDs work with inverted logic, because they are active low. This means that if you set them to HIGH = OFF and LOW = ON.
MicroSD Card Pins
![ESP32 Cheap Yellow Display MicroSD Card](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2024/06/Cheap-Yellow-Display-ESP32-microSD-card.jpg?resize=750%2C421&quality=100&strip=all&ssl=1)
The microSD card uses SPI communication protocol. It uses the ESP32 default VSPI pins:
MicroSD card SPI | GPIO |
MISO | GPIO 19 |
MOSI | GPIO 23 |
SCK | GPIO 18 |
CS | GPIO 5 |
You may also like: ESP32: Guide for MicroSD Card Module using Arduino IDE
LDR (Light Dependent Resistor) – Light Sensor
![ESP32 Cheap Yellow Display LDR (Light Dependent ResistorESP32-Cheap-Yellow-)](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2024/06/ESP32-Cheap-Yellow-Display-LDR.jpg?resize=750%2C423&quality=100&strip=all&ssl=1)
The board comes with an LDR at the front, right next to the display. The LDR is connected to GPIO 34.
LDR | GPIO 34 |
Speaker
There is a 2P 1.25mm JST connector to connect a speaker. It’s controlled with GPIO 26.
Speaker | GPIO 26 |
BOOT and RST Buttons
![ESP32 Cheap Yellow Display BOOT and Reset RST Button](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2024/06/ESP32-cheap-Yellow-Display-Boot-Button.jpg?resize=750%2C420&quality=100&strip=all&ssl=1)
It has the BOOT button which is internally connected to GPIO 0 and you also have the on-board RST (RESET) button.
BOOT Button | GPIO 0 |
Extended IO
There are two extended GPIO connectors labeled P3 and CN1 on the board. In the Extended GPIO connectors, there are 4 GPIOs available: GPIO 35, GPIO 22, GPIO 21, and GPIO 27 that you can use to connect peripherals.
![ESP32 Cheap Yellow Display Extended IO Connectors](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2024/06/ESP32-CYD-Extended-IO-pins.jpg?resize=750%2C422&quality=100&strip=all&ssl=1)
P3 Extended IO
In the P3 connector, you have a GND pin and GPIO 35, GPIO 22, and GPIO 21.
Please note that GPIO 22 is also used on the CN1 connector and that GPIO 21 is used as a backlight for the display. So, as long as the backlight is on, GPIO 21 will be on.
CN1 Extended IO
In the CN1 connector, you have GND, GPIO 22, GPIO 27 and 3V3 pins. Please note that GPIO22 is also available on the P3 connector.
The pins on the CN1 connector can be especially useful to connect I2C devices because you have two available GPIOs that can be used for the I2C bus lines, and power and GND pins.
![ESP32 Cheap Yellow Display Connect BME280 Sensor](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2024/06/ESP32-Cheap-Yellow-Display-Connect-BME280-Sensor.jpg?resize=750%2C422&quality=100&strip=all&ssl=1)
If you want to use those pins to connect with I2C sensors, you need to set custom I2C pins. You cannot use the default SDA and SCL pins (GPIO 21 and GPIO 22) because GPIO 21 is used for the backlight).
Learn more about I2C communication with the ESP32: ESP32 I2C Communication: Set Pins, Multiple Bus Interfaces and Peripherals (Arduino IDE).
Available Pins to Connect Peripherals
So, in summary, you have three pins available to connect peripherals:
- GPIO 35 — on the P3 connector
- GPIO 22 — on the P3 and CN1 connector
- GPIO 27 — on the CN1 connector
TX/RX Connector
![ESP32 Cheap Yellow Display RX TX Serial Connector](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2024/06/ESP32-Cheap-Yellow-display-RX-TX-Serial-connector.jpg?resize=750%2C421&quality=100&strip=all&ssl=1)
It also has the TX/RX pins available on the connector labeled P1. These are used for serial communication and are connected directly to the CH340 (USB to serial converter).
- GPIO 1 — TX
- GPIO 3 — RX
Many of our readers mentioned they couldn’t use those pins to connect peripherals (that communicate via Serial, like a GPS module), but we haven’t tested that feature yet.
Wrapping Up
We hope you find this GPIO reference guide for the ESP32 Cheap Yellow Display useful. If you have more information about the CYD GPIOs, please share by writing a comment down below.
If you’re getting started with the ESP32 CYD, make sure to take a look at the following tutorials:
- Getting Started with ESP32 Cheap Yellow Display Board – CYD (ESP32-2432S028R)
- ESP32 Touchscreen On/Off Button – Cheap Yellow Display (ESP32-2432S028R)
- LVGL with ESP32 Cheap Yellow Display Board (ESP32-2432S028R)
Learn more about the ESP32 with our resources:
- Learn ESP32 with Arduino IDE (2nd Edition)
- SMART HOME with Raspberry Pi, ESP32, ESP8266
- Build Web Servers with ESP32 and ESP8266
- Firebase Web App with the ESP32 and ESP8266
- Learn LVGL: Build GUIs for ESP32 Projects (eBook)
- Free ESP32 Projects,Tutorials and Guides
Thanks for reading.
I have sniffed at this gadget several times, and always come away with the feeling that there is simply too little GPIO available for it to be of any use to me. It is certainly of no use for robotics-like projects with heaps of motors, sensors, actuators and things. I haven’t bothered with detailed pin count but suspect very many GPIO pins remain inaccessible.
These devices make good clock / sensor displays.
I have used BME280, HTU21D, AHT10, Si7021, and DS18B20 sensors successfully on I2C using the following pins:
#define OneWirePin 27
#define I2C_SCL 22
#define I2C_SDA 27
They display data, broadcast telemetry (MQTT), and post to SQL database. Using the LDR the display can automatically dim with the ambient light.
They are also handy for remote buttons using MQTT for controlling various things like flood lights.
The ones with the “C” connector need a capacitor across the reset button to automatically flash in the Arduino IDE. Thank you for your previous article about dealing with that problem.
Correction, the DS18B20 sensor was on OneWire not I2C. I just use the same pins and connector. My devices check for the DS18B20 then each of the other sensors until it finds one. That way changing sensors only requires a reboot. I will post the code if anyone is interested in it.
Yes the Code please.
/*
// Global Variables
char SB2[7], ST2[7], SH2[7];
float B(NAN), T(NAN), H(NAN);
const PROGMEM char bmeLabel[] = “BME”;
const PROGMEM char htuLabel[] = “HTU”;
const PROGMEM char ahtLabel[] = “AHT”;
const PROGMEM char siLabel[] = “SI”;
const PROGMEM char dsLabel[] = “DS”;
const PROGMEM char xxxLabel[] = “XXX”;
const PROGMEM char bmeMsg[] = “BME280 sensor found”;
const PROGMEM char htuMsg[] = “HTU21D sensor found”;
const PROGMEM char ahtMsg[] = “AHT10 sensor found”;
const PROGMEM char siMsg[] = “Si7021 sensor found”;
const PROGMEM char dsMsg[] = “DS18B20 sensor found”;
const PROGMEM char xxxMsg[] = “Sensor not found.”;
BME280I2C bme;
BME280::TempUnit tempUnit(BME280::TempUnit_Fahrenheit);
BME280::PresUnit presUnit(BME280::PresUnit_inHg);
Adafruit_HTU21DF htu = Adafruit_HTU21DF();
Adafruit_Si7021 Si = Adafruit_Si7021();
OneWire oneWire1(OneWirePin);
DallasTemperature sensorsDS(&oneWire1);
AHT10 aht(AHT10_ADDRESS_0X38);
*/
void initSensors() {
// timerWrite(Timer, 0);
// byte addrArray[8];
Serial.println();
// DS18B20 sensors can be found either by search or count
sensorsDS.begin();
// if (oneWire1.search(addrArray)) {
int ds1 = sensorsDS.getDeviceCount();
// Serial.printf(“DS Sensor Count = %u\n”, ds1);
if (ds1 > 0) {
MQTTclient.publish(topic_D, dsMsg);
Serial.println(dsMsg);
strcpy(sensor, dsLabel);
} else {
Wire.begin(I2C_SDA, I2C_SCL); // must start wire after checking for DS18B20 sensor <== necesary because default pins are not used
if (Si.begin()) {
MQTTclient.publish(topic_D, siMsg);
Serial.println(siMsg);
strcpy(sensor, siLabel);
} else {
if (htu.begin()) {
MQTTclient.publish(topic_D, htuMsg);
Serial.println(htuMsg);
strcpy(sensor, htuLabel);
} else {
if (aht.begin()) {
MQTTclient.publish(topic_D, ahtMsg);
Serial.println(ahtMsg);
strcpy(sensor, ahtLabel);
} else {
if (bme.begin()) {
MQTTclient.publish(topic_D, bmeMsg);
Serial.println(bmeMsg);
strcpy(sensor, bmeLabel);
} else {
strcpy(sensor, xxxLabel);
MQTTclient.publish(topic_D, xxxMsg);
Serial.println(xxxMsg);
Wire.end();
}
}
}
}
}
Serial.println();
}
void readSensor() {
// timerWrite(Timer, 0);
if (strcmp(sensor, bmeLabel) == 0) readBME();
else if (strcmp(sensor, htuLabel) == 0) readHTU();
else if (strcmp(sensor, ahtLabel) == 0) readAHT();
else if (strcmp(sensor, siLabel) == 0) readSi();
else if (strcmp(sensor, dsLabel) == 0) readDS();
}
void readAHT() {
char tmp[7];
T = aht.readTemperature();
H = aht.readHumidity();
T = 1.8 * T + 32.0;
dtostrf(T, 5, 1, tmp);
StripSpaces(7, ST2, tmp);
dtostrf(H, 5, 1, tmp);
StripSpaces(7, SH2, tmp);
}
void readBME() {
char tmp[7];
bme.read(B, T, H, tempUnit, presUnit);
dtostrf(B, 5, 1, tmp);
StripSpaces(7, SB2, tmp);
dtostrf(T, 5, 1, tmp);
StripSpaces(7, ST2, tmp);
dtostrf(H, 5, 1, tmp);
StripSpaces(7, SH2, tmp);
}
void readHTU() {
char tmp[7];
T = htu.readTemperature();
T = 1.8 * T + 32.0;
dtostrf(T, 5, 1, tmp);
StripSpaces(7, ST2, tmp);
H = htu.readHumidity();
dtostrf(H, 5, 1, tmp);
StripSpaces(7, SH2, tmp);
}
void readSi() {
char tmp[7];
T = Si.readTemperature();
T = 1.8 * T + 32.0;
dtostrf(T, 5, 1, tmp);
StripSpaces(7, ST2, tmp);
H = Si.readHumidity();
dtostrf(H, 5, 1, tmp);
StripSpaces(7, SH2, tmp);
}
void readDS() {
int tpr;
char tmp[7];
sensorsDS.setWaitForConversion(true);
sensorsDS.requestTemperatures();
//delay(40);
T = sensorsDS.getTempFByIndex(0); // first sensor found
dtostrf(T, 5, 1, tmp);
StripSpaces(7, ST2, tmp);
}
I forgot to include this function used in the above.
void StripSpaces(int len, char* output, char* input) {
// accept either byte or char
int j = 0;
for (int i = 0; i < len; i++) {
if (input[i] != 32) {
if(input[i] == 0) break;
output[j] = char(input[i]);
j++;
}
output[j] = 0;
}
input[len-1] = 0;
}
Of course, you may not need both floating point and text versions of the data so you could just delete those parts.
Sorry, I also forgot the library includes:
#include <Wire.h>
#include <BME280I2C.h>
#include <Adafruit_HTU21DF.h>
#include <Adafruit_Si7021.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <AHT10.h>
Yes please. Looking to do something similar.
There is a branch of TFT_eSPI that has been modified for 2 SPI busses. I have been using it in all my projects. I especially like being able to use the touch_calibrate function from the demo. It provides fast concise calibration for each display. I wish Bodmer would adopt this for the master version.
You can find it here:
https://github.com/maxpautsch/TFT_eSPI
The following lines need to be in the USER_SETUP file:
#define SOFTSPI // Uncomment for software SPI
#define TOUCH_CS 33 // Chip select pin (T_CS) of touch screen
#define TOUCH_MOSI 32 // Separate Touch SoftSPI bus
#define TOUCH_MISO 39 // Separate Touch SoftSPI bus
#define TOUCH_CLK 25 // Separate Touch SoftSPI bus
#define TOUCH_INT 36
#define TOUCH_IRQ 36
Has anyone done anything with going into sleep on this board, what sort of mA do you down to for light sleep, or deep sleep?
And how do you turn off display eyc, just with CS?
As usual, very good article.
Meanwhile, GPIO 16 is used both for SPI (TFT_MISO) and the green led ?
I tested to switch on/off the leds and the green one is mapped to GPIO 16.
I tried to set TFT_MISO to GPIO 16 and the TFT works !
Meanwhile, if you want to use the green LED and both the TFT, you will have to define TFT_MISO to something else (I tried 12, 16, 19 and either 21 !). Of course, if you use pin 12, you won’t be able to use TFT_RST.
Starting from the default example: https://randomnerdtutorials.com/cheap-yellow-display-esp32-2432s028r/
I added these definitions:
#define PIN_LED_R 4
#define PIN_LED_G 16
#define PIN_LED_B 17
And then this method :
void animateLed(int pinNumber) {
digitalWrite(pinNumber, LOW);
delay(500);
digitalWrite(pinNumber, HIGH);
delay(500);
}
In the setup method, before initializing, set the leds pin mode:
pinMode(PIN_LED_R, OUTPUT);
pinMode(PIN_LED_G, OUTPUT);
pinMode(PIN_LED_B, OUTPUT);
and finally, in the loop method, animate the leds:
animateLed(PIN_LED_R);
animateLed(PIN_LED_G);
animateLed(PIN_LED_B);
Finally, in the printTouchToSerial method, add the TFT pins definition to make sure what is User_Setup.h file is used:
Serial.println(“————————————————-“);
Serial.print(“TFT_MISO: “);
Serial.println(TFT_MISO);
Serial.print(“TFT_MOSI: “);
Serial.println(TFT_MOSI);
Serial.print(“TFT_SCLK: “);
Serial.println(TFT_SCLK);
Serial.print(“TFT_CS: “);
Serial.println(TFT_CS);
Serial.print(“TFT_DC: “);
Serial.println(TFT_DC);
Serial.print(“TFT_RST: “);
Serial.println(TFT_RST);
Serial.println(“————————————————-“);
If TFT_MISO is set to 16 (same as green led), the TFT will work but the led not.
If TFT_MISO is set to something else, both will work, and displaying the TFT_MISO pin like it is defined in the User_Setup.h file :
X = 262 | Y = 193 | Pressure = 2675
TFT_MISO: 12
TFT_MOSI: 13
TFT_SCLK: 14
TFT_CS: 15
TFT_DC: 2
TFT_RST: -1
How is it possible that the TFT_MISO can change to other pin ?
I do not understand.