Strange "Guru Meditation Error:" when appending to an SD file in <loop>

Hi all,

Got a strange one.
I am using the current IDE on an ESP32.
Within I open a SD card and create a file, append some data to it and check the size of the file. I append the same data to is a second time and check the size again.

Everything works fine. Until I try appending data to it using the same append function within . Which is when I get a Guru Meditation Error.

A small piece of code which shows the problem is below.
I would appreciate your thoughts or better still a solution :slight_smile:
To see the problem just uncomment the first line in
PS> Code compiles without errors.

Code
#include <FS.h>

#include <SD.h>
#include <SPI.h>
File PM_logfile;

void setup() {
Serial.begin(115200);
delay(200);
#define PIN_MISO 27 // GPIO27
#define PIN_MOSI 26 // GPIO26
#define PIN_SCK 25 // GIPO25
#define PIN_CS 33 // GPIO33
SPIClass SPI1(HSPI);
SPI1.begin(PIN_SCK, PIN_MISO, PIN_MOSI, PIN_CS);
if (!SD.begin(PIN_CS, SPI1)) {
Serial.println(“Card Mount Failed”);
} else {
Serial.println(“Card Mount Suceeded”);
}
Serial.print("\n\nStart of setup\n");
Serial.println("setup:create_logfile "); create_logfile();
Serial.print("setup:show_logfile "); show_logfile();
Serial.println(“setup:append_to_logfile” ); append_to_logfile();
Serial.print("setup:show_logfile "); show_logfile();
Serial.println(“setup:append_to_logfile” ); append_to_logfile();
Serial.print("setup:show_logfile "); show_logfile();
Serial.println(“End of setup\n\n”);
Serial.print(“Start of loop\n”);
}

void loop() {
//Serial.println(“loop:append_to_logfile” ); append_to_logfile(); Uncomment this line to see the problem
Serial.print("loop:show_logfile "); show_logfile();
delay(2000);
}

void create_logfile(){
// create an empty file
PM_logfile = SD.open("/PM_logfile.csv", FILE_WRITE);
PM_logfile.close();
}

void show_logfile(){
PM_logfile = SD.open("/PM_logfile.csv");
Serial.print("\t");
Serial.print(PM_logfile.name());
Serial.print("\t");
Serial.println(PM_logfile.size(), DEC);
PM_logfile.close();
}

void append_to_logfile(){
PM_logfile = SD.open("/PM_logfile.csv", FILE_WRITE);
PM_logfile.seek (PM_logfile.size()); // Go to end of file
PM_logfile.println(“test”);
PM_logfile.close();
}

For starters, install the ESP exception decoder, use it, and paste the results here.

Would it not stand to reason that the offending code is NOT in loop() but instead located in append_to_logfile() and it would make much more sense to use comments in the offending function?

Comment out all the code in append_to_logfile(), does it run, uncomment the first line, does it run, uncomment the 2nd line, does it run… Until you find the offending line of code in the function. Oh, let us know which line of code is the offending line.

BTW, post your properly formatted code in code tags. See the “</>” thingy in the reply window; that’s the code tag tag?

It’s best to get the code tag thingy done quickly or this thread will devolve into a howto use this site thread and your issue will remain unaddressed.

Actually if you take

void append_to_logfile(){

PM_logfile = SD.open("/PM_logfile.csv", FILE_WRITE);

PM_logfile.seek (PM_logfile.size()); // Go to end of file

PM_logfile.println(“test”);

PM_logfile.close();

}

**Down to **

void append_to_logfile(){
  PM_logfile = SD.open("/PM_logfile.csv", FILE_WRITE);
  PM_logfile.close(); 
}

You still get the error
More so if you remove FILE_WRITE, the error ges away.

**Plus if you put **

PM_logfile = SD.open("/PM_logfile.csv", FILE_WRITE);

PM_logfile.close();

Directly into eliminating the function call it will fail

Don’t think I can make it much simpler.

Idahowalker:
BTW, post your properly formatted code in code tags. See the “</>” thingy in the reply window; that’s the code tag tag?

It’s best to get the code tag thingy done quickly or this thread will devolve into a how to use this site thread and your issue will remain unaddressed.

Devolution has begun.

@g_art:
Pleases learn to follow instructions and forum guidelines. USE CODE TAGS!!!

Sorta Solved

[tt]Seems the issue is [color=#ff0000] SPIClass SPI1(HSPI); [/color]is no longer valid in <loop> as  it is declared only in <setup>.
Strange this only affected the append_to_logfile() function and not the show_logfile() function.
That is if you comment out  append_to_logfile() in <loop> the sketch runs fine even though SPIClass is no longer valid.

In this simple example I just moved this line above void setup() and bingo it worked.

However in a much more complicated project I am working on there was no way I could get it to work.
My final solution was to create my own pseudo loop function with a while(true) wrapper within
. [/tt]

Hence the Sorta Solved.

An example of a working and more reliable sketch is below for anyone interested.

#include <FS.h>
#include <SD.h>
#include <SPI.h>
File PM_logfile;
SPIClass SPI1(HSPI);

void setup() {
 Serial.begin(115200);
 delay(200);
 #define PIN_MISO  27  // GPIO27
 #define PIN_MOSI  26  // GPIO26
 #define PIN_SCK   25  // GIPO25
 #define PIN_CS    33  // GPIO33
  SPI1.begin(PIN_SCK, PIN_MISO, PIN_MOSI, PIN_CS);
   if (!SD.begin(PIN_CS, SPI1)) {
       Serial.println("Card Mount Failed");
   } else {
       Serial.println("Card Mount Succeeded");
   }
 Serial.print("\n\nStart of setup\n");  
 Serial.println("setup:create_logfile    ");   create_logfile();  
 Serial.print("setup:show_logfile        ");   show_logfile();      
 Serial.println("setup:append_to_logfile" );   append_to_logfile();
 Serial.print("setup:show_logfile        ");   show_logfile();
 Serial.println("setup:append_to_logfile" );   append_to_logfile();
 Serial.print("setup:show_logfile        ");   show_logfile();
 Serial.println("End of setup\n\n");
 Serial.print("Start of loop\n");

 while(true){  //Workaround loop function
   Serial.println("loop:append_to_logfile"   );   append_to_logfile(); 
   Serial.print("loop:show_logfile        ");   show_logfile();
   delay(2000);
   }
 }

void loop() {
   // do not use
 }

void create_logfile(){
 // create an empty file
 PM_logfile = SD.open("/PM_logfile.csv", FILE_WRITE);
 PM_logfile.close();  
 }

void show_logfile(){
 PM_logfile = SD.open("/PM_logfile.csv");
   Serial.print("\t");
   Serial.print(PM_logfile.name());
   Serial.print("\t");
   Serial.println(PM_logfile.size(), DEC);
 PM_logfile.close();
 }

void append_to_logfile(){
 PM_logfile = SD.open("/PM_logfile.csv", FILE_WRITE);
 PM_logfile.seek (PM_logfile.size());  // Go to end of file
 PM_logfile.println("test");
 PM_logfile.close();
 }

No, it will work just fine in all functions if you properly define the SPIClass object as a global rather than a local in setup().

The reason is that it sort of worked in your original code is you got lucky. The local SPIClass object defined in setup was still on the stack when the loop() function was only calling show_logfile(). After you changed the calling sequence by adding append_to_logfile(), you ended up overwriting those stack locations. This corrupted/destroyed the SPIClass object that was there as a residual.