XIAO Round Display Not Detecting SD Card

Test.ino

#include <lvgl.h>

// uncomment a library for display driver
#define USE_TFT_ESPI_LIBRARY
// #define USE_ARDUINO_GFX_LIBRARY

#include "lv_xiao_round_screen.h"
#include "lv_hardware_test.h"

void setup()
{
    Serial.begin( 115200 );  //prepare for possible serial debug 
    Serial.println( "XIAO round screen - LVGL_Arduino" );


    // Map SPI port to 'new' pins
#define SS 28
#define MOSI 3
#define MISO 4
#define SCK 2
Serial.println("--------------");
  Serial.println(SS);
  Serial.println(MOSI); // master out, slave in
  Serial.println(MISO); // master in, slave out
  Serial.println(SCK);  // clock
  Serial.println("--------------");

    lv_init();

    lv_xiao_disp_init();
    lv_xiao_touch_init();

    lv_hardware_test();
}

void loop()
{
    lv_timer_handler();  //let the GUI do its work 
    delay( 5 );
}

lv_hardware_test.h

#include <SD.h>

#define NUM_ADC_SAMPLE 20
#define RP2040_VREF 3300 // The actual voltage on 3V3 pin. (unit: mV)
static lv_obj_t *slider_label;

static void event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * obj = lv_event_get_target(e);
    if(code == LV_EVENT_VALUE_CHANGED) {
        LV_LOG_USER("State: %s\n", lv_obj_has_state(obj, LV_STATE_CHECKED) ? "On" : "Off");
    }
}

static void hardware_polled_cb(lv_timer_t * timer) {
    lv_obj_t *tf_state = (lv_obj_t *)timer->user_data;
    if(SD.begin(A1)){
      lv_obj_add_state(tf_state, LV_STATE_CHECKED);
      lv_obj_t * test_label = lv_label_create(lv_scr_act());
      lv_label_set_text(test_label, "Success");
      lv_obj_set_pos(test_label, 90, 110);
      delay(4000);
      SD.end();
    } else {
      lv_obj_clear_state(tf_state, LV_STATE_CHECKED); 

      lv_obj_t * test_label = lv_label_create(lv_scr_act());
      lv_label_set_text(test_label, "Failure");
      lv_obj_set_pos(test_label, 90, 110);
    }
}

void lv_hardware_test(void)
{
    lv_obj_t * tf_label = lv_label_create(lv_scr_act());
    lv_label_set_text(tf_label, "tf-card");
    lv_obj_set_pos(tf_label, 90, 130);

    lv_obj_t * tf_state = lv_switch_create(lv_scr_act());
    lv_obj_set_pos(tf_state, 90, 150);
    lv_obj_add_state(tf_state, LV_STATE_CHECKED | LV_STATE_DISABLED);
    lv_obj_add_event_cb(tf_state, event_handler, LV_EVENT_ALL, NULL);
    lv_timer_create(hardware_polled_cb, 7000, tf_state);

    analogReadResolution(12);
#if defined(ARDUINO_SEEED_XIAO_NRF52840_SENSE) || defined(ARDUINO_SEEED_XIAO_NRF52840)
    analogReference(AR_INTERNAL2V4); // 0.6V ref  1/4 Gain
#endif
}

I’m using a modified hardware test example, just using the SD card components, added a “success/failure” condition label.

The compiler output (verbose compile) doesn’t have much, pretty much just the libraries used and file locations.

Hi there,
Ok, then the Output from Serial monitor is fine,
Also Does it load an SPI.lib?
HTH
GL :slight_smile: PJ

WHy does it have that :point_up: there?
can you change it? to A2 pls.
LMK
PJ :slight_smile:

damn hard coded variables… get ya every time

1 Like

Leftover from the other tests… Changed, but still no dice.

And yes, it loads the SPI library. V1.0
Using library SPI at version 1.0 in folder: /home/ognalysis/.arduino15/packages/rp2040/hardware/rp2040/3.6.3/libraries/SPI

Hi there,
Can you post the output with the SPI defines now?
Let’s see what it’s set to?
HTH
GL :slight_smile: PJ

Try this code for XIAO round Display SD Card test with XIAO ESP32

#include "FS.h"
#include "SD.h"
#include "SPI.h"

#define SD_chipSelect D2

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.path(), levels -1);
      }
    }
    else 
    {
    Serial.print("  FILE: ");
    Serial.print(file.name());
    Serial.print("  SIZE: ");
    Serial.println(file.size());
    }
    file = root.openNextFile();
  }
}

void createDir(fs::FS &fs, const char * path)
{
  Serial.printf("Creating Dir: %s\n", path);
  if(fs.mkdir(path))
  {
    Serial.println("Dir created");
  } 
  else 
  {
    Serial.println("mkdir failed");
  }
}

void removeDir(fs::FS &fs, const char * path)
{
  Serial.printf("Removing Dir: %s\n", path);
  if(fs.rmdir(path))
  {
    Serial.println("Dir removed");
  } 
  else 
  {
    Serial.println("rmdir failed");
  }
}

void readFile(fs::FS &fs, const char * path)
{
  Serial.printf("Reading file: %s\n", path);

  File file = fs.open(path);
  if(!file)
  {
    Serial.println("Failed to open file for reading");
    return;
  }

  Serial.print("Read from file: ");
  while(file.available())
  {
    Serial.write(file.read());
  }
  file.close();
}

void writeFile(fs::FS &fs, const char * path, const char * message)
{
  Serial.printf("Writing file: %s\n", path);

  File file = fs.open(path, FILE_WRITE);
  if(!file)
  {
    Serial.println("Failed to open file for writing");
    return;
  }
  if(file.print(message))
  {
    Serial.println("File written");
  } 
  else 
  {
    Serial.println("Write failed");
  }
  file.close();
}

