SD not initializing in XIAO RoundDisplay with ESP32C3

You can compare the compiler output between the TFT-eSPI_Clock code and the Depaul code.
You have verbose output checked, turned on in the IDE preferences?
just compile them both at the same time(two windows)
look at the SD LIB versions.
lmk, yea Good to look here for other ways to Flash those BIN files.
, halftime… Usher ? meh’ :thinking: :stuck_out_tongue:

Alright so my question is: Does my same code without any modifications work for you and stores the data to the SD?
The Code:

#include <Arduino.h>
#include <TFT_eSPI.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
#include <SD.h>

#define SEALEVELPRESSURE_HPA (1013.25)

#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3)
#include "esp_wifi.h"
#include "WiFi.h"
const char *ntpServer = "time.cloudflare.com";
const char *ssid = "Adith";
const char *password = "aadithsp";
#endif

#include "I2C_BM8563.h"
#include "NotoSansBold15.h"

I2C_BM8563 rtc(I2C_BM8563_DEFAULT_ADDRESS, Wire);
I2C_BM8563_TimeTypeDef timeStruct;
I2C_BM8563_DateTypeDef dateStruct;
Adafruit_BME680 bme;        // Create a BME680 sensor object for I2C
TFT_eSPI tft = TFT_eSPI();  // Invoke library, pins defined in User_Setup.h
TFT_eSprite face = TFT_eSprite(&tft);
File myFile;
#define CLOCK_X_POS 10
#define CLOCK_Y_POS 10

#define CLOCK_FG TFT_SKYBLUE
#define CLOCK_BG TFT_NAVY
#define SECCOND_FG TFT_RED
#define LABEL_FG TFT_GOLD

#define CLOCK_R 230.0f / 2.0f  // Clock face radius (float type)
#define H_HAND_LENGTH CLOCK_R / 2.0f
#define M_HAND_LENGTH CLOCK_R / 1.4f
#define S_HAND_LENGTH CLOCK_R / 1.3f

#define FACE_W CLOCK_R * 2 + 1
#define FACE_H CLOCK_R * 2 + 1

// Calculate 1 second increment angles. Hours and minute hand angles
// change every second so we see smooth sub-pixel movement
#define SECOND_ANGLE 360.0 / 60.0
#define MINUTE_ANGLE SECOND_ANGLE / 60.0
#define HOUR_ANGLE MINUTE_ANGLE / 12.0

// Sprite width and height
#define FACE_W CLOCK_R * 2 + 1
#define FACE_H CLOCK_R * 2 + 1

// Time h:m:s
uint8_t h = 0, m = 0, s = 0;

float time_secs = h * 3600 + m * 60 + s;

// Time for next tick
uint32_t targetTime = 0;
int memory_status = 0;
// =========================================================================
// Setup
// =========================================================================
void setup() {
  Serial.begin(19200);
  while (!Serial);
  //delay(2000);
  Serial.println("Booting...");

  // Initialise the screen
  tft.init();

  // Ideally set orientation for good viewing angle range because
  // the anti-aliasing effectiveness varies with screen viewing angle
  // Usually this is when screen ribbon connector is at the bottom
  tft.setRotation(0);
  tft.fillScreen(TFT_BLACK);

  // Create the clock face sprite
  //face.setColorDepth(8); // 8 bit will work, but reduces effectiveness of anti-aliasing
  face.createSprite(FACE_W, FACE_H);

  // Only 1 font used in the sprite, so can remain loaded
  face.loadFont(NotoSansBold15);

  // Draw the whole clock - NTP time not available yet
  renderFace(time_secs);

#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3)
  WiFi.begin(ssid, password);
  for (int a = 0; a < 10; a++) {
    if (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print("\nWaiting for WiFi Connection...");
    }
    delay(500);
  }
  delay(1000);
  if (WiFi.status() == WL_CONNECTED) {
    Serial.print("\nWiFi Successfully Connected!");
  } else {
    Serial.print("\nWiFi Connection Failed");
  }
  configTime(8 * 3600, 0, ntpServer);
  struct tm timeInfo;
  if (getLocalTime(&timeInfo)) {
    timeStruct.hours = timeInfo.tm_hour;
    timeStruct.minutes = timeInfo.tm_min;
    timeStruct.seconds = timeInfo.tm_sec;
    rtc.setTime(&timeStruct);
    // dateStruct.weekDay = timeInfo.tm_wday;
    // dateStruct.month   = timeInfo.tm_mon + 1;
    // dateStruct.date    = timeInfo.tm_mday;
    // dateStruct.year    = timeInfo.tm_year + 1900;
    // rtc.setDate(&dateStruct);
  }
#endif

  Wire.begin();
  rtc.begin();
  syncTime();
  ////////////////////////////////////////////////////////sensor and sd card
  // while (!Serial)
  //   ;
  Serial.println(F("\nBME688 test"));
  //delay(1000);
  if (!bme.begin()) {
    Serial.println("\nCould not find a valid BME688 sensor, check wiring!");
    while (1)
      ;  // Stay in a loop if the sensor is not found
  }
  // Configure sensor settings
  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150);  // 320°C for 150 ms
  ///////////////////////////////////////////////////////////////////
  // Open serial communications and wait for port to open:

  // while (!Serial)
  //   ;

  Serial.print("Initializing SD card... \n");

  pinMode(D2, OUTPUT);
  if (!SD.begin(D2)) {
    Serial.println("initialization failed! \n");
    memory_status = 0;
    return;
  }
  Serial.println("initialization done.");
  memory_status = 1;
}

