ESP32-CAM Power Saving - XCLK undefined reference issue

kevwal
Posts: 3
Joined: Sat Oct 24, 2020 4:02 pm

ESP32-CAM Power Saving - XCLK undefined reference issue

Postby kevwal » Sat Oct 24, 2020 4:05 pm

Hi

I am using the ESP32-CAM board for a project running on batteries and need to save power. I have reduced the CPU frequency and other things, but now I am working on the Camera module. I only need to take a picture once every minute or two, so leaving it on and running all the time is wasting 30mA or so. Before initialising the camera, my device consumes around 50ma, after initialising (and after it settles after taking a picture) it consumes around 70ma.

There is some detailed advice here: https://github.com/espressif/esp32-camera/issues/33 about using the private xclk routines to save power, that apparently work, but I cannot get them to work.


Compiling the code below I get the errors:

Code: Select all

C:\Users\W\AppData\Local\Temp\arduino_build_632483\sketch\Test.ino.cpp.o:(.literal._Z5setupv+0x30): undefined reference to `camera_enable_out_clock(camera_config_t*)'
C:\Users\W\AppData\Local\Temp\arduino_build_632483\sketch\Test.ino.cpp.o:(.literal._Z5setupv+0x34): undefined reference to `camera_disable_out_clock()'
C:\Users\W\AppData\Local\Temp\arduino_build_632483\sketch\Test.ino.cpp.o: In function `setup()':
C:\Users\W\Documents\ESP32 Cam Pico Project\Code\Test/Test.ino:77: undefined reference to `camera_enable_out_clock(camera_config_t*)'
C:\Users\W\Documents\ESP32 Cam Pico Project\Code\Test/Test.ino:81: undefined reference to `camera_disable_out_clock()'
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board AI Thinker ESP32-CAM.
The routines I am calling seem to exist in the binary file libesp32-camera.a which exists on my PC - but how do I use them?

My test code isolating this issue is below:

Code: Select all

#include <esp_camera.h>

// Forward declare cam clock stop/start.
esp_err_t camera_enable_out_clock(camera_config_t *config);
void camera_disable_out_clock();

// 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 //

#define SerialDebug Serial    // Nice names for Serial ports

camera_config_t cam_config;
camera_fb_t *fb; // Declare the variable for the pointer to the framebuffer

void setup() {
    SerialDebug.begin(115200);
   
    setCpuFrequencyMhz(20); // Save power by going slowly

    // Init out Camera
    cam_config.ledc_channel = LEDC_CHANNEL_0;
    cam_config.ledc_timer = LEDC_TIMER_0;
    cam_config.pin_d0 = Y2_GPIO_NUM;
    cam_config.pin_d1 = Y3_GPIO_NUM;
    cam_config.pin_d2 = Y4_GPIO_NUM;
    cam_config.pin_d3 = Y5_GPIO_NUM;
    cam_config.pin_d4 = Y6_GPIO_NUM;
    cam_config.pin_d5 = Y7_GPIO_NUM;
    cam_config.pin_d6 = Y8_GPIO_NUM;
    cam_config.pin_d7 = Y9_GPIO_NUM;
    cam_config.pin_xclk = XCLK_GPIO_NUM;
    cam_config.pin_pclk = PCLK_GPIO_NUM;
    cam_config.pin_vsync = VSYNC_GPIO_NUM;
    cam_config.pin_href = HREF_GPIO_NUM;
    cam_config.pin_sscb_sda = SIOD_GPIO_NUM;
    cam_config.pin_sscb_scl = SIOC_GPIO_NUM;
    cam_config.pin_pwdn = PWDN_GPIO_NUM;
    cam_config.pin_reset = RESET_GPIO_NUM;
    cam_config.xclk_freq_hz = 20000000;
    cam_config.pixel_format = PIXFORMAT_JPEG;
    //init with high specs to pre-allocate larger buffers
    if (psramFound()) {
      SerialDebug.println("  PS RAM Found.");
      cam_config.frame_size = FRAMESIZE_UXGA;
      cam_config.jpeg_quality = 10;
      cam_config.fb_count = 2;
    } else {
      SerialDebug.println("  Error: PS RAM Not Found.");
      cam_config.frame_size = FRAMESIZE_SVGA;
      cam_config.jpeg_quality = 12;
      cam_config.fb_count = 1;
    }

    // Overide the above for testing
    cam_config.frame_size = FRAMESIZE_VGA;
    cam_config.jpeg_quality = 10;  // Quality of JPEG output. 0-63 lower means higher quality
    cam_config.fb_count = 1;

    delay(10000); // doing stuff here
   
    esp_camera_init(&cam_config);

    SerialDebug.printf("  Taking picture:\n");
    setCpuFrequencyMhz(80); // Camera seems to need more than 40mhz to get a picture
    camera_enable_out_clock(&cam_config);
    delay(500);
    fb = esp_camera_fb_get(); // Get the current frame buffer
    delay(500);
    camera_disable_out_clock();
    setCpuFrequencyMhz(20);
    SerialDebug.printf("  Picture length: %d\n", fb->len);
   
    delay(10000); // doing stuff here
   
    esp_camera_fb_return(fb);
 
}



void loop() {
 
}
Thanks very much in advance.
Kevin

kevwal
Posts: 3
Joined: Sat Oct 24, 2020 4:02 pm

Re: ESP32-CAM Power Saving - XCLK undefined reference issue

Postby kevwal » Thu Oct 29, 2020 7:44 pm

Hi All

I am still struggling with this one, is anyone able to help me solve it please?

Thanks
Kevin

kevwal
Posts: 3
Joined: Sat Oct 24, 2020 4:02 pm

Re: ESP32-CAM Power Saving - XCLK undefined reference issue

Postby kevwal » Wed Nov 11, 2020 10:42 pm

FYI, I have solved the "calling XCLK routines from Arduino" issue, they need to be declared like so:

`extern "C" {
esp_err_t camera_enable_out_clock(camera_config_t *config);
void camera_disable_out_clock();
}`

It saves a bit of power and the clock can still be restarted and a picture taken again.

It doesn't save as much as powering down the camera and then powering it up again, but I can't get that to work, it always reboots on me, even though I call esp_camera_deinit() before powering down the camera:

22:36:51.943 -> [E][camera.c:1335] esp_camera_fb_get(): Failed to get the frame on time!
22:36:52.491 -> Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.

Cheers
Kevin

Who is online

Users browsing this forum: No registered users and 11 guests