Hi, I am trying to set up the camera on the ESP-EYE, right now I have a loop which takes a photo and saves it into my image[][] array. When the pointer fb is freed the second time the program loops I get a heap corruption.
#include "esp_camera.h"
#include "esp_timer.h"
#include "img_converters.h"
#include "Arduino.h"
#include "soc/soc.h" // Disable brownour problems
#include "soc/rtc_cntl_reg.h" // Disable brownour problems
#include "driver/rtc_io.h"
#include <FS.h>
uint8_t image[160][120];
// ESP-EYE camera module pin-out
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 4
#define SIOD_GPIO_NUM 18
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 36
#define Y8_GPIO_NUM 37
#define Y7_GPIO_NUM 38
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 35
#define Y4_GPIO_NUM 14
#define Y3_GPIO_NUM 13
#define Y2_GPIO_NUM 34
#define VSYNC_GPIO_NUM 5
#define HREF_GPIO_NUM 27
#define PCLK_GPIO_NUM 25
#define SOBEL_THRESHOLD 50
#define HOUGH_THRESHOLD 110
void setup() {
// Serial port for debugging purposes
Serial.begin(115200);
// Turn-off the 'brownout detector'
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
// ESP-EYE camera module
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_GRAYSCALE;
config.frame_size = FRAMESIZE_QQVGA;
config.jpeg_quality = 10;
config.fb_count = 1;
pinMode(13, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
// Camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
ESP.restart();
}
else
{
Serial.println("camera initialised");
}
}
void loop() {
Serial.println("start loop");
camera_fb_t * fb = NULL; // pointer
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
}
for (uint8_t x = 0; x < 158; x++)
{
for (uint8_t y = 0; y < 118; y++)
{
image[x][y] = *(fb->buf);
(fb->buf)++;
}
}
delay(1000);
esp_camera_fb_return(fb);
free(fb);
}
and here is the serial output with the error:
camera initialised
start loop
start loop
CORRUPT HEAP: Bad head at 0x3ffb96dc. Expected 0xabba1234 got 0x3ffb99b0
assertion "head != NULL" failed: file "/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap_poisoning.c", line 214, function: multi_heap_free
abort() was called at PC 0x400dc223 on core 1
Backtrace: 0x400900d4:0x3ffb1ea0 0x40090301:0x3ffb1ec0 0x400dc223:0x3ffb1ee0 0x4008fd65:0x3ffb1f10 0x4008705e:0x3ffb1f30 0x40087519:0x3ffb1f50 0x4000bec7:0x3ffb1f70 0x400d14c5:0x3ffb1f90 0x400d1e55:0x3ffb1fb0 0x4008cd89:0x3ffb1fd0
Rebooting...
Thanks!!
gcjr
March 10, 2020, 3:21pm
2
why are you freeing something you didn't allocate?
Hi Grey, thanks for the quick reply! If I comment the free(fp) I get this:
camera initialised
start loop
start loop
start loop
start loop
start loop
start loop
start loop
start loop
start loop
start loop
start loop
start loop
start loop
Guru Meditation Error: Core 1 panic'ed (LoadStoreError). Exception was unhandled.
Core 1 register dump:
PC : 0x4008795f PS : 0x00060630 A0 : 0x80087824 A1 : 0x3ffb3480
A2 : 0x3ffb92f4 A3 : 0x3ffb878c A4 : 0x40000000 A5 : 0x3ffb8774
A6 : 0x00060620 A7 : 0x00000000 A8 : 0x00000009 A9 : 0x00000044
A10 : 0x00000028 A11 : 0x00060623 A12 : 0x00060620 A13 : 0x3ffb34d0
A14 : 0x00000002 A15 : 0x00000000 SAR : 0x00000000 EXCCAUSE: 0x00000003
EXCVADDR: 0x40000000 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0xffffffff
Backtrace: 0x4008795f:0x3ffb3480 0x40087821:0x3ffb34a0 0x400884bb:0x3ffb34c0 0x4008cd89:0x3ffb34f0
Rebooting...
gcjr
March 10, 2020, 3:45pm
4
add prints to determine which line of code is causing the problem. are you completing the copy or is it the camera_fb_return().
add a delay after the print so the transmission can complete before the next line & crash occur
why if image is 160x120 are you only copying 158 x 118?
(meant to be 160x120 my bad, have corrected now)
Ok I have added in loads of prints and delays and the error occurs in esp_camera_fb_get() on the 13th loop.
For starters.
The root of the issue would be what ever is causing this: EXCVADDR: 0x40000000. I'd suspect your array is doing a wonky, like writing beyond it bounds or you may be encountering an error where the ESP32 does not clear out the memory when it selects an area for an array.
Instead of uint8_t image[160][120]; consider uint8_t image[160][120] = {};. The ={} causes the memory area allocated to be cleared and filled with default values, in this case all 0's.
Also, you would want to learn the difference between GPIO 0-31 and GPIO 32->. The ESP32 has 2 32 bit GPIO ports, A and B. Port B's GPIO matrix is different then Port A's. One thing is that Port B is input only. All this and more is explained in the documentation of the ESP32, API Reference - ESP32 - — ESP-IDF Programming Guide latest documentation .
Instead of this camera_config_t config; use camera_config_t config={};
Are you 100.01% sure nothing else is using timer 0?
** ledc: 0 => Group: 0, Channel: 0, Timer: 0
** ledc: 1 => Group: 0, Channel: 1, Timer: 0
** ledc: 2 => Group: 0, Channel: 2, Timer: 1
** ledc: 3 => Group: 0, Channel: 3, Timer: 1
** ledc: 4 => Group: 0, Channel: 4, Timer: 2
** ledc: 5 => Group: 0, Channel: 5, Timer: 2
** ledc: 6 => Group: 0, Channel: 6, Timer: 3
** ledc: 7 => Group: 0, Channel: 7, Timer: 3
** ledc: 8 => Group: 1, Channel: 8, Timer: 0
** ledc: 9 => Group: 1, Channel: 9, Timer: 0
** ledc: 10 => Group: 1, Channel: 10, Timer: 1
** ledc: 11 => Group: 1, Channel: 11, Timer: 1
** ledc: 12 => Group: 1, Channel: 12, Timer: 2
** ledc: 13 => Group: 1, Channel: 13, Timer: 2
** ledc: 14 => Group: 1, Channel: 14, Timer: 3
** ledc: 15 => Group: 1, Channel: 15, Timer: 3
If there is another library operation using a timer and that operation does not define which timer to use that operation will be given the 1st timer on the list, 0. If something else happens to also use timer 0, you get FUBAR.
I will look into what you said but also discovered if I comment out the for loops copying to image I don't get the error
(fb->buf)++;
This is what most certainly causing your crash.
Because
esp_camera_fb_return(fb);
expects to clean up internal data of fb and fails when it tries to clean up buff .
arduino_new:
(fb->buf)++;
This is what most certainly causing your crash.
Because
esp_camera_fb_return(fb);
expects to clean up internal data of fb and fails when it tries to clean up buff .
thanks that fixed it!! I made a new pointer ptr and set ptr = fb->buf then in the for loop set image[x][y] = *ptr