ESP32 Cheap Yellow Display (CYD) Pinout (ESP32-2432S028R)

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)

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 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.
ESP32 Cheap Yellow Display CYD Board ESP32-2432S028R front

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

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 PinGPIO
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 PinGPIO 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 PinGPIO
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. Here’s the RGB LED pinout:

Red LEDGPIO 4
Green LEDGPIO 16
Blue LEDGPIO 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

The microSD card uses SPI communication protocol. It uses the ESP32 default VSPI pins:

MicroSD card SPIGPIO
MISOGPIO 19
MOSIGPIO 23
SCKGPIO 18
CSGPIO 5

You may also like: ESP32: Guide for MicroSD Card Module using Arduino IDE

LDR (Light Dependent Resistor – Light Sensor)

The board comes with an LDR at the front, right next to the display. The LDR is connected to GPIO 34.

LDRGPIO 34

Speaker

There is a 2P 1.25mm JST connector to connect a speaker. It’s controlled with GPIO 26.

SpeakerGPIO 26

BOOT Button

The BOOT button is internally connected to GPIO 0.

BOOT ButtonGPIO 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.

P3 Extended IO

In the P3 connector, you have a GND pin and GPIOs 35, 22, and 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, GPIO22, GPIO27 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.

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

It also has the TX/RX pins available on the connector labeled P1. These are used for serial communication.

  • GPIO 1 — TX
  • GPIO 3 — RX

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:

Learn more about the ESP32 with our resources:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

11 thoughts on “ESP32 Cheap Yellow Display (CYD) Pinout (ESP32-2432S028R)”

  1. 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.

    Reply
  2. 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.

    Reply
    • 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.

      Reply
        • /*
          // 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);
          }

          Reply
          • 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>

  3. 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

    Reply
  4. 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?

    Reply
  5. 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.

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.