void appendFile(fs::FS &fs, const char * path, const char * message)
{
  Serial.printf("Appending to file: %s\n", path);

  File file = fs.open(path, FILE_APPEND);
  if(!file)
  {
    Serial.println("Failed to open file for appending");
    return;
  }
  if(file.print(message))
  {
    Serial.println("Message appended");
  } 
  else 
  {
    Serial.println("Append failed");
  }
  file.close();
}

void renameFile(fs::FS &fs, const char * path1, const char * path2)
{
  Serial.printf("Renaming file %s to %s\n", path1, path2);
  if (fs.rename(path1, path2)) 
  {
    Serial.println("File renamed");
  } 
  else 
  {
    Serial.println("Rename failed");
  }
}

void deleteFile(fs::FS &fs, const char * path)
{
  Serial.printf("Deleting file: %s\n", path);
  if(fs.remove(path))
  {
    Serial.println("File deleted");
  } 
  else 
  {
  Serial.println("Delete failed");
  }
}

void testFileIO(fs::FS &fs, const char * path)
{
  File file = fs.open(path);
  static uint8_t buf[512];
  size_t len = 0;
  uint32_t start = millis();
  uint32_t end = start;
  if(file)
  {
    len = file.size();
    size_t flen = len;
    start = millis();
    while(len)
    {
      size_t toRead = len;
      if(toRead > 512)
      {
        toRead = 512;
      }
      file.read(buf, toRead);
      len -= toRead;
    }
    end = millis() - start;
    Serial.printf("%u bytes read for %u ms\n", flen, end);
    file.close();
  } 
  else 
  {
    Serial.println("Failed to open file for reading");
  }
  file = fs.open(path, FILE_WRITE);
  if(!file)
  {
    Serial.println("Failed to open file for writing");
    return;
  }
  size_t i;
  start = millis();
  for(i=0; i<2048; i++)
  {
    file.write(buf, 512);
  }
  end = millis() - start;
  Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end);
  file.close();
}

void setup()
{
  Serial.begin(19200);
  pinMode(SD_chipSelect, OUTPUT);
  if(!SD.begin(SD_chipSelect))
  {
    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, "/", 0);
  createDir(SD, "/mydir");
  listDir(SD, "/", 0);
  removeDir(SD, "/mydir");
  listDir(SD, "/", 2);
  writeFile(SD, "/hello.txt", "Hello ");
  appendFile(SD, "/hello.txt", "World!\n");
  readFile(SD, "/hello.txt");
  deleteFile(SD, "/foo.txt");
  renameFile(SD, "/hello.txt", "/foo.txt");
  readFile(SD, "/foo.txt");
  testFileIO(SD, "/test.txt");
  Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024));
  Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024));
  Serial.printf("All Done!....");
}

void loop()
{
}

28, 3, 4, 2, as defined.

So it seems the pin definition is working, but it still can’t see the card…

I don’t have an ESP32.

Possibly related, but I’ve wired up a small 3.7v battery to the charge circuit. The HW test is supposed to indicate the battery level, but just shows 0%, despite the battery having a charge.

It’s unclear what the cause is.


Dip Switch

SEEED!

They should put background light on pin 1 or 3 (User button or Buzzer on XIAO expansion board,) not pin 6 Rx more likely to need to use the UART !

Good point, but interestingly enough it doesn’t change behavior for the example code.

Even more interesting, turning that dip switch to on, no battery, the battery indicator started changing between 15 and 35… As soon as I plug in the battery and reset, I get 0 again.

I’m going to see if the battery will charge, and maybe it’s because it’s below a threshold or something.

Still can’t figure out why it doesn’t see the SD card. It’s the exact same type and class PJ is using, and it’s formatted FAT32, readable by any OS I’ve put it into.

I would like to believe it’s not that Seeed/Xiao defined the pins incorrectly in the code, because I would imagine a lot of people would be having similar issues.

your battery is not reversed polarity is it?

I hope not. It’s wired up red+, black-.

I tried running this code with XIAO RoundDisplay and ESP32C3, with 32GB SD.
It’s throwing error :frowning:

Error:/Users/adith/Library/Arduino15/packages/esp32/tools/riscv32-esp-elf-gcc/esp-2021r2-patch5-8.4.0/bin/…/lib/gcc/riscv32-esp-elf/8.4.0/…/…/…/…/riscv32-esp-elf/bin/ld: /private/var/folders/gv/3b6sk3c155d1xt__5jbxyhv40000gn/T/arduino/cores/c0bb95db740c3428a30ae0a91016dc00/core.a(main.cpp.o): in function loopTask(void*)': /Users/adith/Library/Arduino15/packages/esp32/hardware/esp32/2.0.14/cores/esp32/main.cpp:45: undefined reference to loop()’
collect2: error: ld returned 1 exit status
Multiple libraries were found for “SD.h”
Used: /Users/adith/Library/Arduino15/packages/esp32/hardware/esp32/2.0.14/libraries/SD
Not used: /Users/adith/Library/Arduino15/libraries/SD
exit status 1

Compilation error: exit status 1

sounds like a problem with the code, maybe a missing ; or { } ,
try getting a fresh clean copy of the code… without seeing it i cant tell what else it could be
but try looking near anything you may have changed
look around the loop function

Hi there,
Can you test this bin on your unit. Check that thread SD fail, Yada, Yada,(GifVeiwer_target.bin)
Upload the bin with the Rf_Test tool or Flash tool , either will work.
Thnx,
GL :slight_smile: PJ