// =========================================================================
// Loop
// =========================================================================
void loop() {
  callfunction();
  // Update time periodically
  if (targetTime < millis()) {

    // Update next tick time in 100 milliseconds for smooth movement
    targetTime = millis() + 1;

    // Increment time by 100 milliseconds
    time_secs += 0.1;

    // Midnight roll-over
    if (time_secs >= (60 * 60 * 24)) time_secs = 0;

    // All graphics are drawn in sprite to stop flicker
    renderFace(time_secs);

    // syncTime();
  }
}
// =========================================================================
//call function
// =========================================================================
void callfunction() {
  //////////////////////////////////////////////////////rtc function
  I2C_BM8563_DateTypeDef dateStruct;
  I2C_BM8563_TimeTypeDef timeStruct;
  // Get RTC
  rtc.getDate(&dateStruct);
  rtc.getTime(&timeStruct);
  // Print RTC
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3)
  Serial.printf("%04d/%02d/%02d %02d:%02d:%02d\n",
                dateStruct.year,
                dateStruct.month,
                dateStruct.date,
                timeStruct.hours,
                timeStruct.minutes,
                timeStruct.seconds);
#endif
  delay(0);
  /////////////////////////////////////////////sensor function
  if (!bme.performReading()) {
    //Serial.println("Failed to perform reading :(");
    return;
  }
  Serial.print("Temperature = " + String(bme.temperature) + "°C \n");
  Serial.print("Humidity = " + String(bme.humidity) + "% \n");
  Serial.print("Gas = " + String(bme.gas_resistance / 1000.0) + "KOhms \n");
  //////////////////////////////////////////////////// sd card write function
  if (memory_status == 1) {

    myFile = SD.open("/test.txt", FILE_WRITE);
    // if the file opened okay, write to it:
    if (myFile) {
      Serial.print("Writing to test.txt... \n");
      myFile.println(dateStruct.year);
      myFile.println(dateStruct.month);
      myFile.println(dateStruct.date);
      myFile.println(timeStruct.hours);
      myFile.println(timeStruct.minutes);
      myFile.println(timeStruct.seconds);
      // close the file:
      myFile.close();
      Serial.println("Time Sensor done. \n");

    } else {
      // if the file didn't open, print an error:
      Serial.println("error opening test.txt");
    }
  } else {
    Serial.print("\nSD Failed \n");
  }
  // // re-open the file for reading:
  // myFile = SD.open("/test.txt");
  // if (myFile) {
  //   Serial.println("test.txt:");

  //   // read from the file until there's nothing else in it:
  //   while (myFile.available()) {
  //     Serial.write(myFile.read());
  //   }
  //   // close the file:
  //   myFile.close();
  // } else {
  //   // if the file didn't open, print an error:
  //   Serial.println("error opening test.txt");
  // }
}
// =========================================================================
// Draw the clock face in the sprite
// =========================================================================
static void renderFace(float t) {
  float h_angle = t * HOUR_ANGLE;
  float m_angle = t * MINUTE_ANGLE;
  float s_angle = t * SECOND_ANGLE;

  // The face is completely redrawn - this can be done quickly
  face.fillSprite(TFT_BLACK);

  // Draw the face circle
  face.fillSmoothCircle(CLOCK_R, CLOCK_R, CLOCK_R, CLOCK_BG);

  // Set text datum to middle centre and the colour
  face.setTextDatum(MC_DATUM);

  // The background colour will be read during the character rendering
  face.setTextColor(CLOCK_FG, CLOCK_BG);

  // Text offset adjustment
  constexpr uint32_t dialOffset = CLOCK_R - 10;

  float xp = 0.0, yp = 0.0;  // Use float pixel position for smooth AA motion

  // Draw digits around clock perimeter
  for (uint32_t h = 1; h <= 12; h++) {
    getCoord(CLOCK_R, CLOCK_R, &xp, &yp, dialOffset, h * 360.0 / 12);
    face.drawNumber(h, xp, 2 + yp);
  }

  // Add text (could be digital time...)
  face.setTextColor(LABEL_FG, CLOCK_BG);
  face.drawString("DePaul University", CLOCK_R, CLOCK_R * 0.75);

  // Draw minute hand
  getCoord(CLOCK_R, CLOCK_R, &xp, &yp, M_HAND_LENGTH, m_angle);
  face.drawWideLine(CLOCK_R, CLOCK_R, xp, yp, 6.0f, CLOCK_FG);
  face.drawWideLine(CLOCK_R, CLOCK_R, xp, yp, 2.0f, CLOCK_BG);

  // Draw hour hand
  getCoord(CLOCK_R, CLOCK_R, &xp, &yp, H_HAND_LENGTH, h_angle);
  face.drawWideLine(CLOCK_R, CLOCK_R, xp, yp, 6.0f, CLOCK_FG);
  face.drawWideLine(CLOCK_R, CLOCK_R, xp, yp, 2.0f, CLOCK_BG);

  // Draw the central pivot circle
  face.fillSmoothCircle(CLOCK_R, CLOCK_R, 4, CLOCK_FG);

  // Draw cecond hand
  getCoord(CLOCK_R, CLOCK_R, &xp, &yp, S_HAND_LENGTH, s_angle);
  face.drawWedgeLine(CLOCK_R, CLOCK_R, xp, yp, 2.5, 1.0, SECCOND_FG);
  face.pushSprite(5, 5, TFT_TRANSPARENT);
}

