Guru issue with ESP32, SD card and RTC

Hi everyone,

I'm currently trying to build a datalogger with an ESP32-S3-WROOM-2, an I2C DS1307 RTC and a SPI2 microSD card reader.

I'm working by baby steps, and i'm currently trying to create a txt file on the SD card, name it with the date and time when the ESP32 boot up and after that, creating a new line every 2 seconds, with the current time and date, each time by reading the RTC.

But I'm facing an issue each time I'm trying to read a second time the RTC.
The strange part is that, if the ESP don't find a SD card, there is no issue with the time reading...

Here is the error -->

Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.

Core  1 register dump:
PC      : 0x420397f9  PS      : 0x00060230  A0      : 0x82004f5a  A1      : 0x3fcebba0  
A2      : 0x3fcec900  A3      : 0x3fcebc09  A4      : 0x00000001  A5      : 0x00000000  
A6      : 0x00000000  A7      : 0x00000000  A8      : 0x00000001  A9      : 0x39456001  
A10     : 0xdffb0e68  A11     : 0x3c040838  A12     : 0x00000001  A13     : 0x0000ff00  
A14     : 0x00ff0000  A15     : 0xff000000  SAR     : 0x0000001c  EXCCAUSE: 0x0000001c  
EXCVADDR: 0xdffb0e68  LBEG    : 0x400556d5  LEND    : 0x400556e5  LCOUNT  : 0xffffffff  


Backtrace: 0x420397f6:0x3fcebba0 0x42004f57:0x3fcebbd0 0x42004dec:0x3fcebbf0 0x42002266:0x3fcebc30 0x4200271b:0x3fcebc80 0x4200c0a0:0x3fcebca0 0x4037f25a:0x3fcebcc0

Here is the exception decoder -->

PC: 0x420397f9:  is in Adafruit_I2CDevice::write(unsigned char const*, unsigned int, bool, unsigned char const*, unsigned int) (d:\Documents\Arduino\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp:115).
EXCVADDR: 0xdffb0e68

Decoding stack results
0x420397f6:  is in Adafruit_I2CDevice::write(unsigned char const*, unsigned int, bool, unsigned char const*, unsigned int) (d:\Documents\Arduino\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp:105).
0x42004f57:  is in Adafruit_I2CDevice::write_then_read(unsigned char const*, unsigned int, unsigned char*, unsigned int, bool) (d:\Documents\Arduino\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp:250).
0x42004dec: RTC_DS1307::now() at d:\Documents\Arduino\libraries\RTClib\src\RTC_DS1307.cpp:58
0x42002266: currentDT() at D:\Documents\Arduino\SD\SD.ino:121
0x4200271b: loop() at D:\Documents\Arduino\SD\SD.ino:151
0x4200c0a0: loopTask(void*) at C:\Users\chala\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32\main.cpp:74
0x4037f25a: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa\port.c:162

And there is my code -->

#include <SD.h>
#include <SPI.h>
#include <ESP32Time.h>
#include "RTClib.h"
#include <Wire.h>
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };

// Set up the pins for SPI2

const int spiClk = 18;   // SCLK
const int spiMiso = 17;  // MISO
const int spiMosi = 14;  // MOSI
const int spiCs = 13;    // CS
char title[20];
String CDT ="";
int i = 0;

// Initialize SPI2
SPIClass spi2(FSPI);

void setup() {
  Serial.begin(115200);
  Wire.begin(15, 16);

  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while (1) delay(10);
  }

  //if (rtc.getYear()<2023){
  //rtc.setTime(30, 24, 15, 17, 1, 2024);

  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  // Initialize SPI2
  spi2.begin(spiClk, spiMiso, spiMosi, spiCs);
  delay(1000);

  // Initialize the SD card
  if (!SD.begin(spiCs, spi2)) {
    Serial.println("SD card initialization failed!");
    return;
  }
  Serial.println("SD card initialization done.");
  currentDT();
  const char *bef = "/";
  const char *ext = ".txt";
  const char *tit = CDT.c_str();
  strcpy(title, bef);
  strcat(title, tit);
  strcat(title, ext);
  }
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();
  }
  }

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 currentDT() {
  Serial.println("2");
  DateTime now = rtc.now();
  Serial.println("3");
  CDT = "";
  CDT = String(now.year(), DEC);
  if (now.month() < 10)
    CDT += "0";
  CDT = CDT + String(now.month());
  if (now.day() < 10)
    CDT += "0";
  CDT = CDT + String(now.day()) + "_";
  if (now.hour() < 10)
    CDT += "0";
  CDT = CDT + String(now.hour());
  if (now.minute() < 10)
    CDT += "0";
  CDT = CDT + String(now.minute());
  if (now.second() < 10)
    CDT += "0";
  CDT = CDT + String(now.second());
  }

void loop() {

  if (i == 0) {
    writeFile(SD, title, "trtu");
    Serial.println(title);
    i = 1;
    }
  if (i == 1) {
    delay(2000);
    currentDT();
    const char *toto = CDT.c_str();
    appendFile(SD, title, toto);
    i = 2;
    Serial.println(toto);
    }

  if (i == 2) {
    appendFile(SD, title, " Hello");
    appendFile(SD, title, " World!\n");
    delay(2000);
    i = 1;
    }
  }

SPI on the ESP can be tricky and also variants have minor differences. I don't own an S3 so i can't test anything.

A Guru meditation error usually means that some peripheral is using a pin that it can't or shouldn't because it is used for something else, or that an object or variable that is being written to does not have the memory allocated.

On my ESP i use a different method to declare and assign the pins for SPI.

I first declare a pointer to the object

SPIClass * hspi = NULL;

and after that i initiate the object though that

hspi = new SPIClass(HSPI);
hspi->begin(HSPI_SCK, HSPI_MISO, HSPI_MOSI, SD_CS);

Still your method should be ok as well.
Then there is the pins as well as the bus. ESP32 has 3 or 4 busses but only 2 of the are usable to the user freely (i think, again it is the variant thing) They also don't have consistent names for SPI2. Also some of the pins may not be usable, as they may be used for the other busses. so i suggest you experiment with them just a bit. Hope this helps. Also could be good to completely remove the RTC code for testing to confirm it is the SD / SPI that is the cause.

Thank you for your answer,

I've tried what you said, but no change, the crash appears to be at the second time that i'm using DateTime now = rtc.now().

I've unplugged the RTC and I have the same issue, but if I eject the SD card no issue.
It messed a lot with my head that it's the rtc.now part that crash but linked to SD card :face_with_spiral_eyes:

Actually doesn't the ESP32 have a built in RTC ?

Since you are using c-strings to parse, those may be suspect.
A good idea is to make sure that you don't overflow the buffer and explicitly add a '\0' terminator

Ok I'm feeling really stupid, the fix was simply to define that before the setup -->

DateTime now = rtc.now();

On the bugged code that I've sent before, I was trying to define it each time I was calling the void function.

If you want to make sure that you find the correct line where the crash occurs, you need to add some delay for transmission time.

That should have been fine though i think.

Why? ESP32 has a built-in RTC.

I want to make a car data logger, and after searching on the internet, it appears that you can't use a battery coin to power the built-in RTC and it's easier to use an external one.

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