espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.52k stars 7.39k forks source link

Rcswitch endless reboot on esp cam with "Guru Meditation Error: Core 1 panic'ed (LoadProhibited)" error #4963

Closed nathalizator closed 3 years ago

nathalizator commented 3 years ago

I'm succesfully using rcswich with a RF receiver and ESP32-cam but when i just try to merge the receiver demo with an esp cam server code it cause a endless reboot of my esp with an error message. The esp cam server code is working well before merging and it starts rebooting with a error message as soon as i add this part :

  Serial.print("Ready to receive.");
  mySwitch.enableReceive(RXD2);
  delay(1000);

I've seen someone with a similar problem but not sure how to implement the solution with my code. Any help would be appreciated if you think this case is related : https://github.com/espressif/esp-who/issues/90#issuecomment-518010560

The error message

:10:12.211 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
10:10:12.211 -> configsip: 0, SPIWP:0xee
10:10:12.211 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
10:10:12.211 -> mode:DIO, clock div:2
10:10:12.211 -> load:0x3fff0018,len:4
10:10:12.211 -> load:0x3fff001c,len:1216
10:10:12.211 -> ho 0 tail 12 room 4
10:10:12.245 -> load:0x40078000,len:9720
10:10:12.245 -> ho 0 tail 12 room 4
10:10:12.245 -> load:0x40080400,len:6364
10:10:12.245 -> entry 0x400806b8
10:10:12.940 -> 
10:10:13.941 -> Ready to receive.Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
10:10:15.047 -> Core 1 register dump:
10:10:15.047 -> PC      : 0x401584a3  PS      : 0x00060833  A0      : 0x801362bf  A1      : 0x3ffb1e50  
10:10:15.047 -> A2      : 0x00000000  A3      : 0x3ffb8058  A4      : 0x00000001  A5      : 0x00000001  
10:10:15.047 -> A6      : 0x00060820  A7      : 0x00000000  A8      : 0x80135bf1  A9      : 0x3ffb1e20  
10:10:15.081 -> A10     : 0x02000000  A11     : 0x401357ac  A12     : 0x3ffb1e38  A13     : 0x00000001  
10:10:15.081 -> A14     : 0x00060a20  A15     : 0x00000000  SAR     : 0x00000007  EXCCAUSE: 0x0000001c  
10:10:15.081 -> EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000  
10:10:15.081 -> 
10:10:15.081 -> Backtrace: 0x401584a3:0x3ffb1e50 0x401362bc:0x3ffb1e70 0x40138020:0x3ffb1ea0 0x4013819f:0x3ffb1ed0 0x400d2482:0x3ffb1f00 0x400d585b:0x3ffb1fb0 0x4008bc19:0x3ffb1fd0
10:10:15.115 -> 

Interpretation of the error with Exception Decoder :

PC: 0x401584a3: esp_intr_get_cpu at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/intr_alloc.c line 780
EXCVADDR: 0x00000000

Decoding stack results
0x401584a3: esp_intr_get_cpu at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/intr_alloc.c line 780
0x401362bc: gpio_isr_handler_add at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/driver/gpio.c line 389
0x40138020: camera_init at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/components/esp32-camera/driver/camera.c line 1205
0x4013819f: esp_camera_init at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/components/esp32-camera/driver/camera.c line 1268
0x400d2482: setup() at /Users/admin/Downloads/Code_Security_Camera_ESP32CAM_Blynk_02/Code_Security_Camera_ESP32CAM_Blynk_02.ino line 116
0x400d585b: loopTask(void*) at /Users/admin/Library/Arduino15/packages/esp32/hardware/esp32/1.0.4/cores/esp32/main.cpp line 14
0x4008bc19: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

Here is the complete code:

#define CAMERA_MODEL_AI_THINKER // Has PSRAM

#include "camera_pins.h"

#define BTN 13
#define PHOTO 14
#define LED 4

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
#define RXD2 2

#include "config.h"
const char* ssid = secret_ssid;
const char* password = secret_pwd;
char auth[] = secret_auth;  //sent by Blynk

String local_IP;

void startCameraServer();

void takePhoto()
{
  digitalWrite(LED, HIGH);
  delay(200);
  uint32_t randomNum = random(50000);
  Serial.println("http://" + local_IP + "/capture?_cb=" + (String)randomNum);
  Blynk.setProperty(V1, "urls", "http://" + local_IP + "/capture?_cb=" + (String)randomNum);
  digitalWrite(LED, LOW);
  delay(1000);
}

