Core 1 panic'ed (LoadProhibited)

Trying to run the following code to use an array to pull data stored in an element.

case SAVE_LOG_BTN:
        for (int i = 0; i < 12; i++) {
          appendFile(SD, logName, gslc_ElemGetTxtStr(&m_gui,(textfield[i])));
          delay(200);
        }
        break;

Only the first 4 values are saved then I get the following error in the serial monitor

Appending to file: /Log_2.txt
Message appended
Appending to file: /Log_2.txt
Message appended
Appending to file: /Log_2.txt
Message appended
Appending to file: /Log_2.txt
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x400014fd  PS      : 0x00060530  A0      : 0x800dcc8c  A1      : 0x3ffb1cf0  
A2      : 0xff000000  A3      : 0xfefffffc  A4      : 0x000000ff  A5      : 0x0000ff00  
A6      : 0x00ff0000  A7      : 0xff000000  A8      : 0x00000000  A9      : 0x3ffb1c30  
A10     : 0x3ffb1c60  A11     : 0x00000001  A12     : 0x00008000  A13     : 0x3f4001a3  
A14     : 0x00008000  A15     : 0x0000000a  SAR     : 0x0000001b  EXCCAUSE: 0x0000001c  
EXCVADDR: 0xff000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffff  

ELF file SHA256: 0000000000000000

Backtrace: 0x400014fd:0x3ffb1cf0 0x400dcc89:0x3ffb1d00 0x400dcd61:0x3ffb1d20 0x400d3881:0x3ffb1d40 0x400d3ab5:0x3ffb1d80 0x400d4f6a:0x3ffb1de0 0x400d4fbd:0x3ffb1e10 0x400d5844:0x3ffb1e50 0x400d58bd:0x3ffb1e70 0x400d5925:0x3ffb1eb0 0x400d5a31:0x3ffb1ee0 0x400d5adb:0x3ffb1f30 0x400d37df:0x3ffb1f90 0x400dd309:0x3ffb1fb0 0x40085a0a:0x3ffb1fd0

Any ideas?

You think the code snippet you posted will help in finding the issue with the problem you are having?

Have you loaded up the ESP Exception decoder and put your error into the decoder?

Oh, oh. This EXCVADDR: 0xff000000 looks like someone coded a bad thingy; such as an array going out of bounds. But, with just a code snippet, the world may never know.

Yeah, theres a good chance the whole program is rubbish. I really need some help with it but alot of my posts are ignored, i think mainly because there are not alot of people with experience using the GUISlice lib.

Code is way to big to fit in a post, but here is everything in a .zip

TiretoolNew.zip (133 KB)

I'm sorry, not going to download and install your code.

Just from looking at the debug info, I'd look for an array that is going out of bounds. Good luck.


You could break your code up into 6 or 7 posts that will put you close or over 100 posts and remove the wait time limit, post count.

What exactly do you mean by an array thats going out of bounds?

How do you make an array?

Lets say String sThings[4] = {};

What happens when you Serial.println( sThings[15] )?

#include "TiretoolNew_GSLC.h"
#include <SD.h>
#include "TS-NTC-103_simple.h"

// Save some element references for direct access
//<Save_References !Start!>
gslc_tsElemRef* Close_Log_Pup     = NULL;
gslc_tsElemRef* DATA_TEXT_1       = NULL;
gslc_tsElemRef* DATA_TEXT_10      = NULL;
gslc_tsElemRef* DATA_TEXT_11      = NULL;
gslc_tsElemRef* DATA_TEXT_12      = NULL;
gslc_tsElemRef* DATA_TEXT_2       = NULL;
gslc_tsElemRef* DATA_TEXT_3       = NULL;
gslc_tsElemRef* DATA_TEXT_4       = NULL;
gslc_tsElemRef* DATA_TEXT_5       = NULL;
gslc_tsElemRef* DATA_TEXT_6       = NULL;
gslc_tsElemRef* DATA_TEXT_7       = NULL;
gslc_tsElemRef* DATA_TEXT_8       = NULL;
gslc_tsElemRef* DATA_TEXT_9       = NULL;
gslc_tsElemRef* Front_Left        = NULL;
gslc_tsElemRef* Front_Right       = NULL;
gslc_tsElemRef* Log_Del_n         = NULL;
gslc_tsElemRef* Log_Del_y         = NULL;
gslc_tsElemRef* NEXT_DATA         = NULL;
gslc_tsElemRef* Open_Log          = NULL;
gslc_tsElemRef* PREV_DATA         = NULL;
gslc_tsElemRef* RESET             = NULL;
gslc_tsElemRef* Rear_Left         = NULL;
gslc_tsElemRef* Rear_Right        = NULL;
gslc_tsElemRef* SAVE_SD           = NULL;
gslc_tsElemRef* Save_Log_btn      = NULL;
gslc_tsElemRef* m_pElemListbox1   = NULL;
gslc_tsElemRef* m_pElemRadial1    = NULL;
gslc_tsElemRef* m_pElemXRingGauge1 = NULL;
//<Save_References !End!>

// Define debug message function
static int16_t DebugOut(char ch) {
  if (ch == (char)'\n') Serial.println("");
  else Serial.write(ch);
  return 0;
}
int counter (-1);
char   logTemp[5];
char   nullVal[5];
char   logName[8];
static char nullnullval[7] = "---.--";

// Common Button callback
bool CbBtnCommon(void* pvGui, void *pvElemRef, gslc_teTouch eTouch, int16_t nX, int16_t nY)
{
  // Typecast the parameters to match the GUI and element types
  gslc_tsGui*     pGui     = (gslc_tsGui*)(pvGui);
  gslc_tsElemRef* pElemRef = (gslc_tsElemRef*)(pvElemRef);
  gslc_tsElem*    pElem    = gslc_GetElemFromRef(pGui, pElemRef);
  gslc_tsElemRef* textfield[] = {
    DATA_TEXT_1,
    DATA_TEXT_2,
    DATA_TEXT_3,
    DATA_TEXT_4,
    DATA_TEXT_5,
    DATA_TEXT_6,
    DATA_TEXT_7,
    DATA_TEXT_8,
    DATA_TEXT_9,
    DATA_TEXT_10,
    DATA_TEXT_11,
    DATA_TEXT_12,
  };
  TS_NTC_103 sensor (0.11, 10);
  float Temp (sensor.getTemp(analogRead(36)));
  if ( eTouch == GSLC_TOUCH_UP_IN ) {
    // From the element's ID we can determine which button was pressed.
    switch (pElem->nId) {
      //<Button Enums !Start!>
      case E_ELEM_IMAGEBTN3:
        gslc_SetPageCur(&m_gui, E_PG2);
        break;
      case E_ELEM_IMAGEBTN4:
        gslc_SetPageCur(&m_gui, E_PG4);
        break;
      case E_ELEM_IMAGEBTN1:
        gslc_SetPageCur(&m_gui, E_PG3);
        break;
      case E_ELEM_IMAGEBTN2:
        gslc_SetPageCur(&m_gui, E_PG5);
        break;
      case E_ELEM_IMAGEBTN6:
        gslc_SetPageCur(&m_gui, E_PG_MAIN);
        break;
      case E_ELEM_IMAGEBTN7:
        gslc_SetPageCur(&m_gui, E_PG_MAIN);
        break;
      case E_ELEM_IMAGEBTN8:
        gslc_SetPageCur(&m_gui, E_PG_MAIN);
        break;
      case E_ELEM_IMAGEBTN9:
        gslc_SetPageCur(&m_gui, E_PG_MAIN);
        break;
      case NEXT_DATA_BTN:
        counter++;
        if (counter > 11) {
          counter = 0;
        }
        snprintf(logTemp, MAX_STR, "%.2f", Temp);
        gslc_ElemSetTxtStr(&m_gui, (textfield[counter]) , logTemp);
        break;
      case PREV_DATA_BTN:
        if (counter >= 0)
        {
          snprintf(nullVal, MAX_STR, "%.2f", nullnullval);
          gslc_ElemSetTxtStr(&m_gui, (textfield[counter]) , nullnullval);
          counter --;
        }
        break;
      case RESET_DATA_BTN:
        gslc_SetPageCur(&m_gui, Log_Delete);
        break;
      case SAVE_SD_BTN:
        gslc_SetPageCur(&m_gui, E_PG_POPUP3);
        break;
      case LOG_DEL_Y:
        for (int i = 0; i < 12; i++) {
          snprintf(nullVal, MAX_STR, "%.2f", nullnullval);
          gslc_ElemSetTxtStr(&m_gui, (textfield[i]) , nullnullval);
          delay (10);
        }
        counter = -1;
        gslc_SetPageCur(&m_gui, E_PG5);
        break;
      case LOG_DEL_N:
        gslc_SetPageCur(&m_gui, E_PG5);
        break;
      case OPEN_LOG_BTN:
        break;
      case SAVE_LOG_BTN:
        for (int i = 0; i < 11; i++) {
          appendFile(SD, logName,gslc_ElemGetTxtStr(&m_gui, (textfield[i])));
          delay(200);
        }
        break;
      case CLOSE_LOG_PUP:
        gslc_SetPageCur(&m_gui, E_PG5);
        break;

      //<Button Enums !End!>
      default:
        break;
    }
  }
  return true;
}

bool CbListbox(void* pvGui, void* pvElemRef, int16_t nSelId)
{
  gslc_tsGui*     pGui     = (gslc_tsGui*)(pvGui);
  gslc_tsElemRef* pElemRef = (gslc_tsElemRef*)(pvElemRef);
  gslc_tsElem*    pElem    = gslc_GetElemFromRef(pGui, pElemRef);


  if (pElemRef == NULL) {
    return false;
  }

  // From the element's ID we can determine which listbox was active.
  switch (pElem->nId) {
    //<Listbox Enums !Start!>
    case E_ELEM_LISTBOX1:
      if (nSelId != XLISTBOX_SEL_NONE) {
        gslc_ElemXListboxGetItem(&m_gui, pElemRef, nSelId, logName, MAX_STR);
      }
      break;

    //<Listbox Enums !End!>
    default:
      break;
  }
  return true;
}

void setup()
{
  // ------------------------------------------------
  // Initialize
  // ------------------------------------------------
  Serial.begin(9600);
  // Wait for USB Serial
  //delay(1000);  // NOTE: Some devices require a delay after Serial.begin() before serial port can be used

  gslc_InitDebug(&DebugOut);

  // ------------------------------------------------
  // Create graphic elements
  // ------------------------------------------------
  InitGUIslice_gen();
  uint8_t cardType = SD.cardType();

}


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();
}



// -----------------------------------
// Main event loop
// -----------------------------------
void loop()
{

  // ------------------------------------------------
  // Update GUI Elements
  // ------------------------------------------------

 if (counter <= 1) {
    gslc_ElemSetGlow(&m_gui, Front_Left , true);
  }
  else {
    gslc_ElemSetGlow(&m_gui, Front_Left , false);
  }
  if (counter >= 2 && counter <= 4 ) {
    gslc_ElemSetGlow(&m_gui, Rear_Left , true);
  }
  else {
    gslc_ElemSetGlow(&m_gui, Rear_Left , false);
  }
  if (counter >= 5 && counter <= 7) {
    gslc_ElemSetGlow(&m_gui, Rear_Right , true);
  }
  else {
    gslc_ElemSetGlow(&m_gui, Rear_Right , false);
  }
  if (counter >= 8 && counter <= 10) {
    gslc_ElemSetGlow(&m_gui, Front_Right , true);
  }
  else {
    gslc_ElemSetGlow(&m_gui, Front_Right , false);
  }

  // ------------------------------------------------
  // Periodically call GUIslice update function
  // ------------------------------------------------
  gslc_Update(&m_gui);

}

thanks for the tip, it what the character array being used for logName. I changed it from [8] to [MAX_STR +1] and it seems to be working now.

Please, have a skim through my code and tell me if anything terrible or disasterous catches your eye, Im quite new to this and this project is huge for me. It would be reassuring to have another person take a quick look.

I'd be using, cause it is an ESP32, freeRTOS. If not using WiFi/BT, I'd put some of the code onto core 0. The ESP32 has 2 processors and one of the processors has 2 cores. By default the Arduino IDE only uses core1 and, core0 gets the WiFi or BT or does nothing. If not using WiFi or BT you can put code onto the unused processor core. Multi-Processing.

I'd use log printing over Serial.print, log prints give line numbers and are faster then serial prints; otherwise looks good.

Thanks for the input.
I haven't completely ruled out bluetooth functionality (but I would like to get all other aspects working before going down that rabbit hole). Multi proccessing sounds nice though.

I will do a bit of reading about serial.log

Now that I have the datalogger working, I would like to recall the logs once they are saved.
I have the data from each element saved to a new line, so each value is seperated by "\n"

For the recall function I would like to take each line of data and write it back to the elements.

Here is what I have so far:

case OPEN_LOG_BTN:
      readFile(SD, logName);
     for (int i = 0; i < 11; i++) {
        gslc_ElemSetTxtStr(&m_gui, (textfield[i]) , printLineN(i));
     }
        break;


//......//


void printLineN(unsigned int lineNumber){
  File file;
  file.seek(0);
  
  char cr;
  
  for(unsigned int i = 0; i < (lineNumber -1);){
    cr = file.read();
    if(cr == '\n'){
      i++;
    }
  }
  
  //Now we are at the right line
  while(true){
    cr = file.read();
    Serial.write(cr);
    if(cr == '\n'){
      break;
    }
  }
  //a for loop with a read limit might be a good idea
}
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();
}

Cant get it to compile, I get the following error message:

C:\Users\MickW\Documents\Arduino\TiretoolNew\TiretoolNew.ino: In function 'bool CbBtnCommon(void*, void*, gslc_teTouch, int16_t, int16_t)':
TiretoolNew:161:66: error: invalid use of void expression
         gslc_ElemSetTxtStr(&m_gui, (textfield[i]) , printLineN(i));

Its probably something super dumb, but ive hit a wall and cant figure it out.

From the information given, I can't figure it out either.

PrintLn is a void function, but

gslc_ElemSetTxtStr

expects a char array (I guess) since I can't see a definition for it.

Thats correct, gslc_ElemSetTxtStr expects a char array.

how do I make a char array from PrintLineN?

PrintLineN should return a character string, or have I misunderstood something?

printLineN(i).c_str()

Doesnt work, I think i need to rewrite the function.
Any idesa where it might be going wrong?

mickymik:
Doesnt work, I think i need to rewrite the function.
Any idesa where it might be going wrong?

Not at the moment.

Not sure which function you mean needs rewriting, but he code under OPEN_LOG_BTN seems rather confused. The call to readfile merely tries to open the file and read each line, outputting the requested one to the serial output before closing the file. It does no other processing that I can see.

It looks as though the call to gslc_ElemSetTxtStr should be taking each line of data being read from the file just processed with readfile and loading it into an array. The call to printLineN seems to be irrelevant - but I am not really sure since there are no comments to explain how and why the code is there.

Yeesssss!!!!! Thats exactly what I am trying to do!
Could you help me fix this up so it works?

There is a better explanation of the problem here
I am really struggling with this problem