// =========================================================================
// Get coordinates of end of a line, pivot at x,y, length r, angle a
// =========================================================================
// Coordinates are returned to caller via the xp and yp pointers
#define DEG2RAD 0.0174532925
void getCoord(int16_t x, int16_t y, float *xp, float *yp, int16_t r, float a) {
  float sx1 = cos((a - 90) * DEG2RAD);
  float sy1 = sin((a - 90) * DEG2RAD);
  *xp = sx1 * r + x;
  *yp = sy1 * r + y;
}

void syncTime(void) {
  targetTime = millis() + 100;
  rtc.getTime(&timeStruct);
  time_secs = timeStruct.hours * 3600 + timeStruct.minutes * 60 + timeStruct.seconds;
}

Yes.
I put in the home WiFi credentials and it does connect
I comment out the two Sensor lines that are hard wait loops. as I stated (don’t have those)
it does continue and write some random numbers to a Test.txt file on the SD card as I posted.
face increments time.
pj

Great then, there should be some isse with my 32GB SD card. I will try with other SD

OK, keep me posted…
GL :slight_smile: PJ :+1:

Definitely! Thanks a lot.

Check out this device… it also has a SD so you can test different hardware

I solved it! It was just an SD card issue.

1 Like

Hi there,
Yea, I knew you would get it going… Nice work. :+1:
Awesome, sometimes it’s the basic stuff… LOL
GL :wink: PJ :v: