Close
0%
0%

Bird Feeder Cam

Welcome to our innovative school project: the Bird Feeder Camera!

Similar projects worth following
386 views
0 followers
With Arduino, we've crafted a setup that not only invites our feathered friends for a snack but that also captures photos of them. And if you want to see birds in action, you can start a stream option. Let's dive into the details of our creation, showcasing the fusion of creativity, engineering, and bird lovers! 🐤🐦

(Arthur's old research)

First of all, we thought on doing a localhost site where our image will be uploaded. We did an HTML and PHP code which receive the pictures from the ESP-32 cam and print them on our site.

After several research and studies, we arrived to the conclusion that it will saturated pretty fast because of the memory on the computer. After that, we decided to move on drive, which is removing the problem. 

camera_index.h

h - 147.18 kB - 05/29/2024 at 17:50

Download

app_httpd.cpp

cpp - 43.25 kB - 05/29/2024 at 17:50

Download

camera_pins.h

h - 7.94 kB - 05/29/2024 at 17:50

Download

README.md

md - 29.00 bytes - 05/29/2024 at 17:50

Download

Base64.h

h - 2.84 kB - 05/29/2024 at 17:50

Download

View all 8 files

  • 1 × ESP32 Cam
  • 1 × VL53L1X Sensor
  • 2 × Solar Panels
  • 1 × Battery LP803465
  • 20 × Wires

View all 6 components

View all 20 project logs

  • 1
    Start with the code

    Make sure it works.

    //Libraries
    #include <WiFi.h>
    #include <WiFiClientSecure.h>
    #include "soc/soc.h"
    #include "soc/rtc_cntl_reg.h"
    #include "Base64.h"
    #include "esp_camera.h"
    
    #include <VL53L1X.h>
    #define SDA 15
    #define SCL 14
    
    //CAMERA_MODEL_AI_THINKER GPIO.
    #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
    
    //Enter your WiFi ssid and password.
    const char* ssid = "Enamor";
    const char* password = "romaneromane";
    //======================================== 
    
    //Replace with your "Deployment ID" and Folder Name.
    String myDeploymentID = "AKfycbxMCVfz7Ige6_Sm1PgfUB-OH_5-lhg8pToatdPfY6NjS_NZIL5wd6v5BlH9_JKca7DzgA";
    String myMainFolderName = "ESP32-CAM";
    //======================================== 
    
    WiFiClientSecure client;
    
    VL53L1X sensor;
    
    // This is to test the connection to "script.google.com".
    void Test_Con() {
      const char* host = "script.google.com";
      while(1) {
        Serial.println("-----------");
        Serial.println("Connection Test...");
        Serial.println("Connect to " + String(host));
      
        client.setInsecure();
      
        if (client.connect(host, 443)) {
          Serial.println("Connection successful.");
          Serial.println("-----------");
          client.stop();
          break;
        } else {
          Serial.println("Connected to " + String(host) + " failed.");
          Serial.println("Wait a moment for reconnecting.");
          Serial.println("-----------");
          client.stop();
        }
        delay(1000);
      }
    }
    
    // For capturing and sending photos to Google Drive.
    void SendCapturedPhotos() {
      const char* host = "script.google.com";
      Serial.println();
      Serial.println("-----------");
      Serial.println("Connect to " + String(host));
      
      client.setInsecure();
    
      if (client.connect(host, 443)) {
        Serial.println("Connection successful.");
    
        //.............................. Taking a photo.
        Serial.println();
        Serial.println("Taking a photo...");
        
        for (int i = 0; i <= 3; i++) {
          camera_fb_t * fb = NULL;
          fb = esp_camera_fb_get();
           if(!fb) {
              Serial.println("Camera capture failed");
              Serial.println("Restarting the ESP32 CAM.");
              delay(1000);
              ESP.restart();
              return;
            } 
          esp_camera_fb_return(fb);
          delay(200);
        }
      
        camera_fb_t * fb = NULL;
        fb = esp_camera_fb_get();
        if(!fb) {
          Serial.println("Camera capture failed");
          Serial.println("Restarting the ESP32 CAM.");
          delay(1000);
          ESP.restart();
          return;
        } 
        
        Serial.println("Taking a photo was successful.");
    
        //.............................. Sending image to Google Drive.
        Serial.println();
        Serial.println("Sending image to Google Drive.");
        Serial.println("Size: " + String(fb->len) + "byte");
        
        String url = "/macros/s/" + myDeploymentID + "/exec?folder=" + myMainFolderName;
    
        client.println("POST " + url + " HTTP/1.1");
        client.println("Host: " + String(host));
        client.println("Transfer-Encoding: chunked");
        client.println();
    
        int fbLen = fb->len;
        char *input = (char *)fb->buf;
        int chunkSize = 3 * 1000; //--> must be multiple of 3.
        int chunkBase64Size = base64_enc_len(chunkSize);
        char output[chunkBase64Size + 1];
    
        Serial.println();
        int chunk = 0;
        for (int i = 0; i < fbLen; i += chunkSize) {
          int l = base64_encode(output, input, min(fbLen - i, chunkSize));
          client.print(l, HEX);
          client.print("\r\n");
          client.print(output);
          client.print("\r\n");
          delay(100);
          input += chunkSize;
          Serial.print(".");
          chunk++;
          if (chunk % 50 == 0) {
            Serial.println();
          }
        }
        client.print("0\r\n");
        client.print("\r\n");
    
        esp_camera_fb_return(fb);
    
        //.............................. Waiting for response.
        Serial.println("Waiting for response.");
        long int StartTime = millis();
        while (!client.available()) {
          Serial.print(".");
          delay(100);
          if ((StartTime + 10 * 1000) < millis()) {
            Serial.println();
            Serial.println("No response.");
            break;
          }
        }
        Serial.println();
        while (client.available()) {
          Serial.print(char(client.read()));
        } 
      }
      else {
        Serial.println("Connected to " + String(host) + " failed.");
      Serial.println("-----------");
      client.stop();
    }
    
    
    void setup() {
      // Disable brownout detector.
      WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
      
      Serial.begin(115200);
      Serial.println();
      delay(1000);
      
      // Setting the ESP32 WiFi to station mode.
      Serial.println();
      Serial.println("Setting the ESP32 WiFi to station mode.");
      WiFi.mode(WIFI_STA);
    
      //The process of connecting ESP32 CAM with WiFi Hotspot / WiFi Router.
      Serial.println();
      Serial.print("Connecting to : ");
      Serial.println(ssid);
      WiFi.begin(ssid, password);
      
      // The process timeout of connecting ESP32 CAM with WiFi Router is 20 seconds.
      // If within 20 seconds the ESP32 CAM has not been successfully connected to WiFi, the ESP32 CAM will restart.
    
      int connecting_process_timed_out = 20; //--> 20 = 20 seconds.
      connecting_process_timed_out = connecting_process_timed_out * 2;
      while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        digitalWrite(FLASH_LED_PIN, HIGH);
        delay(250);
        digitalWrite(FLASH_LED_PIN, LOW);
        delay(250);
        if(connecting_process_timed_out > 0) connecting_process_timed_out--;
        if(connecting_process_timed_out == 0) {
          Serial.println();
          Serial.print("Failed to connect to ");
          Serial.println(ssid);
          Serial.println("Restarting the ESP32 CAM.");
          delay(1000);
          ESP.restart();
        }
      }
      
      Serial.println();
      Serial.print("Successfully connected to ");
      Serial.println(ssid);
      //Serial.print("ESP32-CAM IP Address: ");
      //Serial.println(WiFi.localIP());
    
      //---------------------------------------- Set the camera ESP32 CAM.
      Serial.println();
      Serial.println("Set the camera ESP32 CAM...");
      
      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_sccb_sda = SIOD_GPIO_NUM;
      config.pin_sccb_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;
      
      // init with high specs to pre-allocate larger buffers
      if(psramFound()){
        config.frame_size = FRAMESIZE_UXGA;
        config.jpeg_quality = 10;  //0-63 lower number means higher quality
        config.fb_count = 2;
      } else {
        config.frame_size = FRAMESIZE_SVGA;
        config.jpeg_quality = 8;  //0-63 lower number means higher quality
        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);
        Serial.println();
        Serial.println("Restarting the ESP32 CAM.");
        delay(1000);
        ESP.restart();
      }
    
      sensor_t * s = esp_camera_sensor_get();
    
      // Selectable camera resolution details :
      // -UXGA   = 1600 x 1200 pixels
      // -SXGA   = 1280 x 1024 pixels
      // -XGA    = 1024 x 768  pixels
      // -SVGA   = 800 x 600   pixels
      // -VGA    = 640 x 480   pixels
      // -CIF    = 352 x 288   pixels
      // -QVGA   = 320 x 240   pixels
      // -HQVGA  = 240 x 160   pixels
      // -QQVGA  = 160 x 120   pixels
      s->set_framesize(s, FRAMESIZE_SXGA);  //--> UXGA|SXGA|XGA|SVGA|VGA|CIF|QVGA|HQVGA|QQVGA
    
      Serial.println("Setting the camera successfully.");
      Serial.println();
    
      delay(1000);
    
      Test_Con();
    
      Serial.println();
      Serial.println("ESP32-CAM captures and sends photos to the server every 10 seconds.");
      Serial.println();
      delay(2000);
    
    
      Wire.begin(SDA, SCL);
    
      sensor.setTimeout(500);
        if (!sensor.init())
      {
        Serial.println("Failed to detect and initialize sensor!");
        while (1);
      }
      sensor.setDistanceMode(VL53L1X::Short);
      sensor.setMeasurementTimingBudget(5000);
      sensor.startContinuous(50);
    }
    
    
      void loop() {
        Serial.println(sensor.read());
        if(sensor.read() < 200) { 
          SendCapturedPhotos();
          delay(1000);
        }
      Serial.println(sensor.read());
    }
    
  • 2
    Buy the components and make the circuit

    You'll find the component's names above.

  • 3
    When all the electronic is ready, make the first part of the house.

    The module in the center of the house.

    Wood laser plan OR 3D model plan (soon maybe yes maybe not :D) :

View all 4 instructions

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates