Function call ... and "return"?

My history is with Microchip PIC controllers and their MPLAB.ide.

“Call function” will effectively goto “Function” somewhere in code, but normally come back to where it came from, i.e. the next line after “Call function”.

Starting out with ESP32 in Platformio has been great fun, but now I’m writing a proper project, not just playing with on-line tutorials.

During my “void setup()” I read an SD card on SPI bus and get data onto a TFT display screen. Works well enough, but in void Init_SD_CARD() { where I do “SD.begin”, it could fail or maybe not even have a card inserted.

So, I’ve included 2 TFT screens, inside the SD card initialization “void Init_SD_CARD()” function.

  1. “Insert SD Card” …. card NOT OK, this flashes
  2. “SD Card ok” ……… now reading data OK

Without a card, I get screen 1.

Then insert the card, it changes to screen 2 ………… but takes several seconds to get back to my “void setup()” path, where it starts putting data on the TFT screen.

Part of my code …

Not shown SD_ONbus() and TFT_ONbus() they just swap the CS lines for the SPI bus.

//init SD Card ###########################################################
void Init_SD_CARD() {
  Card_Error = 0;
  SD_ONbus();                               //swap CS lines
  while (!Serial) { ; }                     //wait for serial port to connect
  Serial.print("Initializing SD card … ");

  if (!SD.begin(SD_CS)) {
    Serial.println(“Failed!”);

    //NO CARD !!! Splash screen ============================ CARD ERROR ====
    Card_Error = 1;
    TFT_ONbus();                             //swap CS lines
    tft.fillScreen(TFT_BLUE);
    tft.setTextColor(TFT_WHITE);
    tft.setTextSize(2);
    tft.drawString (“Insert”  ,90, 100,4);
    tft.drawString (“SD Card” ,60, 170,4);
    Init_SD_CARD();                          //try to Init_SD_CARD() again
  }

  //CARD OK  !!! Splash screen ============================ CARD OK =====
  TFT_ONbus();                               //swap CS lines
  tft.fillScreen(TFT_BLUE);
  tft.drawString (“SD Card” ,60, 170,4);
  tft.drawString (“OK”     ,110, 220,4);
  Serial.println(“OK \n”);
  SD_ONbus();                               //swap CS lines

}       // STRANGE !!! this takes ages to go back to ...
        // READ SD Card files ##############”



//###########################################################################
void setup() {
  Serial.begin(115200);              //Serial terminal baud rate 115200
  delay(100);
  // Set CS pins as OUTPUTS
  pinMode(TFT_CS, OUTPUT);
  pinMode(SD_CS, OUTPUT);
  // Set CS pins OFF = HIGH          //TFT and SD OFF bus
  digitalWrite(TFT_CS, HIGH);
  digitalWrite(SD_CS, HIGH);
  //init TFT screen ####################################################
  TFT_ONbus();                       //swap CS lines
  tft.init();
  tft.setRotation(4);                //4 is Portrait with PCB pins at bottom
  //Splash screen on TFT Screen ########################################
  tft.fillScreen(TFT_BLUE);
  tft.setTextColor(TFT_WHITE);
  tft.setTextSize(2);                      //textsize multiplies font size
  tft.drawString (“MIDI”      ,100,250,4);
  tft.drawString (“Keyboard”   ,40,300,4);
  tft.drawString (“Controller” ,45,350,4);
  delay(1000);

  // READ SD Card files #################################################
  SD_ONbus();                               //swap CS lines
  Init_SD_CARD();                           //Initialize SD card reader

    //  takes ages to come back here !!! ============

  List_SD(“/”);                             //list all files on SD card
  Read_SongFile(“/XXXX XXXX.txt”);
  Send_Chords();
  //setup MAIN SCREEN --------------------------------------
  TFT_ONbus();                              //swap CS lines
  tft.fillScreen(TFT_BLACK);
  blah … blah … blah … TFT screen layouts
  }   // end of setup

//#######################################################################
void loop() {
  // Functions put my SD card data on TFT screen …
  // I press some buttons, things happen …
  // All works fine !
} // end of loop

This all “works”, but why several seconds to exit “void Init_SD_CARD()” and get back into “void setup()” ???

I do eventually get all my data on screen and then void loop() { works fine.

Any ideas guys ?

Thank you

Trevor

Just been watching the terminal output …..

Unitl I insert card, I get loads of these - - - - - - - -

Initializing SD card … [ 28122][E][sd_diskio.cpp:806] sdcard_mount(): f_mount
failed: (3) The physical drive cannot work 
[ 28631][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
Failed!

When I insert card, I get - - - - - - - -

Initializing SD card …
OK
OK
OK
OK
OK
OK
OK
OK
OK
OK
OK
OK
OK
SD Card Songs list --------
XXXX XXXX.txt
YYYY YYYY.txt
ZZZZ ZZZZ.txt
Song - /XXXX XXXX.txt - Chords DGA#F#Bb
End of Song

Strange there are so many “OK” ‘s.

Expected just one, that’s why the delay.

That Serial.println("OK \n"); is right at the bottom of void Init_SD_CARD() { just before the exit.
Hmmmmmmm - - - - much head scratching

You’re using recursion, the function Init_SD_CARD calls itself. So you end up with many nested calls.

1 Like

Thanks azarubkin,

I think I understand, learning C++ as I go along.

So, all those nested “calls” pile onto a stack somewhere and need to be individually “returned” until the correct one is found ???

My thinking was, just stick around, trying to read SD card. No point carrying on until Read SD card is successful.

How to loop around something like this ? I’ll have a Google.

Thank you

Trevor

EDIT - looks like I should have a “WHILE” function loop, trying now

So, now have this, works ok, but a bit clumsy maybe using int Car_Error = xx ???.

//Retry SD Card ##############################################################
void Retry_SD_CARD() {
SD_ONbus();
Card_Error = 1; //assume will be ok
if (!SD.begin(SD_CS)) { //0 = Begin failed
Card_Error = 0;
}
}

//init SD Card ################################################################
void Init_SD_CARD() {
Card_Error = 1; //assume will be ok
SD_ONbus(); //swap CS lines
while (!Serial) { ; } // wait for serial port to connect
Serial.print("Initializing SD card … ");
if (!SD.begin(SD_CS)) { //begin failed ???
Card_Error = 0; //0 = Begin failed
//Begin failed ========================================= SPLASH INSERT CARD
TFT_ONbus(); //swap CS lines
tft.fillScreen(TFT_BLUE);
tft.setTextColor(TFT_WHITE);
tft.setTextSize(2);
tft.drawString (“Insert” ,90, 100,4);
tft.drawString (“SD Card” ,60, 170,4);
//Begin failed ========================================= CARD ERROR RETRY
while(Card_Error < 1) {
Retry_SD_CARD();
delay(2000);
}
}
//Begin worked OK ======================================== SPLASH CARD OK
TFT_ONbus(); //swap CS lines
tft.fillScreen(TFT_BLUE);
tft.drawString (“SD Card” ,60, 170,4);
tft.drawString (“OK” ,110, 220,4);
Serial.println(“OK \n”);
SD_ONbus(); //swap CS lines
delay(2000); //carry on, to read data
}

Got it all working again now, you guided me the right way.

Thanks azarubkin

Trevor

1 Like