CYD: SD Issues, probably due to Touch pins?

CYD = Cheap Yellow Display
e.g. ESP32 Cheap Yellow Display Board (ESP32-2432S028R) | Random Nerd Tutorials
My CYD appears to be newer since it also has a USB-C port (not checked for anything else yet)

So...

The issue is, at boot I can init the SD (using SD.h not SD_MMC.h) and successfully do a list dir.
Then after initialising the screen and touch, I can no longer do a list dir, even if re-initialise.

I'm about to do some tests to try to find out where the conflict is, but does anybody else have a tried and tested solution, even if it is using a different library...

Thanks

My demo code...


//  TEST VARS
//  ==========================================
int delay_extra = 1000;
int use_touch_register = 1;
int use_touch_callback = 0;


//  SD CARD
//  ==========================================
#include "FS.h"
#include "SD.h"
#include "SPI.h"

#define SPI_SCK 18
#define SPI_MISO 19
#define SPI_MOSI 23
#define SPI_SS_SD 5

void init_sd();
void listDir(fs::FS &fs, const char * dirname, uint8_t levels);


//  DISPLAY & TOUCH
//  ==========================================
#include <lvgl.h>
#include <TFT_eSPI.h> //  Install the "TFT_eSPI" library by Bodmer
#include <XPT2046_Touchscreen.h>  //  Install the "XPT2046_Touchscreen" library by Paul Stoffregen

// Touchscreen pins
#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
SPIClass touchscreenSPI = SPIClass(VSPI);
XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);
#define SCREEN_WIDTH 320    //  TFT_HOR_RES, TFT_VER_RES
#define SCREEN_HEIGHT 240
int x, y, z;  // Touchscreen coords: (x, y) and pressure (z)
#define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8))
uint32_t draw_buf[DRAW_BUF_SIZE / 4];


void ui_create(void);
void log_print(lv_log_level_t level, const char * buf);
void touchscreen_read(lv_indev_t * indev, lv_indev_data_t * data);
void ui_init(void);


void setup()
{
  //  INIT SERIAL
  Serial.begin(115200);
  delay(101);
  Serial.println("INIT");

  init_sd();
  ui_init();

  Serial.println("INIT END");
}

void loop() {
  lv_task_handler();  // let the GUI do its work
  lv_tick_inc(5);     // tell LVGL how much time has passed + delay_extra?
  //ldr_echo();
  listDir(SD, "/", 1);

  delay(delay_extra);
  delay(5);
}


//  SD CARD
//  ==========================================
void init_sd()
{
  //if(!SD.begin(5))
  //if(!SD.begin())
  if(!SD.begin(SPI_SS_SD))
  //if(!SD.begin(SPI_SS_SD, spi, 80000000))
  {
    Serial.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();

  if(cardType == CARD_NONE){
    Serial.println("No SD card attached");
    return;
  }

  Serial.print("SD Card Type: ");
  if(cardType == CARD_MMC){
    Serial.println("MMC");
  } else if(cardType == CARD_SD){
    Serial.println("SDSC");
  } else if(cardType == CARD_SDHC){
    Serial.println("SDHC");
  } else {
    Serial.println("UNKNOWN");
  }

  uint64_t cardSize = SD.cardSize() / (1024 * 1024);
  Serial.printf("SD Card Size: %lluMB\n", cardSize);

  listDir(SD, "/", 1);
  Serial.println("------");
  listDir(SD, "/", 1);
}

void listDir(fs::FS &fs, const char * dirname, uint8_t levels)
{
  Serial.printf("Listing directory: %s\n", dirname);

  File root = fs.open(dirname);
  if(!root){
    Serial.println("Failed to open directory");
    return;
  }
  if(!root.isDirectory()){
    Serial.println("Not a directory");
    return;
  }

  File file = root.openNextFile();
  while(file){
    if(file.isDirectory()){
      Serial.print("  DIR : ");
      Serial.println(file.name());
      if(levels){
        listDir(fs, file.name(), levels -1);
      }
    } else {
      Serial.print("  FILE: ");
      Serial.print(file.name());
      Serial.print("  SIZE: ");
      Serial.println(file.size());
    }
    file = root.openNextFile();
  }
  root.close();
}


//  DISPLAY & TOUCH
//  ==========================================

void create_panel_home(void)
{
  //  BODY_MAIN: CREATE
  lv_obj_t * c_body_home = lv_obj_create(lv_screen_active());
  lv_obj_set_size(c_body_home, 320, 240);
  lv_obj_set_flex_flow(c_body_home, LV_FLEX_FLOW_COLUMN);
  
  //  TITLE
  lv_obj_t *label2 = lv_label_create(c_body_home);
  lv_label_set_text_fmt(label2, "HELLO");
  lv_obj_center(label2);
}

void ui_create(void)
{
  //gen_styles();
  //create_menu();
  create_panel_home();
}

void log_print(lv_log_level_t level, const char * buf)
{
  LV_UNUSED(level);
  Serial.println(buf);
  Serial.flush();
}

// Get the Touchscreen data
void touchscreen_read(lv_indev_t * indev, lv_indev_data_t * data)
{
  // Checks if Touchscreen was touched, and prints X, Y and Pressure (Z)
  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
    x = map(p.x, 200, 3700, 1, SCREEN_WIDTH);
    y = map(p.y, 240, 3800, 1, SCREEN_HEIGHT);
    z = p.z;

    data->state = LV_INDEV_STATE_PRESSED;

    // Set the coordinates
    data->point.x = x;
    data->point.y = y;

    // Print Touchscreen info about X, Y and Pressure (Z) on the Serial Monitor
    //Serial.print("X = ");
    //Serial.print(x);
    //Serial.print(" | Y = ");
    //Serial.print(y);
    //Serial.print(" | Pressure = ");
    //Serial.print(z);
    //Serial.println();
  }
  else {
    data->state = LV_INDEV_STATE_RELEASED;
  }
}

