Como puedo arreglar Meditation Guru error: Core 1 panicked con interrupciones y SPI?

Estoy haciendo un pequeño programa que cambia una imagen en una pantalla TFT LCD de 0.96" cada vez que se presiona un botón. El problema viene que cuando presiono este botón hace la función que tiene que hacer pero instantáneamente la placa se apaga y aparece este error aparece en Serie:

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

Core  1 register dump:
PC      : 0x4037883f  PS      : 0x00050531  A0      : 0x80375311  A1      : 0x3fc94030
A2      : 0x0000000c  A3      : 0x0001804c  A4      : 0x000637ff  A5      : 0x3fc94010  
A6      : 0x00000000  A7      : 0x3fc928b4  A8      : 0x00000014  A9      : 0x4037aa2e
A10     : 0x3fcf54c0  A11     : 0x80000001  A12     : 0x60004000  A13     : 0x3fc93ff0  
A14     : 0x00000000  A15     : 0x00000000  SAR     : 0x00000007  EXCCAUSE: 0x0000001c
EXCVADDR: 0x8037531d  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  


Backtrace: 0x4037883c:0x3fc94030 0x4037530e:0x3fcf5880 0x4200f93e:0x3fcf58a0 0x4037bbe0:0x3fcf58c0

  #0  0x4037883c:0x3fc94030 in _xt_lowint1 at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/freertos/port/xtensa/xtensa_vectors.S:1114
  #1  0x4037530e:0x3fcf5880 in FNKeyboardDisplay() at src/main.cpp:91
  #2  0x4200f93e:0x3fcf58a0 in esp_vApplicationIdleHook at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/freertos_hooks.c:63
  #3  0x4037bbe0:0x3fcf58c0 in prvIdleTask at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/freertos/tasks.c:3987




ELF file SHA256: 3fb2c8df1881d850

Rebooting...
�ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x42029fca
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3808,len:0x44c
load:0x403c9700,len:0xbe4
load:0x403cc700,len:0x2a38
entry 0x403c98d4

This is the code:

#include <Arduino.h>
#include <SPI.h>
#include <TFT_eSPI.h>

#define DISPLAY_ENABLED
#define DISPLAY_WIDTH 80
#define DISPLAY_HEIGHT 160
#define DISPLAY_ROTATION 0
TFT_eSPI tft = TFT_eSPI(DISPLAY_WIDTH, DISPLAY_HEIGHT); // Invoke custom library

//Size: 480 Bytes 32x15 pixels
static const uint8_t image_KeyboardFN[495] PROGMEM= {
0x80,0x00,0x00,0x01
,0x00,0x00,0x00,0x00
,0x35,0xda,0xda,0x6d
,0x35,0xda,0xda,0x6d
,0x00,0x00,0x00,0x01
,0x3b,0xbd,0xb5,0xdd
,0x0a,0x24,0xa4,0x41
,0x0a,0x24,0xa4,0x41
,0x04,0x52,0x4a,0x21
,0x3d,0xda,0xdb,0xbd
,0x00,0x00,0x00,0x01
,0x3d,0xff,0xff,0xbd
,0x3d,0xff,0xff,0xbd
,0x00,0x00,0x00,0x00
,0x80,0x00,0x00,0x01
};

//Size: 480 Bytes 32x15 pixels
static const uint8_t image_DisplaydFN[495] PROGMEM= {
0xff,0xff,0xff,0xff
,0xff,0xff,0xff,0xff
,0xc0,0x00,0x00,0x03
,0xda,0x00,0x00,0x5b
,0xd0,0x00,0x00,0x0b
,0xc0,0x00,0x00,0x03
,0xd0,0x00,0x00,0x0b
,0xc0,0x00,0x00,0x03
,0xd0,0x00,0x00,0x0b
,0xc0,0x00,0x00,0x03
,0xd0,0x00,0x00,0x0b
,0xda,0x00,0x00,0x5b
,0xc0,0x00,0x00,0x03
,0xff,0xff,0xff,0xff
,0xff,0xff,0xff,0xff
};

const struct KeyboardFN_display_image{
    const uint8_t x = 40;
    const uint8_t y = 5;
    const uint8_t width = 32;
    const uint8_t height = 15;
}KeyboardFN_display_image;

const struct DisplaydFN_display_image{
    const uint8_t x = 40;
    const uint8_t y = 5;
    const uint8_t width = 32;
    const uint8_t height = 15;
}DisplaydFN_display_image;

#define KEYBOARD_DISPLAY_SWITCH 10
//KEYBOARD_DISPLAY_SWITCH FN KEY
bool volatile WorkingAsKeyboard = true;

void IRAM_ATTR FNKeyboardDisplay()
{
	WorkingAsKeyboard = !WorkingAsKeyboard;
	delay(5);
	if(WorkingAsKeyboard)
	{
		tft.fillRect(KeyboardFN_display_image.x, 
					 KeyboardFN_display_image.y, 
					 KeyboardFN_display_image.width, 
					 KeyboardFN_display_image.height, 
					 TFT_BLACK);
		tft.pushImage(KeyboardFN_display_image.x,
				  	  KeyboardFN_display_image.y, 
					  KeyboardFN_display_image.width, 
					  KeyboardFN_display_image.height, 
					  image_KeyboardFN, 0);
	}
	else
	{
		tft.fillRect(DisplaydFN_display_image.x, 
					 DisplaydFN_display_image.y, 
					 DisplaydFN_display_image.width, 
					 DisplaydFN_display_image.height, 
					 TFT_BLACK);
		tft.pushImage(DisplaydFN_display_image.x,
				  	  DisplaydFN_display_image.y, 
					  DisplaydFN_display_image.width, 
					  DisplaydFN_display_image.height, 
					  image_DisplaydFN, 0);
	}
}

void setup()
{
	Serial.begin(115200);

	tft.begin();
	tft.setRotation(3);
	tft.setFreeFont(&FreeSansBold9pt7b); //Altura de la fuente 12
	tft.setTextColor(TFT_WHITE);

	tft.fillRect(KeyboardFN_display_image.x, 
					 KeyboardFN_display_image.y, 
					 KeyboardFN_display_image.width, 
					 KeyboardFN_display_image.height, 
					 TFT_WHITE);
	tft.pushImage(KeyboardFN_display_image.x,
					KeyboardFN_display_image.y, 
					KeyboardFN_display_image.width, 
					KeyboardFN_display_image.height, 
					image_KeyboardFN, 0);

	pinMode(KEYBOARD_DISPLAY_SWITCH, INPUT_PULLUP);
	attachInterrupt(digitalPinToInterrupt(KEYBOARD_DISPLAY_SWITCH), FNKeyboardDisplay, FALLING); //Function KEY Pushed (PullUp)
}

void loop()
{
	Serial.print("Program: ");
	Serial.println(WorkingAsKeyboard);
	delay(10);
}

Show the switch wiring. It might be mis-wired to short out the power supply when it's pressed.

This is a Spanish sub forum. People might be expecting you to post in Espanol.


No puedes usar delay() en la ISR.
La ISR tiene que ser corta y rápida.

No hace falta una interrupción para cambiar la imagen que muestras. Lee el pin del pulsador y listo.

Te recomiendo leer
https://www.gammon.com.au/interrupts

Gracias por la pagina, ya he entendido como hacer las cosas mejor.
Esta es la solucion:

#define KEYBOARD_DISPLAY_SWITCH 10
#define DEBOUNCE_DELAY 50
//KEYBOARD_DISPLAY_SWITCH FN KEY
bool volatile WorkingAsKeyboard = true;
bool volatile interrupted = false;
//millis var to debounce
unsigned int volatile last_interrupt_time = 0;

void IRAM_ATTR FNKeyboardDisplay()
{
	unsigned int interrupt_time = millis();
	if (interrupt_time - last_interrupt_time > DEBOUNCE_DELAY){
		WorkingAsKeyboard = !WorkingAsKeyboard;
		interrupted = true;
		last_interrupt_time = interrupt_time;
	}
}

void loop()
{
	if(WorkingAsKeyboard && interrupted)
	{
		tft.fillRect(KeyboardFN_display_image.x, 
					 KeyboardFN_display_image.y, 
					 KeyboardFN_display_image.width, 
					 KeyboardFN_display_image.height, 
					 TFT_BLACK);
		tft.pushImage(KeyboardFN_display_image.x,
				  	  KeyboardFN_display_image.y, 
					  KeyboardFN_display_image.width, 
					  KeyboardFN_display_image.height, 
					  image_KeyboardFN, 0);
		interrupted = false;
	}
	else if(!WorkingAsKeyboard && interrupted)
	{
		tft.fillRect(DisplaydFN_display_image.x, 
					 DisplaydFN_display_image.y, 
					 DisplaydFN_display_image.width, 
					 DisplaydFN_display_image.height, 
					 TFT_BLACK);
		tft.pushImage(DisplaydFN_display_image.x,
				  	  DisplaydFN_display_image.y, 
					  DisplaydFN_display_image.width, 
					  DisplaydFN_display_image.height, 
					  image_DisplaydFN, 0);
		interrupted = false;
	}
}

Moderador:
Por favor, lee las Normas del foro
Si posteas en el foro en inglés usa idioma inglés para expresarte.
Si escribes en español debes usar el foro Arduino en español.


Para la proxima, todo posteo que no sea de Arduino board va en Microcontroladores.
ESP8266, ESP32, STM32, etc, son candidatos a esta sección.

Igual no tiene sentido usar una interrupción para leer el estado de un botón y no es buena práctica.
Las interrupciones se usan para cosas más importantes y que necesitan atención inmediata. Este no es el caso.

De hecho verificas si se produjo una interrupción en cada pasada de loop(), ¿qué diferencia hay (en cuanto a velocidad de respuesta) a leer directamente el estado del botón en cada pasada? A lo sumo algunos microsegundos si justo pulsas el botón luego de que se leyó el pin pero igual tardarás varios milisegundos (muchos) en soltarlo así que se lee en la próxima pasada. Nada se pierde. :wink:

Pero atento, lo mismo ocurre si pulsas el botón luego de haber verificado si se produjo una interrupción, no se responderá hasta la próxima pasada. O sea, el resultado es el mismo.

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