I'm trying to write a simple sketch that takes a picture using an ESP32-CAM module, when a sensor detects motion. I know the camera functionality works as I wrote a test script that takes a picture and then shuts down. I simply used this test script and added code for handling the interrupt. However, I'm getting an unhandled exception when it tries to initialise the camera:
15:43:38.319 -> Initialising camera
15:43:38.649 -> Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
I hate posting long code snippets because it's unfair to expect people to read through it all, but I'm confused by what's happening. Any help would be appreciated.
#include "esp_camera.h" #include "Arduino.h" #include "soc/soc.h" #include "soc/rtc_cntl_reg.h" #include "driver/rtc_io.h" // Pin definition for CAMERA_MODEL_AI_THINKER #define PWDN_GPIO_NUM 32 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 0 #define SIOD_GPIO_NUM 26 #define SIOC_GPIO_NUM 27 #define Y9_GPIO_NUM 35 #define Y8_GPIO_NUM 34 #define Y7_GPIO_NUM 39 #define Y6_GPIO_NUM 36 #define Y5_GPIO_NUM 21 #define Y4_GPIO_NUM 19 #define Y3_GPIO_NUM 18 #define Y2_GPIO_NUM 5 #define VSYNC_GPIO_NUM 25 #define HREF_GPIO_NUM 23 #define PCLK_GPIO_NUM 22 camera_config_t config; int sensor_state = LOW; volatile bool is_triggered = false; void ICACHE_RAM_ATTR ISR_HANDLER() { is_triggered = true; } void loop_forever() { while (1) { delay(500); yield(); } } void setup() { WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector Serial.begin(115200); Serial.setDebugOutput(true); Serial.println(); 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 (psramFound()) { config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA config.jpeg_quality = 10; config.fb_count = 2; } else { config.frame_size = FRAMESIZE_SVGA; config.jpeg_quality = 12; config.fb_count = 1; } pinMode(13, INPUT); attachInterrupt(digitalPinToInterrupt(13), ISR_HANDLER, RISING); } void take_picture() { // Init Camera esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { loop_forever(); } camera_fb_t * fb = NULL; // Take Picture with Camera fb = esp_camera_fb_get(); if (!fb) { loop_forever(); } esp_camera_fb_return(fb); // Turns off the ESP32-CAM white on-board LED (flash) connected to GPIO 4 pinMode(4, OUTPUT); digitalWrite(4, LOW); } void loop() { if (is_triggered) { take_picture(); is_triggered = false; } }
However, I'm getting an unhandled exception when it tries to initialise the camera:
Can you give all the serial debug data leading up to this error?
This could mean it tries to access an empty pointer or a part of memory that you shouldn't have(Probably not on purpose). You are also dealing with PSRAM so maybe there is a problem there too. You could have also have just run out of RAM.
I also don't see how you are handling the interrupt. I would expect
void handleInterrupt() {
ThingToDo; }
The interrupt is handled in the function ISR_HANDLER. I'll try to post the full trace back later. It's definitely trying to use a null pointer - I did some reading based on the output. Thanks
Here's the full debug info:
Rebooting... ets Jun 8 2016 00:22:57 rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:1 load:0x3fff0018,len:4 load:0x3fff001c,len:1216 ho 0 tail 12 room 4 load:0x40078000,len:9720 ho 0 tail 12 room 4 load:0x40080400,len:6352 entry 0x400806b8 ISR Update Initialising camera Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled. Core 1 register dump: PC : 0x400f50eb PS : 0x00060a33 A0 : 0x800eda17 A1 : 0x3ffb1ec0 A2 : 0x00000000 A3 : 0x3ffb8058 A4 : 0x00000001 A5 : 0x00000001 A6 : 0x00060a20 A7 : 0x00000000 A8 : 0x800ed379 A9 : 0x3ffb1e90 A10 : 0x02000000 A11 : 0x400ecf5c A12 : 0x3ffb1ea8 A13 : 0x00000001 A14 : 0x00060e20 A15 : 0x00000000 SAR : 0x00000007 EXCCAUSE: 0x0000001c EXCVADDR: 0x00000000 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0x00000000 Backtrace: 0x400f50eb:0x3ffb1ec0 0x400eda14:0x3ffb1ee0 0x400ef5f7:0x3ffb1f10 0x400ef767:0x3ffb1f40 0x400d152a:0x3ffb1f70 0x400d1593:0x3ffb1f90 0x400d2c8d:0x3ffb1fb0 0x4008ce2d:0x3ffb1fd0
// Init Camera
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
loop_forever(); }
That's not really handling it but I do not know what that function is for.
try:
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
I would also expect you to define the camera model as well but I don't see that either.
You should also look into your PSRAM. Confirm you have the space there and access to it. Remember that even though some boards come with an 8 MB chip, you only get 4MB. Documentation suggests there are ways to use the upper 4MB but only on WROVER-B. You can run this and have debug level set to verbose:
#include <Arduino.h>
void setup() {
log_d("Total heap: %d", ESP.getHeapSize());
log_d("Free heap: %d", ESP.getFreeHeap());
log_d("Total PSRAM: %d", ESP.getPsramSize());
log_d("Free PSRAM: %d", ESP.getFreePsram());
}
void loop() {}
I would say confirm your PSRAM is correct. There are instances where enabling PSRAM support can crash your board.
Thanks.
The loop_forever function simply loops to avoid hitting the same exception over and over again.
I have used that printf statement but it is never executed; the panic happens in the esp_camera_init function.
I'll add the extra logging you suggested; I'll see what it shows.
There's nothing in the docs that says I need to define the camera model; the CameraWebServer example expects the camera model to be defined, but that's primarily to setup the pin defines. My sketch includes the pin defines for the camera model following this comment line:
// Pin definition for CAMERA_MODEL_AI_THINKER
Extra output, looks reasonable:
Total heap: 366600
Free heap: 340700
Total PSRAM: 4194252
Free PSRAM: 4194252
I added this line to the setup function:
esp_log_level_set("*", ESP_LOG_VERBOSE);
I now see these errors in the Serial monitor:
Initialising camera
[E][sccb.c:154] SCCB_Write(): SCCB_Write Failed addr:0x30, reg:0xff, data:0x01, ret:-1
[E][sccb.c:154] SCCB_Write(): SCCB_Write Failed addr:0x30, reg:0x12, data:0x80, ret:-1
[E][camera.c:1049] camera_probe(): Detected camera not supported.
[E][camera.c:1249] esp_camera_init(): Camera probe failed with error 0x20004
I'll read up on these errors. I have a vague memory that some people have problems if they don't use a reliable 5V power supply. I'll use my DMM and see what the voltage is.
This is the ESP32-CAM I have:
https://www.universal-solder.ca/product/esp32-camera-kit-2mp-wifi-bluetooth-240mhz-dual-core/
Edit: Vin = 5.01V.
There's nothing in the docs that says I need to define the camera model; the CameraWebServer example expects the camera model to be defined, but that's primarily to setup the pin defines. My sketch includes the pin defines for the camera model following this comment line:
That is the example I loaded up to compare. I totally missed the section where you defined it. My bad.
Yeah, I would say brownout is likely the cause. If you are powering it from your computer because you are using the serial from there then that is likely. Power from external source and connect only TX/RX to an FTDI if you have one.
The strange thing is, if I remove all non-camera related code, and program it to take a picture in the setup function, it works. Even if I don't change the pins that are connected or modify any wiring or connections. So I wonder if it's something to do with the pin (I've tried GPIO13 and GPIO15) the RCWL-0516 is connected to.
How is the RCWL-0516 getting power? With the camera module alone with the ESP32, power delivery from your motherboard might be inadequate or just on the edge(intermittent brownouts) and then adding a bit more of a power draw would just make it worse. I would measure it on your multimeter but depending on your meter, it might not be quick enough to pick it up.
Or as a test and you don't have an FTDI available, merge your code with the wifi version and test with an external power supply you know you can trust. If everything works including the sensor, you have a solution.
I don't have an external 5V power supply. The RCWL-0516 is connected to an Arduino Uno, which is serving as my "bench power supply" for sensors. 🤣
I'm trying to put together a 9V to 5V linear voltage regulator with an LM317T, but that'll be finished tomorrow. I'll see if it makes a difference if I use it to power the ESP32-CAM.
I built a basic linear voltage regulateor using an LM317T, and it puts out 5.06V. I powered the ESP32-CAM with this "power supply" but it still crashes with the same excepntion. Maybe it's because of the pin I'm using for the sensor.
I also tried powering the ESP32-CAM with 3.3V from the FTDI (right acronym?) and that still fails with the same exception.
I'll have to re-write my code to not use interrupts; I have no idea how to fix this.
Perhaps the question should be "which pins aren't used by the camera or the micro-SD card and can be used by a motion sensor?".
Here I am linking an article about interrupts for ESP32. handling-esp32-gpio-interrupts-tutorial
Note the section Interrupt Service Routine, it mentions how it should be done according to the ESP32 documentation. I suspect the way you are calling it might be the problem. I don't know very much about this. They linked the documentation that has a little more detail, I would check that out.