Problem with ESP32 CPU crashing when using TFT_eSPI library

Hello,

I'm using an ILI9341 Touch Screen with the TFT_eSPI library. I have created a code for a kind of scale, with an interface in which you have to select info on the screen. In this project, a pariodic table is drawn, and the user must click on the element he is weighing.

The library works fine, but at some point, inside one specific while loop, when I ask the EPS32 to perform anything on the screen, it crashes.

Here is the error I get:

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

Core  1 register dump:
PC      : 0x400d4cc9  PS      : 0x00060c30  A0      : 0x800d2a04  A1      : 0x3ffc6820
A2      : 0x3ffc30a8  A3      : 0x00000000  A4      : 0x00000000  A5      : 0x00000001  
A6      : 0x00000001  A7      : 0x00000000  A8      : 0x00000000  A9      : 0x08000000  
A10     : 0x3ffc329c  A11     : 0x00000001  A12     : 0xffffffff  A13     : 0x00000001  
A14     : 0x3ffc30a8  A15     : 0x00000011  SAR     : 0x0000000a  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000044  LBEG    : 0x400d9270  LEND    : 0x400d92d4  LCOUNT  : 0x00000000

It seems like it is trying to read/write at an illegal adress.
The code is very long, and most of it is irrelevant for my problem, so I put only the essential parts.

#include <HX711_ADC.h> 
#include <Wire.h>
#include <EEPROM.h>
#include <molmetre_v2.h>

#include "FS.h"

#include <SPI.h>

#include "Free_Fonts.h"  // Include the header file attached to this sketch

#include <TFT_eSPI.h>  // Hardware-specific library

TFT_eSPI tft = TFT_eSPI();  // Invoke custom library


#define LABEL1_FONT &FreeSansBold9pt7b


#define MYGREY 0xDEFB      ///< 224, 224, 224
#define PALE 0xDF9E        ///< 223, 241, 243
#define LIGHTBLUE 0xB6FC   ///< 185, 223, 234
#define MIDBLUE 0x969C     ///< 151, 212, 233
#define DARKBLUE 0x24BB    ///< 36, 148, 224
#define PURPLE 0xB417      ///< 178, 129, 193
#define PINK 0xE294        ///< 231, 80, 162
#define DARKYELLOW 0xF641  ///< 250, 201, 8

#define MOLMETRE "MOLMETRE"
#define MyName "Thibault de Percin"

float MM[57] = {
 //molar masses of all the elements (needed after)
};

char elements[57][3] = {
  //names of all the elements
};


char L[27] = {
  //alphabet in capital letters
};
char l[27] = {
  //alphabet is small letters
};


uint8_t numberElements = 57;

bool completed = 0;
bool nextStep = 0;
bool finished = 0;
uint8_t mode;
float last_i = 0;
int count = 0;
int number = 0;

int formula[5] = {};
int stoechio[5] = {};


// Invoke the TFT_eSPI button class and create all the button objects
TFT_eSPI_Button button[15];
//0: Balance
//1: Molmetre
//2: Tare
//3: Terminé for measure
//4: Rentrer la formule
//5: Espece enregistree
//6: Terminé for periodic table
//7:
//8:


#define HX711_dout 16  //mcu > HX711 dout pin
#define HX711_sck 17   //mcu > HX711 sck pin
HX711_ADC LoadCell(HX711_dout, HX711_sck);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(38400);


//this is for the HX711 module of weight
  LoadCell.begin();
  boolean _tare = true;
  LoadCell.start(2000, _tare);
  LoadCell.setCalFactor(1135.16);  //Find the right value by using the Calibration file in the HX711 examples





  tft.init();
  tft.setRotation(1);


//this calibration data comes from the file Touch_calibrate in the example of the TFT_eSPI library.
  uint16_t calData[5] = { 365, 3546, 239, 3597, 7 };
  tft.setTouch(calData);  //to change this data, reuse the code Touch_calibrate

  tft.fillScreen(ILI9341_BLACK);  //fill screen with black
  yield();                        //I don't know what this does, not sure it's necessary

  tft.setTextDatum(MC_DATUM);
  tft.setFreeFont(&FreeSansBold24pt7b);    //big font (18 or 24)

  // I deleted some lines that are just the home screen

}