void ui_init(void)
{
  
  // BOOT INFO
  String LVGL_Arduino = String("LVGL Library Version: ") + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
  Serial.println(LVGL_Arduino);
  
  //  INIT LVGL
  lv_init();
  // Register print function for debugging
  lv_log_register_print_cb(log_print);

  if(use_touch_register){
    //  INIT TOUCHSCREEN
    touchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
    touchscreen.begin(touchscreenSPI);
    // Set the Touchscreen rotation in landscape mode
    // Note: in some displays, the touchscreen might be upside down, so you might need to set the rotation to 1: touchscreen.setRotation(1);
    touchscreen.setRotation(3);
  }
  
  // Create a display object
  lv_display_t * disp;
  // Initialize the TFT display using the TFT_eSPI library
  disp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));
  
  // Initialize an LVGL input device object (Touchscreen)
  lv_indev_t * indev = lv_indev_create();
  lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);

  if(use_touch_register && use_touch_callback){
    // Set the callback function to read Touchscreen input
    lv_indev_set_read_cb(indev, touchscreen_read);
  }

  //  CREATE UI
  ui_create();
}


From discord:

This code is working, uses XPT2046_Bitbang, not tried lvgl yet but nm...

/*******************************************************************
    TFT_eSPI button example for the ESP32 Cheap Yellow Display.

    https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display

    Written by Claus Näveke
    Github: https://github.com/TheNitek
 *******************************************************************/

// Make sure to copy the UserSetup.h file into the library as
// per the Github Instructions. The pins are defined in there.

// ----------------------------
// Standard Libraries
// ----------------------------

#include <SPI.h>

// ----------------------------
// Additional Libraries - each one of these will need to be installed.
// ----------------------------

#include <XPT2046_Bitbang.h>
// A library for interfacing with the touch screen
//
// Can be installed from the library manager (Search for "XPT2046 Slim")
// https://github.com/TheNitek/XPT2046_Bitbang_Arduino_Library

#include <TFT_eSPI.h>
// A library for interfacing with LCD displays
//
// Can be installed from the library manager (Search for "TFT_eSPI")
// https://github.com/Bodmer/TFT_eSPI


// ----------------------------
// Touch Screen pins
// ----------------------------

// The CYD touch uses some non default
// SPI pins

#define XPT2046_IRQ 36
#define XPT2046_MOSI 32
#define XPT2046_MISO 39
#define XPT2046_CLK 25
#define XPT2046_CS 33
// ----------------------------

XPT2046_Bitbang ts(XPT2046_MOSI, XPT2046_MISO, XPT2046_CLK, XPT2046_CS);

TFT_eSPI tft = TFT_eSPI();

TFT_eSPI_Button key[6];


//  SD CARD
//  ==========================================
#include "FS.h"
#include "SD.h"
#include "SPI.h"
/*
#define SPI_SCK 18
#define SPI_MISO 19
#define SPI_MOSI 23
#define SPI_SS_SD 5
*/
void init_sd();
void listDir(fs::FS &fs, const char * dirname, uint8_t levels);