void setup() {
  Serial.begin(115200);
  pinMode(RXD2, INPUT);
  pinMode(LED, OUTPUT);
  pinMode(BTN, INPUT_PULLUP);
  Serial.setDebugOutput(true);
  Serial.println();
  delay(1000);

Serial.print("Ready to receive.");
  mySwitch.enableReceive(RXD2);
  delay(1000);

  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;

  // if PSRAM IC present, init with UXGA resolution and higher JPEG quality
  //                      for larger pre-allocated frame buffer.
  if (psramFound()) {
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

  // camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  sensor_t * s = esp_camera_sensor_get();
  // initial sensors are flipped vertically and colors are a bit saturated
  if (s->id.PID == OV3660_PID) {
    s->set_vflip(s, 1); // flip it back
    s->set_brightness(s, 1); // up the brightness just a bit
    s->set_saturation(s, -2); // lower the saturation
  }
  // drop down frame size for higher initial frame rate
  s->set_framesize(s, FRAMESIZE_QVGA);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  startCameraServer();

  Serial.print("Camera Ready! Use 'http://");
  Serial.print(WiFi.localIP());
  local_IP = WiFi.localIP().toString();
  Serial.println("' to connect");
  Blynk.begin(auth, ssid, password);

}

void loop() {
  Serial.println(BTN);
  // put your main code here, to run repeatedly:
  Blynk.run();

  if (digitalRead(BTN) == LOW) {
    Serial.println("Send Notification");
    Blynk.notify("Il y a une personne à la porte!");
    Serial.println("Capture Photo");
    Serial.println(BTN);
    takePhoto();
    delay(3000);
  } else if (digitalRead(BTN) == HIGH) { };

  /*
    if (mySwitch.available()) {

    Serial.print(mySwitch.getReceivedValue());
    unsigned long int num = mySwitch.getReceivedValue();
    Serial.println(num);

    mySwitch.resetAvailable();
    }
  */

}
me-no-dev commented 3 years ago

please decode the backtrace with ESPExceptionDecoder so that we can see where the issue happens.

nathalizator commented 3 years ago

please decode the backtrace with ESPExceptionDecoder so that we can see where the issue happens.

you can see it in my original message above but here it is again:

PC: 0x401584a3: esp_intr_get_cpu at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/intr_alloc.c line 780
EXCVADDR: 0x00000000

Decoding stack results
0x401584a3: esp_intr_get_cpu at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/intr_alloc.c line 780
0x401362bc: gpio_isr_handler_add at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/driver/gpio.c line 389
0x40138020: camera_init at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/components/esp32-camera/driver/camera.c line 1205
0x4013819f: esp_camera_init at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/components/esp32-camera/driver/camera.c line 1268
0x400d2482: setup() at /Users/admin/Downloads/Code_Security_Camera_ESP32CAM_Blynk_02/Code_Security_Camera_ESP32CAM_Blynk_02.ino line 116
0x400d585b: loopTask(void*) at /Users/admin/Library/Arduino15/packages/esp32/hardware/esp32/1.0.4/cores/esp32/main.cpp line 14
0x4008bc19: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143
me-no-dev commented 3 years ago

If RCSwitch is using GPIO Interrupts, then it's having a conflict with the camera driver. There is currently no workaround for this situation, but one is planned for near future.

nathalizator commented 3 years ago

Hello ! it means that we can't have 2 interrupt on the esp cam ? Also, can you be more specific on "near future", does it means 1 week, 1 month, 1 year ? Just to see if i should look for another solution or wait for the fix. Thanks! @me-no-dev

nathalizator commented 3 years ago

@me-no-dev Hello again, any update on this ?

nathalizator commented 3 years ago

@me-no-dev Hello, any news ?

AndyFBs commented 1 year ago

I've encountered this well over 100 times. It always comes down to the same thing. The ESP32-CAM is a duel core module. There is Core 0 and Core 1. When the module appears to constantly reboot after about 1 second it, in my case, has always been due to the following either in my code, or a library that I am using that has been written with single core in mind.

I consider it an issue with the Arduino IDE compiler. Here is a tiny code fragment showing the issue....

Explaination of code: I have some data stored in the EEPROM, and at is shown in a webpage.

If 'char * wchtml=' is used, then memcpy will fail in setup with this Core 1 panic issue. If 'char wchtml[366]=' is used, then memcpy will be fine in setup.


` // With the following the EEPROM.get is done in Core 0. The memcpy in the setup function is on Core 1. // wchtml is not initialised prior to the memcpy ergo CRASH.

struct uEepromData { uint8_t Ver; uint8_t Mode; char MID[5]; char OtherData[500]; };

char host[14] = "ABCDABC_xxxxx"; uEepromData EPData;

// the following line is the difference. This causes an issue for Core 1 when altering in setup char * wchtml="<!DOCTYPE html>...";

void setup(){
EEPROM.begin(sizeof(uEepromData)); EEPROM.get(0, EPData);

memcpy(&wchtml[59],EPData.MID,5); // The line crash happens

memcpy(&host[8],EPData.MID,5); host[13]=0;
}

void loop(){

}


// With the following Core 0 does the EEPROM.get. Core 1 does the initialisation of wchtml and the memcpy.

struct uEepromData { uint8_t Ver; uint8_t Mode; char MID[5]; char OtherData[500]; };

char host[14] = "ABCDABC_xxxxx"; uEepromData EPData;

// the following line is the difference. This works char wchtml[366]="<!DOCTYPE html>...365 characters in total";

void setup(){ EEPROM.begin(sizeof(uEepromData)); EEPROM.get(0, EPData);

memcpy(&wchtml[59],EPData.MID,5);

memcpy(&host[8],EPData.MID,5); host[13]=0;
}

void loop(){

}`

me-no-dev commented 1 year ago

char * wchtml="<script>var ABSerial='xxxxx';var FwVer='yyy';</script>..."; must be const! This is a pointer to where const char wchtml_data[] = "<script>var ABSerial='xxxxx';var FwVer='yyy';</script>...365 characters in total"; is located.

that is why declaring it as array works. There is nothing wrong with the compiler.