{"id":190235,"date":"2026-03-26T12:11:50","date_gmt":"2026-03-26T12:11:50","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=190235"},"modified":"2026-03-26T12:38:57","modified_gmt":"2026-03-26T12:38:57","slug":"esp32-cyd-display-touchscreen-microsd-card","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-cyd-display-touchscreen-microsd-card\/","title":{"rendered":"ESP32 CYD: Use Display, Touchscreen and MicroSD Card Simultaneously"},"content":{"rendered":"\n<p>In this guide, we\u2019ll show you how to use the display, touchscreen, and microSD card all at once with the ESP32 CYD (Cheap Yellow Display) board. We&#8217;ll build a simple example that shows the current touch points on the screen while simultaneously saving them to the microSD card.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/ESP32-CYD-TouchDisplaysdcard.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 CYD Cheap Yellow Display Board How to use Display, Touchscreen and MicroSD Card Simultaneously\" class=\"wp-image-190255\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/ESP32-CYD-TouchDisplaysdcard.jpg?w=1920&amp;quality=100&amp;strip=all&amp;ssl=1 1920w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/ESP32-CYD-TouchDisplaysdcard.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/ESP32-CYD-TouchDisplaysdcard.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/ESP32-CYD-TouchDisplaysdcard.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/ESP32-CYD-TouchDisplaysdcard.jpg?resize=1536%2C864&amp;quality=100&amp;strip=all&amp;ssl=1 1536w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p>Although this is a basic example, it provides a solid foundation for understanding how to combine these features. Using all three functions simultaneously on the CYD board is not as straightforward as it seems due to hardware\/library limitations related to the SPI communication protocol. This approach was tested on the <a href=\"https:\/\/makeradvisor.com\/tools\/cyd-cheap-yellow-display-esp32-2432s028r\/\" target=\"_blank\" rel=\"noopener\" title=\"\">ESP32-2432S028R \u2013 2.8 inch 240\u00d7320 with a resistive touchscreen<\/a>.<\/p>\n\n\n\n<p class=\"rntbox rntclgray\"><strong>New to the ESP32 CYD board?<\/strong> Get Started with this guide: <a href=\"https:\/\/randomnerdtutorials.com\/cheap-yellow-display-esp32-2432s028r\/\">Getting Started with ESP32 Cheap Yellow Display Board \u2013 CYD (ESP32-2432S028R)<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>Before proceeding, make sure you follow the next prerequisites.<strong> You must follow all steps, otherwise, your project will not work.<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1) Install ESP32 Boards in Arduino IDE<\/h3>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"204\" height=\"204\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/arduino-ide-2.jpg?resize=204%2C204&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Arduino IDE 2 Logo\" class=\"wp-image-159109\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/arduino-ide-2.jpg?w=204&amp;quality=100&amp;strip=all&amp;ssl=1 204w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/arduino-ide-2.jpg?resize=150%2C150&amp;quality=100&amp;strip=all&amp;ssl=1 150w\" sizes=\"(max-width: 204px) 100vw, 204px\" \/><\/figure><\/div>\n\n\n<p>We&#8217;ll program the ESP32 using Arduino IDE. Make sure you have the ESP32 boards installed. Follow the next tutorial:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/installing-esp32-arduino-ide-2-0\/\" title=\"\">Installing ESP32 Board in Arduino IDE 2 (Windows, Mac OS X, Linux)<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2) Install TFT and LVGL Libraries<\/h3>\n\n\n\n<p><a href=\"https:\/\/docs.lvgl.io\/master\/\" target=\"_blank\" rel=\"noreferrer noopener\">LVGL<\/a>&nbsp;(Light and Versatile Graphics Library) is a free and open-source graphics library that provides a wide range of easy-to-use graphical elements for your microcontroller projects that require a graphical user interface (GUI).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"622\" height=\"194\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/LVGL-new-logo.png?resize=622%2C194&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"LVGL new logo\" class=\"wp-image-161339\" style=\"width:340px;height:auto\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/LVGL-new-logo.png?w=622&amp;quality=100&amp;strip=all&amp;ssl=1 622w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/LVGL-new-logo.png?resize=300%2C94&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 622px) 100vw, 622px\" \/><\/figure><\/div>\n\n\n<p>Follow the next tutorial to install and configure the required libraries to use LVGL for the <a href=\"https:\/\/makeradvisor.com\/tools\/cyd-cheap-yellow-display-esp32-2432s028r\/\" target=\"_blank\" rel=\"noopener\" title=\"\">ESP32 Cheap Yellow Display<\/a> using Arduino IDE.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/lvgl-cheap-yellow-display-esp32-2432s028r\/\" title=\"\"><strong>Get started with LVGL using the ESP32 Cheap Yellow Display Board (ESP32-2432S028R)<\/strong><\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">The MicroSD Card and SPI Communication<\/h2>\n\n\n\n<p>Before diving into the example, it\u2019s important to review some key points about the SPI communication protocol on ESP32 boards, particularly the CYD.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/ESP32-CYD-microSD-card.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 CYD with microSD card\" class=\"wp-image-190237\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/ESP32-CYD-microSD-card.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/ESP32-CYD-microSD-card.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>The ESP32 supports two separate SPI buses: VSPI and HSPI. These are the default pins for VSPI and HSPI.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>SPI<\/strong><\/td><td><strong>MOSI<\/strong><\/td><td><strong>MISO<\/strong><\/td><td><strong>SCLK<\/strong><\/td><td><strong>CS<\/strong><\/td><\/tr><tr><td><strong>VSPI<\/strong><\/td><td>GPIO 23<\/td><td>GPIO 19<\/td><td>GPIO 18<\/td><td>GPIO 5<\/td><\/tr><tr><td><strong>HSPI<\/strong><\/td><td>GPIO 13<\/td><td>GPIO 12<\/td><td>GPIO 14<\/td><td>GPIO 15<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"rntbox rntclblue\">Recommended reading: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-spi-communication-arduino\/\">ESP32 SPI Communication: Set Pins, Multiple SPI Bus Interfaces, and Peripherals (Arduino IDE)<\/a>.<\/p>\n\n\n\n<p>The microSD card on the CYD uses the default VSPI pins:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>MicroSD card<\/strong><\/td><td><strong>GPIO<\/strong><\/td><\/tr><tr><td><strong>MOSI<\/strong><\/td><td>GPIO 23<\/td><\/tr><tr><td><strong>MISO<\/strong><\/td><td>GPIO 19<\/td><\/tr><tr><td><strong>SCLK<\/strong><\/td><td>GPIO 18<\/td><\/tr><tr><td><strong>CS<\/strong><\/td><td>GPIO 5<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"rntbox rntclgreen\">Recommended reading: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-microsd-card-arduino\/\">ESP32 Guide for MicroSD Card Module (Arduino IDE)<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Shared SPI Bus<\/h3>\n\n\n\n<p>Both the display and touchscreen use the SPI communication protocol. In our examples, the display library is configured to use the HSPI bus, while the touchscreen library uses the VSPI bus. This becomes problematic because the <strong>microSD card also uses the VSPI bus (on the default hardware pins), creating a conflict<\/strong>.<\/p>\n\n\n\n<p>At first glance, this may not seem like a problem. After all, multiple devices can share the same SPI bus if each one has its own CS (Chip Select) pin.<\/p>\n\n\n\n<p>HOWEVER, the issue arises with the touchscreen, which continuously listens for touch events. Temporarily disabling it while accessing the microSD card isn\u2019t ideal. Additionally, many users report this approach doesn&#8217;t work reliably.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Software SPI for the touchscreen<\/h3>\n\n\n\n<p>So, what can we do about this?<\/p>\n\n\n\n<p>We know that the ESP32 allows the use of Software SPI (SoftSPI) on any available pins. To solve the conflict, we can use a modified version of the <span class=\"rnthl rntliteral\">XPT2046_Touchscreen<\/span> library that communicates over SoftSPI instead of hardware SPI. This lets us separate the touchscreen from the VSPI bus and avoid conflicts with the microSD card.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Download the XPT2046_TouchscreenSOFTSPI library<\/h2>\n\n\n\n<p>We\u2019ll call this modified version of the library <span class=\"rnthl rntliteral\">XPT2046_TouchscreenSOFTSPI<\/span>. This library also needs the <span class=\"rnthl rntliteral\">SoftSPI<\/span> library, which we\u2019ll also install locally.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-TFT-Touchscreen\/raw\/refs\/heads\/main\/examples\/ESP32_CYD_Micro_SD_Card_Display_Touchscreen\/ESP32_CYD_Micro_SD_Card_Display_Touchscreen.zip\" target=\"_blank\" rel=\"noopener\" title=\"\"><strong>Click here to download all the project files<\/strong><\/a> (including the main sketch)<\/li>\n<\/ul>\n\n\n\n<p>This link should download a <em>.zip<\/em> folder with the following files:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>XPT2046_TouchscreenSOFTSPI.cpp<\/li>\n\n\n\n<li>XPT2046_TouchscreenSOFTSPI.h<\/li>\n\n\n\n<li>SoftSPI.cpp<\/li>\n\n\n\n<li>SoftSPI.h<\/li>\n\n\n\n<li>The Arduino sketch<\/li>\n<\/ul>\n\n\n\n<p>Unzip the folder.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Moving the Library Files to the Sketch Folder<\/h3>\n\n\n\n<p>The previous folder already contains all the files to run the example. However, if you\u2019re starting a project from scratch, you\u2019ll need to move the library files to the sketch folder, as we\u2019ll explain next.<\/p>\n\n\n\n<p><strong>1) <\/strong>Open Arduino IDE. Save the current sketch folder (even if empty). File &gt; Save as\u2026 to save it to a desired location.<\/p>\n\n\n\n<p><strong>2)<\/strong> Go to <strong>Sketch<\/strong> &gt; <strong>Show Sketch Folder<\/strong>. This will open your current sketch folder. You should move those four library files into this folder.<\/p>\n\n\n\n<p><strong>3)<\/strong> Your Arduino sketch folder should look like this.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"706\" height=\"340\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/03\/XPT2046_TouchscreenSOFTSPI-library-files-arduino-ide-project.png?resize=706%2C340&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"XPT2046_TouchscreenSOFTSPI library files Arduino IDE Project Folder structure\" class=\"wp-image-193505\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/03\/XPT2046_TouchscreenSOFTSPI-library-files-arduino-ide-project.png?w=706&amp;quality=100&amp;strip=all&amp;ssl=1 706w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/03\/XPT2046_TouchscreenSOFTSPI-library-files-arduino-ide-project.png?resize=300%2C144&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 706px) 100vw, 706px\" \/><\/figure><\/div>\n\n\n<p><strong>4)<\/strong> After moving the files, restart Arduino IDE.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example Sketch (Display + Touchscreen + MicroSD Card)<\/h2>\n\n\n\n<p>After having all the required library files in the sketch folder, you can write your Arduino sketch. This is the example that we\u2019ll be running.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*  Rui Santos &amp; Sara Santos - Random Nerd Tutorials - https:\/\/RandomNerdTutorials.com\/esp32-cyd-display-touchscreen-microsd-card\/\n    THIS EXAMPLE WAS TESTED WITH THE FOLLOWING HARDWARE:\n    1) ESP32-2432S028R 2.8 inch 240\u00d7320 also known as the Cheap Yellow Display (CYD): https:\/\/makeradvisor.com\/tools\/cyd-cheap-yellow-display-esp32-2432s028r\/\n      SET UP INSTRUCTIONS: https:\/\/RandomNerdTutorials.com\/cyd-lvgl\/\n    2) REGULAR ESP32 Dev Board + 2.8 inch 240x320 TFT Display: https:\/\/makeradvisor.com\/tools\/2-8-inch-ili9341-tft-240x320\/ and https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\n      SET UP INSTRUCTIONS: https:\/\/RandomNerdTutorials.com\/esp32-tft-lvgl\/\n    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.\n    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n*\/\n\n#include &lt;SPI.h&gt;\n\/*  Install the &quot;TFT_eSPI&quot; library by Bodmer to interface with the TFT Display - https:\/\/github.com\/Bodmer\/TFT_eSPI\n    *** IMPORTANT: User_Setup.h available on the internet will probably NOT work with the examples available at Random Nerd Tutorials ***\n    *** YOU MUST USE THE User_Setup.h FILE PROVIDED IN THE LINK BELOW IN ORDER TO USE THE EXAMPLES FROM RANDOM NERD TUTORIALS ***\n    FULL INSTRUCTIONS AVAILABLE ON HOW CONFIGURE THE LIBRARY: https:\/\/RandomNerdTutorials.com\/cyd-lvgl\/ or https:\/\/RandomNerdTutorials.com\/esp32-tft-lvgl\/   *\/\n#include &lt;TFT_eSPI.h&gt;\n\n\/\/ Copy the &quot;XPT2046_TouchscreenSOFTSPI.h&quot; library provided in the project page: https:\/\/RandomNerdTutorials.com\/esp32-cyd-display-touchscreen-microsd-card\/\n#include &lt;XPT2046_TouchscreenSOFTSPI.h&gt;\n\n\/\/ Touchscreen pins\n#define XPT2046_IRQ 36   \/\/ T_IRQ\n#define XPT2046_MOSI 32  \/\/ T_DIN\n#define XPT2046_MISO 39  \/\/ T_OUT\n#define XPT2046_CLK 25   \/\/ T_CLK\n#define XPT2046_CS 33    \/\/ T_CS\n\nSoftSPI *tsSoftSpi;\n\/\/ Set touch screen to use SOftSpi\nXPT2046_TouchscreenSOFTSPI touchscreen(XPT2046_CS, XPT2046_IRQ);\n\n\/*  Install the &quot;lvgl&quot; library version 9.X by kisvegabor to interface with the TFT Display - https:\/\/lvgl.io\/\n    *** IMPORTANT: lv_conf.h available on the internet will probably NOT work with the examples available at Random Nerd Tutorials ***\n    *** YOU MUST USE THE lv_conf.h FILE PROVIDED IN THE LINK BELOW IN ORDER TO USE THE EXAMPLES FROM RANDOM NERD TUTORIALS ***\n    FULL INSTRUCTIONS AVAILABLE ON HOW CONFIGURE THE LIBRARY: https:\/\/RandomNerdTutorials.com\/cyd-lvgl\/ or https:\/\/RandomNerdTutorials.com\/esp32-tft-lvgl\/   *\/\n#include &lt;lvgl.h&gt;\n\n#include &quot;FS.h&quot;\n#include &quot;SD.h&quot;\n\n\/\/ SD Reader pins (default VSPI pins)\n#define SD_MISO  19\n#define SD_MOSI  23\n#define SD_SCK  18\n#define SD_CS  5\nSPIClass Sd_spi = SPIClass(VSPI);\n\n#define SCREEN_WIDTH 240\n#define SCREEN_HEIGHT 320\n\n\/\/ Touchscreen coordinates: (x, y) and pressure (z)\nint x, y, z;\n\n#define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT \/ 10 * (LV_COLOR_DEPTH \/ 8))\nuint32_t draw_buf[DRAW_BUF_SIZE \/ 4];\n\n\/\/ If logging is enabled, it will inform the user about what is happening in the library\nvoid log_print(lv_log_level_t level, const char * buf) {\n  LV_UNUSED(level);\n  Serial.println(buf);\n  Serial.flush();\n}\n\nstatic lv_obj_t * text_label_touch;\n\nvoid listDir(fs::FS &amp;fs, const char * dirname, uint8_t levels){\n  Serial.printf(&quot;Listing directory: %s\\n&quot;, dirname);\n\n  File root = fs.open(dirname);\n  if(!root){\n    Serial.println(&quot;Failed to open directory&quot;);\n    return;\n  }\n  if(!root.isDirectory()){\n    Serial.println(&quot;Not a directory&quot;);\n    return;\n  }\n\n  File file = root.openNextFile();\n  while(file){\n    if(file.isDirectory()){\n      Serial.print(&quot;  DIR : &quot;);\n      Serial.println(file.name());\n      if(levels){\n        listDir(fs, file.name(), levels -1);\n      }\n    } else {\n      Serial.print(&quot;  FILE: &quot;);\n      Serial.print(file.name());\n      Serial.print(&quot;  SIZE: &quot;);\n      Serial.println(file.size());\n    }\n    file = root.openNextFile();\n  }\n}\n\nvoid createDir(fs::FS &amp;fs, const char * path){\n  Serial.printf(&quot;Creating Dir: %s\\n&quot;, path);\n  if(fs.mkdir(path)){\n    Serial.println(&quot;Dir created&quot;);\n  } else {\n    Serial.println(&quot;mkdir failed&quot;);\n  }\n}\n\nvoid removeDir(fs::FS &amp;fs, const char * path){\n  Serial.printf(&quot;Removing Dir: %s\\n&quot;, path);\n  if(fs.rmdir(path)){\n    Serial.println(&quot;Dir removed&quot;);\n  } else {\n    Serial.println(&quot;rmdir failed&quot;);\n  }\n}\n\nvoid readFile(fs::FS &amp;fs, const char * path){\n  Serial.printf(&quot;Reading file: %s\\n&quot;, path);\n\n  File file = fs.open(path);\n  if(!file){\n    Serial.println(&quot;Failed to open file for reading&quot;);\n    return;\n  }\n\n  Serial.print(&quot;Read from file: &quot;);\n  while(file.available()){\n    Serial.write(file.read());\n  }\n  file.close();\n}\n\nvoid writeFile(fs::FS &amp;fs, const char * path, const char * message){\n  Serial.printf(&quot;Writing file: %s\\n&quot;, path);\n\n  File file = fs.open(path, FILE_WRITE);\n  if(!file){\n    Serial.println(&quot;Failed to open file for writing&quot;);\n    return;\n  }\n  if(file.print(message)){\n    Serial.println(&quot;File written&quot;);\n  } else {\n    Serial.println(&quot;Write failed&quot;);\n  }\n  file.close();\n}\n\nvoid appendFile(fs::FS &amp;fs, const char * path, const char * message){\n  Serial.printf(&quot;Appending to file: %s\\n&quot;, path);\n\n  File file = fs.open(path, FILE_APPEND);\n  if(!file){\n    Serial.println(&quot;Failed to open file for appending&quot;);\n    return;\n  }\n  if(file.print(message)){\n      Serial.println(&quot;Message appended&quot;);\n  } else {\n    Serial.println(&quot;Append failed&quot;);\n  }\n  file.close();\n}\n\nvoid deleteFile(fs::FS &amp;fs, const char * path){\n  Serial.printf(&quot;Deleting file: %s\\n&quot;, path);\n  if(fs.remove(path)){\n    Serial.println(&quot;File deleted&quot;);\n  } else {\n    Serial.println(&quot;Delete failed&quot;);\n  }\n}\n\n\/\/ Get the Touchscreen data\nvoid touchscreen_read(lv_indev_t * indev, lv_indev_data_t * data) {\n  \/\/ Checks if Touchscreen was touched, and prints X, Y and Pressure (Z)\n  if(touchscreen.tirqTouched() &amp;&amp; touchscreen.touched(tsSoftSpi)) {\n    \/\/ Get Touchscreen points\n    TS_Point p = touchscreen.getPoint(tsSoftSpi);\n    \/\/ Calibrate Touchscreen points with map function to the correct width and height\n    x = map(p.x, 200, 3700, 1, SCREEN_WIDTH);\n    y = map(p.y, 240, 3800, 1, SCREEN_HEIGHT);\n    z = p.z;\n\n    data-&gt;state = LV_INDEV_STATE_PRESSED;\n\n    \/\/ Set the coordinates\n    data-&gt;point.x = x;\n    data-&gt;point.y = y;\n\n    \/\/ Print Touchscreen info about X, Y and Pressure (Z) on the Serial Monitor\n    Serial.print(&quot;X = &quot;);\n    Serial.print(x);\n    Serial.print(&quot; | Y = &quot;);\n    Serial.print(y);\n    Serial.print(&quot; | Pressure = &quot;);\n    Serial.print(z);\n    Serial.println();\n    String touch_data = &quot;X = &quot; + String(x) + &quot;\\nY = &quot; + String(y) + &quot;\\nZ = &quot; + String(z);\n    lv_label_set_text(text_label_touch, touch_data.c_str());\n\n    String sdMessage = String(x) + &quot;,&quot; + String(y) + &quot;,&quot; + String(z) + &quot;\\n&quot;;\n    appendFile(SD, &quot;\/touch_points.txt&quot;, sdMessage.c_str());\n  }\n  else {\n    data-&gt;state = LV_INDEV_STATE_RELEASED;\n  }\n}\n\nvoid lv_create_main_gui(void) {\n  \/\/ Create a text label aligned center: https:\/\/docs.lvgl.io\/master\/widgets\/label.html\n  text_label_touch = lv_label_create(lv_screen_active());\n  lv_label_set_text(text_label_touch, &quot;Touch screen to test&quot;);\n  lv_obj_align(text_label_touch, LV_ALIGN_CENTER, 0, 0);\n\n  \/\/ Set font type and size. More information: https:\/\/docs.lvgl.io\/master\/overview\/font.html\n  static lv_style_t style_text_label;\n  lv_style_init(&amp;style_text_label);\n  lv_style_set_text_font(&amp;style_text_label, &amp;lv_font_montserrat_18);\n  lv_obj_add_style(text_label_touch, &amp;style_text_label, 0);\n}\n\nvoid setup() {\n  Serial.begin(115200);\n  String LVGL_Arduino = String(&quot;LVGL Library Version: &quot;) + lv_version_major() + &quot;.&quot; + lv_version_minor() + &quot;.&quot; + lv_version_patch();\n\n  while (!Serial &amp;&amp; (millis() &lt;= 1500));\n  delay (1000);\n\n  Serial.println(LVGL_Arduino);\n\n  Serial.print(&quot;\\nInitializing SD card...\\n&quot;);\n\n  Sd_spi.begin(SD_SCK, SD_MISO, SD_MOSI, SD_CS);\n\n  if (!SD.begin(SD_CS, Sd_spi, 55000000)) {\n    Serial.println(&quot;Card Mount Failed&quot;);\n  }\n \n  uint8_t cardType = SD.cardType();\n\n  if(cardType == CARD_NONE){\n    Serial.println(&quot;No SD card attached&quot;);\n    return;\n  }\n\n  Serial.print(&quot;SD Card Type: &quot;);\n  if(cardType == CARD_MMC){\n    Serial.println(&quot;MMC&quot;);\n  } else if(cardType == CARD_SD){\n    Serial.println(&quot;SDSC&quot;);\n  } else if(cardType == CARD_SDHC){\n    Serial.println(&quot;SDHC&quot;);\n  } else {\n    Serial.println(&quot;UNKNOWN&quot;);\n  }\n\n  uint64_t cardSize = SD.cardSize() \/ (1024 * 1024);\n  Serial.printf(&quot;SD Card Size: %lluMB\\n&quot;, cardSize);\n\n  listDir(SD, &quot;\/&quot;, 0);\n\n  \/\/ If the touch_points.txt file doesn't exist, create a file on the SD card and write the header\n  File file = SD.open(&quot;\/touch_points.txt&quot;);\n  if(!file) {\n    Serial.println(&quot;touch_points.txt file doesn't exist&quot;);\n    Serial.println(&quot;Creating file...&quot;);\n    writeFile(SD, &quot;\/touch_points.txt&quot;, &quot;x,y,z\\r\\n&quot;);\n  }\n  else {\n    Serial.println(&quot;touch_points.txt file already exists&quot;);  \n  }\n  file.close();\n\n  lv_init();\n  \/\/ Register print function for debugging\n  lv_log_register_print_cb(log_print);\n\n  \/\/ Create a Softspi Object and set its SPI pins\n  tsSoftSpi = new SoftSPI (XPT2046_MOSI, XPT2046_MISO, XPT2046_CLK);\n\n  \/\/ Start the SPI for the touchscreen and init the touchscreen\n  touchscreen.begin(tsSoftSpi);\n\n  \/\/ Set the Touchscreen rotation in landscape mode\n  \/\/ Note: in some displays, the touchscreen might be upside down, so you might need to set the rotation to 0: touchscreen.setRotation(0);\n  touchscreen.setRotation(2);\n\n  \/\/ Create a display object\n  lv_display_t * disp;\n  \/\/ Initialize the TFT display using the TFT_eSPI library\n  disp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));\n  lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270);\n\n  \/\/ Initialize an LVGL input device object (Touchscreen)\n  lv_indev_t * indev = lv_indev_create();\n  lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);\n\n  \/\/ Set the callback function to read Touchscreen input\n  lv_indev_set_read_cb(indev, touchscreen_read);\n\n  lv_create_main_gui();\n}\n\nvoid loop() {\n  lv_task_handler();  \/\/ let the GUI do its work\n  lv_tick_inc(5);     \/\/ tell LVGL how much time has passed\n  delay(5);           \/\/ let this time pass\n }<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-TFT-Touchscreen\/raw\/main\/examples\/ESP32_CYD_Micro_SD_Card_Display_Touchscreen\/ESP32_CYD_Micro_SD_Card_Display_Touchscreen.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How Does the Code Work?<\/h3>\n\n\n\n<p>This code is not much different from the example in <a href=\"https:\/\/randomnerdtutorials.com\/cheap-yellow-display-esp32-2432s028r\/\" title=\"\">this previous tutorial<\/a>.<\/p>\n\n\n\n<p>We&#8217;ve just added the lines of code to interface with the microSD card, save the touchpoints, and initialize the touchscreen using the modified library.<\/p>\n\n\n\n<p>We\u2019ll take a look at the relevant parts of code to show how to use the display, touschscreen and microSD card simultaneously,<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Import the XPT2046_TouchscreenSOFTSPI library<\/h4>\n\n\n\n<p>We import the modified version of the touchscreen library:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;XPT2046_TouchscreenSOFTSPI.h&gt;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Create a SoftSPI Instance<\/h4>\n\n\n\n<p>We create a new instance of <span class=\"rnthl rntliteral\">SoftSPI<\/span> to initialize the touchscreen via software instead of hardware VSPI later on.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>SoftSPI *tsSoftSpi;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Create a Touchscreen Object<\/h4>\n\n\n\n<p>We create a new touchscreen object using the modified version of the library.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>XPT2046_TouchscreenSOFTSPI touchscreen(XPT2046_CS, XPT2046_IRQ);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Import Libraries for the MicroSD Card<\/h4>\n\n\n\n<p>We import the <span class=\"rnthl rntliteral\">FS<\/span> and <span class=\"rnthl rntliteral\">SD<\/span> libraries, needed to handle files on the microSD card.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include \"FS.h\"\n#include \"SD.h\"<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">MicroSD Card SPI Pins and Bus<\/h4>\n\n\n\n<p>We define the pins for the microSD card (default VSPI pins), and create a new SPI instance on VSPI with those pins.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define SD_MISO &nbsp;19\n#define SD_MOSI &nbsp;23\n#define SD_SCK &nbsp;18\n#define SD_CS &nbsp;5\nSPIClass Sd_spi = SPIClass(VSPI);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">MicroSD Card Functions<\/h4>\n\n\n\n<p>We then have several defined functions to interact with the microSD card. We won\u2019t use them all, but we\u2019re leaving them in this example so that you know which functions are available. The names of the functions are pretty self-explanatory.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void listDir(fs::FS &amp;fs, const char * dirname, uint8_t levels){\n  Serial.printf(\"Listing directory: %s\\n\", dirname);\n\n  File root = fs.open(dirname);\n  if(!root){\n    Serial.println(\"Failed to open directory\");\n    return;\n  }\n  if(!root.isDirectory()){\n    Serial.println(\"Not a directory\");\n    return;\n  }\n\n  File file = root.openNextFile();\n  while(file){\n    if(file.isDirectory()){\n      Serial.print(\"  DIR : \");\n      Serial.println(file.name());\n      if(levels){\n        listDir(fs, file.name(), levels -1);\n      }\n    } else {\n      Serial.print(\"  FILE: \");\n      Serial.print(file.name());\n      Serial.print(\"  SIZE: \");\n      Serial.println(file.size());\n    }\n    file = root.openNextFile();\n  }\n}\n\nvoid createDir(fs::FS &amp;fs, const char * path){\n  Serial.printf(\"Creating Dir: %s\\n\", path);\n  if(fs.mkdir(path)){\n    Serial.println(\"Dir created\");\n  } else {\n    Serial.println(\"mkdir failed\");\n  }\n}\n\nvoid removeDir(fs::FS &amp;fs, const char * path){\n  Serial.printf(\"Removing Dir: %s\\n\", path);\n  if(fs.rmdir(path)){\n    Serial.println(\"Dir removed\");\n  } else {\n    Serial.println(\"rmdir failed\");\n  }\n}\n\nvoid readFile(fs::FS &amp;fs, const char * path){\n  Serial.printf(\"Reading file: %s\\n\", path);\n\n  File file = fs.open(path);\n  if(!file){\n    Serial.println(\"Failed to open file for reading\");\n    return;\n  }\n\n  Serial.print(\"Read from file: \");\n  while(file.available()){\n    Serial.write(file.read());\n  }\n  file.close();\n}\n\nvoid writeFile(fs::FS &amp;fs, const char * path, const char * message){\n  Serial.printf(\"Writing file: %s\\n\", path);\n\n  File file = fs.open(path, FILE_WRITE);\n  if(!file){\n    Serial.println(\"Failed to open file for writing\");\n    return;\n  }\n  if(file.print(message)){\n    Serial.println(\"File written\");\n  } else {\n    Serial.println(\"Write failed\");\n  }\n  file.close();\n}\n\nvoid appendFile(fs::FS &amp;fs, const char * path, const char * message){\n  Serial.printf(\"Appending to file: %s\\n\", path);\n\n  File file = fs.open(path, FILE_APPEND);\n  if(!file){\n    Serial.println(\"Failed to open file for appending\");\n    return;\n  }\n  if(file.print(message)){\n      Serial.println(\"Message appended\");\n  } else {\n    Serial.println(\"Append failed\");\n  }\n  file.close();\n}\n\nvoid deleteFile(fs::FS &amp;fs, const char * path){\n  Serial.printf(\"Deleting file: %s\\n\", path);\n  if(fs.remove(path)){\n    Serial.println(\"File deleted\");\n  } else {\n    Serial.println(\"Delete failed\");\n  }\n}<\/code><\/pre>\n\n\n\n<p>Additionally, we recommend taking a look at our microSD card guide for more details about interfacing a microSD card with the ESP32.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-microsd-card-arduino\/\">ESP32: Guide for MicroSD Card Module (Arduino IDE)<\/a><\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">setup()<\/h4>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">setup()<\/span>, we need to add the following lines to initialize the microSD card:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>Serial.print(\"\\nInitializing SD card...\\n\");\n\nSd_spi.begin(SD_SCK, SD_MISO, SD_MOSI, SD_CS);\n\nif (!SD.begin(SD_CS, Sd_spi, 55000000)) {\n&nbsp; Serial.println(\"Card Mount Failed\");\n}<\/code><\/pre>\n\n\n\n<p>We also print information about the microSD card type, size, and currently saved files.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>uint8_t cardType = SD.cardType();\n\nif(cardType == CARD_NONE){\n  Serial.println(\"No SD card attached\");\n  return;\n}\n\nSerial.print(\"SD Card Type: \");\nif(cardType == CARD_MMC){\n  Serial.println(\"MMC\");\n} else if(cardType == CARD_SD){\n  Serial.println(\"SDSC\");\n} else if(cardType == CARD_SDHC){\n  Serial.println(\"SDHC\");\n} else {\n  Serial.println(\"UNKNOWN\");\n}\n\n  uint64_t cardSize = SD.cardSize() \/ (1024 * 1024);\n  Serial.printf(\"SD Card Size: %lluMB\\n\", cardSize);\n\n  listDir(SD, \"\/\", 0);<\/code><\/pre>\n\n\n\n<p>Then, we create a new file on the microSD card called <span class=\"rnthl rntliteral\">touch_point.txt<\/span> to save the touch points, if it doesn\u2019t already exist. We also create the headers for the file.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ If the touch_points.txt file doesn't exist\n\/\/create a file on the SD card and write the header\nFile file = SD.open(\"\/touch_points.txt\");\nif(!file) {\n  Serial.println(\"touch_points.txt file doesn't exist\");\n  Serial.println(\"Creating file...\");\n  writeFile(SD, \"\/touch_points.txt\", \"x,y,z\\r\\n\");\n}\nelse {\n  Serial.println(\"touch_points.txt file already exists\");  \n}\nfile.close();<\/code><\/pre>\n\n\n\n<p>Still in the <span class=\"rnthl rntliteral\">setup()<\/span>, we need to initialize the touchscreen using Software SPI.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Create a Softspi Object and set its SPI pins\ntsSoftSpi = new SoftSPI (XPT2046_MOSI, XPT2046_MISO, XPT2046_CLK);\n\n\/\/ Start the SPI for the touchscreen and init the touchscreen\ntouchscreen.begin(tsSoftSpi);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Saving the Touch Points to the MicroSD Card<\/h4>\n\n\n\n<p>Another change we need to make is to add the lines of code to save the touchpoints to the microSD card. We can do that on the <span class=\"rnthl rntliteral\">touchscreen_read()<\/span> function.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Get the Touchscreen data\nvoid touchscreen_read(lv_indev_t * indev, lv_indev_data_t * data) {\n  \/\/ Checks if Touchscreen was touched, and prints X, Y and Pressure (Z)\n  if(touchscreen.tirqTouched() &amp;&amp; touchscreen.touched(tsSoftSpi)) {\n    \/\/ Get Touchscreen points\n    TS_Point p = touchscreen.getPoint(tsSoftSpi);\n    \/\/ Calibrate Touchscreen points with map function to the correct width and height\n    x = map(p.x, 200, 3700, 1, SCREEN_WIDTH);\n    y = map(p.y, 240, 3800, 1, SCREEN_HEIGHT);\n    z = p.z;\n\n    data-&gt;state = LV_INDEV_STATE_PRESSED;\n\n    \/\/ Set the coordinates\n    data-&gt;point.x = x;\n    data-&gt;point.y = y;\n\n    \/\/ Print Touchscreen info about X, Y and Pressure (Z) on the Serial Monitor\n    Serial.print(\"X = \");\n    Serial.print(x);\n    Serial.print(\" | Y = \");\n    Serial.print(y);\n    Serial.print(\" | Pressure = \");\n    Serial.print(z);\n    Serial.println();\n    String touch_data = \"X = \" + String(x) + \"\\nY = \" + String(y) \n                      + \"\\nZ = \" + String(z);\n    lv_label_set_text(text_label_touch, touch_data.c_str());\n\n    String sdMessage = String(x) + \",\" + String(y) + \",\" + String(z) + \"\\n\";\n    appendFile(SD, \"\/touch_points.txt\", sdMessage.c_str());\n  }\n  else {\n    data-&gt;state = LV_INDEV_STATE_RELEASED;\n  }\n}<\/code><\/pre>\n\n\n\n<p>After detecting touch and saving the data points and pressure on the <span class=\"rnthl rntliteral\">x<\/span>, <span class=\"rnthl rntliteral\">y<\/span>, and <span class=\"rnthl rntliteral\">z<\/span> variables, we can save them to the file on the microSD card as follows.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String sdMessage = String(x) + \",\" + String(y) + \",\" + String(z) + \"\\n\";\nappendFile(SD, \"\/touch_points.txt\", sdMessage.c_str());<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Demonstration<\/h2>\n\n\n\n<p>Now, you can upload the code to your CYD board.<\/p>\n\n\n\n<p>Make sure you have the required files to use <span class=\"rnthl rntliteral\">SoftSPI<\/span> for the touchscreen in your sketch folder.<\/p>\n\n\n\n<p>Those files should be available as tabs in your Arduino IDE project (if not, it means they are not in the correct location).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"822\" height=\"320\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/CYD-using-modified-touch-library.png?resize=822%2C320&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"CYD using modified touch library on Arduino IDE\" class=\"wp-image-190248\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/CYD-using-modified-touch-library.png?w=822&amp;quality=100&amp;strip=all&amp;ssl=1 822w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/CYD-using-modified-touch-library.png?resize=300%2C117&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/CYD-using-modified-touch-library.png?resize=768%2C299&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/figure><\/div>\n\n\n<p>After uploading the code, touch on a few random points on the screen. The screen will show the touched points. At the same time, those points will be saved on the microSD card.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"423\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/touch-CYD-display-points-testing.jpg?resize=750%2C423&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 CYD board testing touchscreen\" class=\"wp-image-190250\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/touch-CYD-display-points-testing.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/touch-CYD-display-points-testing.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>After touching a few number of points, you can remove the microSD card from the CYD and insert it into your computer.<\/p>\n\n\n\n<p>It should have a file called <span class=\"rnthl rntliteral\">touch_points.txt<\/span>. You can open that file to check which points were saved to the microSD card.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"610\" height=\"460\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/CYD-save-touchpoints-microsdcard.png?resize=610%2C460&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 CYD board saving touch points on a file\" class=\"wp-image-190251\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/CYD-save-touchpoints-microsdcard.png?w=610&amp;quality=100&amp;strip=all&amp;ssl=1 610w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/CYD-save-touchpoints-microsdcard.png?resize=300%2C226&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 610px) 100vw, 610px\" \/><\/figure><\/div>\n\n\n<p>Now, you know which tricks you need to do to be able to use the microSD card, touchscreen, and display simultaneously.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">When You Don\u2019t Need to Use the Modified Touchscreen Library?<\/h2>\n\n\n\n<p>Finally, I would like to clarify that you only need to use the modified touchscreen library when using these three things simultaneously: screen, touchscreen, and microSD card. <\/p>\n\n\n\n<p>If the microSD card and the touchscreen are not used on the same project, there\u2019s no need to use the modified version of the touchscreen library. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>If you&#8217;re using the <a href=\"https:\/\/makeradvisor.com\/tools\/cyd-cheap-yellow-display-esp32-2432s028r\/\" target=\"_blank\" rel=\"noopener\" title=\"\">ESP32-2432S028R \u2013 2.8 inch 240\u00d7320 with a resistive touchscreen<\/a> CYD board, you may find some issues when trying to use the microSD card, touchscreen, and the display simultaneously because all three components use the SPI communication protocol.<\/p>\n\n\n\n<p>In this guide, we&#8217;ve shown you a simple trick you can use if you want to use the three features together in your project.<\/p>\n\n\n\n<p>We hope this quick guide was helpful.<\/p>\n\n\n\n<p>If you want to learn more about controlling the CYD display and creating awesome ESP32 projects with a nice graphical user interface, check out our eBook:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/randomnerdtutorials.com\/learn-lvgl-esp32-ebook\/\">Learn LVGL: Build GUIs for ESP32 Projects\u200b<\/a><\/strong><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, we\u2019ll show you how to use the display, touchscreen, and microSD card all at once with the ESP32 CYD (Cheap Yellow Display) board. We&#8217;ll build a simple &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP32 CYD: Use Display, Touchscreen and MicroSD Card Simultaneously\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-cyd-display-touchscreen-microsd-card\/#more-190235\" aria-label=\"Read more about ESP32 CYD: Use Display, Touchscreen and MicroSD Card Simultaneously\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":190255,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[276,281,277,299,264],"tags":[],"class_list":["post-190235","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32","category-esp32-project","category-esp32-arduino-ide","category-0-esp32","category-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/02\/ESP32-CYD-TouchDisplaysdcard.jpg?fit=1920%2C1080&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/190235","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=190235"}],"version-history":[{"count":8,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/190235\/revisions"}],"predecessor-version":[{"id":193510,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/190235\/revisions\/193510"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/190255"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=190235"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=190235"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=190235"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}