void setup() {
  Serial.begin(115200);

  // Start the SPI for the touch screen and init the TS library
  ts.begin();
  //ts.setRotation(1);

  // Start the tft display and set it to black
  tft.init();
  tft.setRotation(1); //This is the display in landscape

  // Clear the screen before writing to it
  tft.fillScreen(TFT_BLACK);
  tft.setFreeFont(&FreeMono18pt7b);

  drawButtons();

  init_sd();
  
}

void drawButtons() {
  uint16_t bWidth = TFT_HEIGHT/3;
  uint16_t bHeight = TFT_WIDTH/2;
  // Generate buttons with different size X deltas
  for (int i = 0; i < 6; i++) {
    key[i].initButton(&tft,
                      bWidth * (i%3) + bWidth/2,
                      bHeight * (i/3) + bHeight/2,
                      bWidth,
                      bHeight,
                      TFT_BLACK, // Outline
                      TFT_BLUE, // Fill
                      TFT_BLACK, // Text
                      "",
                      1);

    key[i].drawButton(false, String(i+1));
  }
}

void loop() {
  TouchPoint p = ts.getTouch();
  // Adjust press state of each key appropriately
  for (uint8_t b = 0; b < 6; b++) {
    if ((p.zRaw > 0) && key[b].contains(p.x, p.y)) {
      key[b].press(true);  // tell the button it is pressed
    } else {
      key[b].press(false);  // tell the button it is NOT pressed
    }
  }

  // Check if any key has changed state
  for (uint8_t b = 0; b < 6; b++) {
    // If button was just pressed, redraw inverted button
    if (key[b].justPressed()) {
      Serial.printf("Button %d pressed\n", b);
      key[b].drawButton(true, String(b+1));
    }

    // If button was just released, redraw normal color button
    if (key[b].justReleased()) {
      Serial.printf("Button %d released\n", b);
      Serial.println("Button " + (String)b + " released");
      key[b].drawButton(false, String(b+1));
      listDir(SD, "/", 1);
    }
  }
  delay(50);
}


//  SD CARD
//  ==========================================
void init_sd()
{
  if(!SD.begin(SS))
  //SPIClass spi = SPIClass(VSPI);
  //if(!SD.begin(SS, spi, 80000000))
  {
    Serial.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();

  if(cardType == CARD_NONE){
    Serial.println("No SD card attached");
    return;
  }

  Serial.print("SD Card Type: ");
  if(cardType == CARD_MMC){
    Serial.println("MMC");
  } else if(cardType == CARD_SD){
    Serial.println("SDSC");
  } else if(cardType == CARD_SDHC){
    Serial.println("SDHC");
  } else {
    Serial.println("UNKNOWN");
  }

  uint64_t cardSize = SD.cardSize() / (1024 * 1024);
  Serial.printf("SD Card Size: %lluMB\n", cardSize);

  listDir(SD, "/", 1);
  Serial.println("------");
  listDir(SD, "/", 1);
}

void listDir(fs::FS &fs, const char * dirname, uint8_t levels)
{
  
  Serial.printf("Listing directory: %s\n", dirname);

  /*
  //Serial.println(SD);
  try {
    SPIClass spi = SPIClass(VSPI);
    if(!SD.begin(SS, spi, 80000000))
    {
      Serial.println("Oops: restart sd test");
    }
    else{
      Serial.println("Oops GOOD: didn't restart sd test");
    }
  } catch(String error) {
    Serial.println("Oops exception");
  }
  Serial.println("NEXT");

  fs = SD;
  */

  try {
    
  File root = fs.open(dirname);
  if(!root){
    Serial.println("Failed to open directory");
    return;
  }
  if(!root.isDirectory()){
    Serial.println("Not a directory");
    return;
  }

  File file = root.openNextFile();
  while(file){
    if(file.isDirectory()){
      Serial.print("  DIR : ");
      Serial.println(file.name());
      if(levels){
        listDir(fs, file.name(), levels -1);
      }
    } else {
      Serial.print("  FILE: ");
      Serial.print(file.name());
      Serial.print("  SIZE: ");
      Serial.println(file.size());
    }
    file = root.openNextFile();
  }
  root.close();

  } catch(String error) {
    Serial.println("LS: Oops exception");
  }
  Serial.println("LS: NEXT");
}

if the SD card is sharing a SPI bus with other devices there can be problems, see ESP32 sdspi_share

suggest you leave the SD card connected to the VSPI bus and connect the display to the HSPI bus

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.