ESP32 Camera trail camera/photo trap

The story
During the winter time I usually feed wild birds, but unfortunately while working out of my place I can’t see what is going on in my bird feeder. So the solution was to make some photos automatically when I’m away.

How does it work?
Most of the time camera stays in deep sleep mode witch is very energy efficient that means that board does not consume a lot of energy. In the same time solar panel charges the battery. When PIR event occurs camera wake’s up, connect to local wi-fi, make photos and sends them to defined FTP server. If there is no motion again , it goes to sleep. What’s more every 30 minutes camera reports it’s status to mqtt and shows current temperature and wi-fi signal strength.

Bill of materials:

  • esp32 camera module
  • programmer FTDI
  • wi-fi antenna (IPEX to SMA)
  • sr 501 pir sensor but any other pir sensor should do the job
  • 1865 battery 3000mah
  • ds18b20 – one wire temperature sensor
  • 1865 battery holder
  • on-off switch
  • solar panel – 1W, 5,5V, 95mmx95mm
  • li-poly charger - TP4056 5V USB
  • dc converter - STEP-UP MT3608
  • ds18b20 – one wire temperature sensor

Step 1 - program the board
Program the board with attached code sketch - .ino.
Before, change settings inside the code especially:

char ftp_server[] = "192.168.1.XX"; //your FTP IP
char ftp_user[]   = "XX"; //your FTP user name
char ftp_pass[]   = "XXX"; //your FTP pass
const char *ssid =     "XXXX";         // Put your SSID here
const char *password = "XXXX";     // Put your PASSWORD here
const char* mqttServer = "XXX.XXX.X.XX"; // MQTT broker IP, home-assistant 
const int mqttPort = 1883; // MQTT port (domyślnie 1883)
const char* mqttUser = "XX"; // MQTT user
const char* mqttPassword = "XXX"; // MQTT pass
IPAddress ip(192, 168, 1, 22); // trap does not use DHCP so set any free IP address on you router
IPAddress gateway(192, 168, 1, 222); //gateway 
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8); // optional

ftp.ChangeWorkDir("/files"); // change it to reflect your directory

client.publish("cam_trap/temp", (char*)temperatura.c_str()); //set topic for mqtt that will publish the temperature

client.publish("cam_trap/pir","ON"); // set topic for mqtt that will publish the pir sensor status

client.publish("cam_trap/signal", clientRSSI); // set topic for mqtt that will publish the signal strength

Step 2 – programming the board
After setting everything up, just program the board with FTDI programmer – remember to shortage GND and GPIO0 (program mode) and connect RX of programmer to TX of the board (GPIO1)and TX of the programmer to RX (GPIO3) of the board.
Hit upload and after a minute or two everything should be done.

Step 3 – wiring
Schema below show’s how to wire everything up. Most of the parts could be soldered directly, except ds18b20 – one wire temperature sensor – signal of this sensor goes to RX PIN of the board so you will not be able to program board again.


ds18b20 SIGNAL >>GPIO3
ds18b20 VIN >> 3V
ds18b20 GND >> GND

dc converter - STEP-UP MT3608 with multimeter set it to 5V-5,1V
OUT + >> 5V of esp32cam
OUT - >> GND of esp32cam


Step 4 – prepare SD card
format card with FAT32 and insert sd card into esp32

Step 5 – prepare Home Assistant

To get everything working you have to set up mqtt sensors in you configuration.yaml file. Examples are shown below.

  - platform: mqtt
    name: temp_trap
    state_topic: "cam_trap/temp"
    unit_of_measurement: C
  - platform: "mqtt"
    name: "trap_signal"
    state_topic: "cam_trap/signal"
    icon: "mdi:signal"
    unit_of_measurement: "lqi"
  - platform: mqtt
    state_topic: "cam_trap/pir"
    name: "motion_phototrap"
    off_delay: 20

That’s it!!! you are ready to start photographing wild life around you :wink:

Coming soon - how to make enclosure :wink:


Bird pictures?

Yes but probably in the autumn :slight_smile:


Nice project, did you evaluate using an all-in-one ESP32 board like this?

BTW, this is the Redstart (Phoenicurus phoenicurus) family we “adopted” three years ago, and every year they return. This years pups chicks are already flying around :slight_smile:

The nest is in a dark corner and I don’t want to light it, moreover that old D-Link camera sucks, but I’m happy to be the “uncle” of these birds.
WhatsApp Image 2020-05-25 at 11.48.50
WhatsApp Image 2020-05-25 at 11.47.59

So I’m planning to adopt more bird families and more ESP32 CAMs in my garden.

chicks :slight_smile: (pups are young dogs)

Actually i used this kind of esp32 camera. There are a lot of options to set quality of the image. Some kind of solution in dark places could be lighting up them with IR diodes.
Those little guys look grate - congratulations uncle PieBru! :slight_smile:

Thanks @nickrout :slight_smile: I studied English more than half century ago, and rarely exercised it :frowning:

1 Like

Awesome project - love the ESPCAM boards - $8 Australian Dollars! Crazy.

Has anybody seen a NOIR version? i.e. could use infrared LEDs for night-vision?

I have the raspberry PI NOIR camera and that works pretty well. An ESP version would be crazy!

Very nice project do you guys know if have a way to measure battery level?

There are plenty of adc pins on the esp32.

I know but since it’s charging batteries and discharge maybe need diode or something like that to correct measure

Do you have the steps for the enclosure already?

I get this recurring error on my ESP32-CAM on serial output…
What’s wrong?

12:41:25.115 → Rebooting…
12:41:25.115 → ets Jul 29 2019 12:21:46
12:41:25.115 →
12:41:25.115 → rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
12:41:25.160 → configsip: 0, SPIWP:0xee
12:41:25.160 → clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
12:41:25.160 → mode:DIO, clock div:1
12:41:25.160 → load:0x3fff0030,len:1344
12:41:25.160 → load:0x40078000,len:13964
12:41:25.160 → load:0x40080400,len:3600
12:41:25.160 → entry 0x400805f0
12:41:25.996 → E (474) sar_periph_ctrl: s_sar_power_release called, but s_sar_power_on_cnt == 0
12:41:25.996 →
12:41:25.996 → abort() was called at PC 0x40104ec0 on core 1
12:41:25.996 →
12:41:25.996 →
12:41:25.996 → Backtrace: 0x40083b4d:0x3ffcd1f0 0x400977e1:0x3ffcd210 0x4009d3e5:0x3ffcd230 0x40104ec0:0x3ffcd2b0 0x40104ff3:0x3ffcd2d0 0x400dfa53:0x3ffcd2f0 0x400d30fc:0x3ffcd310 0x400db806:0x3ffcd490
12:41:25.996 →
12:41:25.996 →
12:41:25.996 →
12:41:25.996 →
12:41:25.996 → ELF file SHA256: 88806b9eb5320d65
12:41:25.996 →