void loop() {
  // put your main code here, to run repeatedly:

  uint16_t t_x = 0, t_y = 0;  // To store the touch coordinates
  // Get current touch state and coordinates
  bool pressed = tft.getTouch(&t_x, &t_y);

  if (pressed) {
    doMeasure();
  }
}



void doMeasure() {
  tft.fillScreen(TFT_BLACK);

  nextStep = 0;
  finished = 0;
  count = 0;
  number = 0;
  tft.fillScreen(TFT_BLACK);
  drawTable();
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.drawString("Cliquer sur le premier ", 160, 10);
  tft.drawString("element de la formule", 160, 30);

  for (int i = 0; i < 10; i++) {
    formula[i] = 0;
    stoechio[i] = 0;
  }

  while (finished == 0) {

    nextStep = 0;
    while (nextStep == 0) {
      number = testTable();

      if (count > 2) { //this creates a button that is used to say you have finished choosing the various elements you are weighing
        button[7].initButton(&tft, 140, 80, 110, 40, TFT_BLACK, TFT_WHITE, TFT_RED, "Termine", 1);
        //            x, y (center button), w,    h,    outline,   fill,    text color,    text,   text size multiplier
        button[7].drawButton();


        uint16_t t_x = 0, t_y = 0;  // To store the touch coordinates
        bool pressed = tft.getTouch(&t_x, &t_y);
        if (pressed && button[7].contains(t_x, t_y)) {
          button[7].press(true);  // tell the button it is pressed
        } else {
          button[7].press(false);  // tell the button it is NOT pressed
        }
        if (button[7].justPressed()) {
          nextStep = 1;
          finished = 1 ;
        }
      }
      Serial.print("Step 2");
    }
    nextStep = 0;


    while (nextStep == 0) {
      Serial.print("Step 6");
      //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      //                                    Here is the moment it crashes
      //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      tft.fillRect(0, 0, 1, 1, TFT_BLACK);
      //If I remove this line it doesn't crash
    }



    if (finished == 0) {
      formula[count] = number;
      Serial.print("number:");
      Serial.print(number);
      count++;
    }
  }
}






void drawTable(){
   //this draws the periodic table
}



int testTable() {//This (long) function returns a value between 0 and 56 (the number corresponds to the number of the element chosen)
}

As you can see in the code, inside a certain while loop, I put a tft.fillRect(0,0,1,1, BLACK) funtion. If this function is right over (out of the while loop), the code works fine, but whenever I put it into the loop, it crashes immediately (the first time it tries to). In the IDE, I get "Step 6", as asked for in the code, and immediately after, I get the error... I really don't understand why that command makes it crash.
Can anyone help me?

Tell me if there is info that I should remove or that is missing, or if I have done anything wrong!
Thanks!

There's no ; after finished = 1
That would not Verify like that. Is this your latest ?
There are two while(nextStep == 0) loops practically in succession.

There's no ; after finished = 1

Oops, that's a typo that appeared when I copied the code. I corrected it in my original post.

How does it ever get out of this while loop ?
If it gets into it then it's trapped, Serial.printing Step 6 and tft.fillRect'ing,
nothing changes, forever.
N'est-ce pas?

There are two while(nextStep == 0) loops practically in succession.

This is on purpose: the first while(nextStep == 0) loop goes on until someone clicks on the screen (in the testTable function that I deleted, it becomes true), and then the code goes on to the next part of the interface with the second loop, in which will generate a 2nd interface (which I haven't coded yet, because it keeps crashing before I can do anything)

If it gets into it then it's trapped, Serial.printing Step 6 and tft.fillRect'ing,
nothing changes, forever.

Indeed, that's true, but that's because I haven't coded what comes after. And actually, the CPU crashes immediately after printing Step 6. That means it is the tft function making it crash. I tried adding a Step 7 right after, but it never got printed.

It gets there because nextStep is equal to zero. Crucially, there's nothing going on there that will change nextStep to anything else.

It gets there because nextStep is equal to zero. Crucially, there's nothing going on there that will change nextStep to anything else.

I know, but my problem is not that it is stuck there, my problem is the CPU crashing:

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

Core  1 register dump:
PC      : 0x400f858b  PS      : 0x00060c30  A0      : 0x800d29e9  A1      : 0x3ffc6830  
A2      : 0x3ffc30a8  A3      : 0x00000000  A4      : 0x000000a0  A5      : 0x0000001e  
A6      : 0x3f400184  A7      : 0x3f4001ed  A8      : 0x00000000  A9      : 0x3ffc6810  
A10     : 0x00000006  A11     : 0x3f400229  A12     : 0x00000000  A13     : 0x00000002  
A14     : 0x3ffc30a8  A15     : 0x0000006d  SAR     : 0x0000000a  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x0000002c  LBEG    : 0x40086481  LEND    : 0x40086491  LCOUNT  : 0xfffffffe  

Backtrace: 0x400f8588:0x3ffc6830 0x400d29e6:0x3ffc6850 0x400d2b15:0x3ffc68b0 0x400d9b65:0x3ffc68e0


ELF file SHA256: c7b3c4a1472a93b7

Rebooting...

Actually, I tried changing my code, and if I put this, it crashed too. It never reached Step 6... It printed Step 2 for a while, then when I pressed, it crashed:

    while (finished == 0) {

      nextStep = 0;
      while (nextStep == 0) {
        number = testTable();

        if (count > 2) {
          button[7].initButton(&tft, 140, 80, 110, 40, TFT_BLACK, TFT_WHITE, TFT_RED, "Termine", 1);
          //            x, y (center button), w,    h,    outline,   fill,    text color,    text,   text size multiplier
          button[7].drawButton();


          uint16_t t_x = 0, t_y = 0;  // To store the touch coordinates
          bool pressed = tft.getTouch(&t_x, &t_y);
          if (pressed && button[7].contains(t_x, t_y)) {
            button[7].press(true);  // tell the button it is pressed
          } else {
            button[7].press(false);  // tell the button it is NOT pressed
          }
          if (button[7].justPressed()) {
            nextStep = 1;
            finished = 0;
          }
        }
        Serial.print("Step 2");
      }
      nextStep = 0;

      tft.fillScreen(TFT_BLACK);
///////////////////////////////////////////////////////////////////////////////////////////
//               This is the line I just added
///////////////////////////////////////////////////////////////////////////////////////////
      while (nextStep == 0) {
        Serial.print("Step 6");
        tft.fillRect(0, 0, 1, 1, TFT_BLACK);
      }

It's the same conundrum rearranged.

What does that mean?

It's the same mess in a different place.

I'm sorry, I don't understand what mess you are refering to...
The function that is making it crash is clearly "tft.fillScreen(BLACK);

Is that the mess?

That your sketch allows that to execute, to go on and on and on. That's the problem.

Oh I see ok.
Actually I found the problem:

int formula[5] = {};
int stoechio[5] = {};

And then later on:

  for (int i = 0; i < 10; i++) {
    formula[i] = 0;
    stoechio[i] = 0;
  }

I wrote formula[6]=0 although there is no formula[6].
That doesn't make the code crash immediately, but later, when I try to use other functions.

Fixing this solved my problem

This can help find the line of code causing crashes.

It requires IDE 1.x. There is no IDE 2.x equivalent that I know of.

The usual way to get a display working is to disconnect other hardware except for the display. Modify User_Setup.h or User_Setup_Select.h. Run one or more examples until the display works. If the display does not work, the wiring or configuration file(s) or both are wrong.

1 Like

Thanks for your help!
I found the problem :wink:

That's why using

  • a constant or
  • a variable calculated as sizeof(array)/sizeof(array[0])

in/ after the declaration and e g. for-loops is a good idea...

Avoids a lot of headache and changes in the code ...

:wink:

1 Like

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