1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <!--Favicon--> 8 <link rel="shortcut icon" href="/assets/icon.png" type="image/x-icon"> 9 10 <!-- Font Awesome --> 11 <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.9.0/css/all.css" 12 integrity="sha384-i1LQnF23gykqWXg6jxC2ZbCbUMxyw5gLZY6UiUS98LYV5unm8GWmfkIS6jqJfb4E" crossorigin="anonymous"> 13 14 <!-- Spoqa Han Sans --> 15 <link href='//spoqa.github.io/spoqa-han-sans/css/SpoqaHanSans-kr.css' rel='stylesheet' type='text/css'> 16 17 <!-- CSS --> 18 <link rel="stylesheet" href="/assets/css/main.css"> 19 20 <!-- OG Tag --> 21 22 <meta name="title" content="Benjamin Ropple-Hummingbird Cam - Version 1" /> 23 <meta name="author" content="Benjamin Ropple" /> 24 <meta name="keywords" content="Quick Projects,ESP-32,ESP32-CAM,Camera,Hummingbirds" /> 25 <meta name="description" content="A low-cost, motion-triggered camera" /> 26 <meta name="robots" content="index,follow" /> 27 28 <meta property="og:title" content="Benjamin Ropple-Hummingbird Cam - Version 1" /> 29 <meta property="og:description" content="A low-cost, motion-triggered camera" /> 30 <meta property="og:type" content="website, blog" /> 31 <meta property="og:image" 32 content="https://www.benropple.com/assets/img/profile.jpg" /> 33 <meta property="og:site_name" content="Benjamin Ropple" /> 34 <meta property="og:url" content="https://www.benropple.com/2020/09/01/hummingbird-cam.html" /> 35 36 <meta name="twitter:card" content="summary" /> 37 <meta name="twitter:title" content="Benjamin Ropple-Hummingbird Cam - Version 1" /> 38 <meta name="twitter:description" content="A low-cost, motion-triggered camera" /> 39 <meta name="twitter:image" 40 content="https://www.benropple.com/assets/img/profile.jpg" /> 41 42 <title>Benjamin Ropple-Hummingbird Cam - Version 1</title> 43</head> 44<body> 45 <div class="container"> 46 47 48<header> 49 <nav> 50 <ul> 51 52 <!-- others --> 53 <a href="https://www.benropple.com"> 54 <li class="current btn-nav">Main</li> 55 </a> 56 <a href="https://www.benropple.com/portfolio"> 57 <li class="btn-nav">Portfolio</li> 58 </a> 59 <a href="https://www.benropple.com/tags"> 60 <li class="btn-nav">Tags</li> 61 </a> 62 <!--<ul id="icons"> 63 64 65<li> 66 <a href="mailto:[email protected]"> 67 <i class="fas fa-envelope"></i> 68 </a> 69</li> 70 71 72 73<li> 74 <a href="https://www.linkedin.com/in/benjamin-ropple-66aaa1124/" target="_blank"> 75 <i class="fab fa-linkedin"></i> 76 </a> 77</li> 78 79 80 81<li> 82 <a href="https://github.com/bropple" target="_blank"> 83 <i class="fab fa-github"></i> 84 </a> 85</li> 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 </ul>--> 103 104 </ul> 105 </nav> 106</header> 107 108<div id="post"> 109 <section class="post-header"> 110 <h1 class="title">Hummingbird Cam - Version 1</h1> 111 <p class="subtitle">A low-cost, motion-triggered camera</p> 112 <p class="meta"> 113 September 1, 2020 114 </p> 115 </section> 116 <section class="post-content"> 117 <p>The Hummingbird Cam is a motion-triggered camera, featuring an ESP32-CAM development board and a passive infrared sensor.</p> 118 119<p><img src="/assets/img/HummingbirdCam/hummbirddeployed.jpg" alt="Hummingbird Camera" class="width-55" /></p> 120<center> Hummingbird Cam in operation. </center> 121 122<h2> Inspiration </h2> 123<p>Since May 2020, I have observed the hummingbirds that come to drink from the feeders set up around my house. I was able to take some decent pictures of them with a DSLR:</p> 124 125<p><img src="/assets/img/HummingbirdCam/BackyardHummBirbs.jpg" alt="Hummingbirds" class="width-85" /></p> 126<center>Left: Male Ruby-Throated Hummingbird. Right: Female Ruby-Throated Hummingbird. 127<br /> 128Photos taken with a Nikon D90 DSLR camera. 129</center> 130 131<p><br /></p> 132 133<p>While I am able to take high-quality pictures of the hummingbirds with a normal camera, I have to wait for them to appear and manually take a photo each time. I would also sometimes startle the hummingbirds if I got too close, causing them to fly away. This is when I came up with the idea of using a motion-triggered camera. A motion-triggered camera would be able to take pictures of the hummingbirds up close without disturbing them. Products like this exist already for taking pictures of animals (trail cams), but that would take the fun out of building one.</p> 134 135<p><br /></p> 136 137<h2> Components </h2> 138<p>After doing some research online, I found components that would help me achieve this goal. The following section describes the devices and parts I used to build the Hummingbird Camera.</p> 139 140<p><br /></p> 141 142<h3> ESP32-CAM </h3> 143 144<p><img src="/assets/img/HummingbirdCam/esp32cam.jpg" alt="ESP32-CAM module" class="width-35" /></p> 145<center> The ESP32-CAM development board. </center> 146 147<p><br /></p> 148 149<p>The ESP32-CAM is a development board created specifically for use with a camera module. It uses the ESP32-S microcontroller developed by Espressif Systems. The microcontroller itself operates on 3.3V, but the development board has a built-in voltage regulator to convert a 5V input to the required 3.3V. Some of its specifications are listed below:</p> 150 151<figure class="highlight"><pre><code class="language-html" data-lang="html">- Dual-core 32-bit microprocessor, with adjustable clock speed from 80MHz to 240MHz 152- 520kB RAM + 4MB PSRAM 153- ULP co-processor 154- WiFi and Bluetooth connectivity 155- Built-in SD card slot 156- ZIF connector for camera module</code></pre></figure> 157 158<p>Detailed specifications for the ESP32-S microcontroller can be found in <a href="https://www.es.co.th/Schemetic/PDF/ESP32.PDF">its datasheet</a>.</p> 159 160<p><br /></p> 161 162<p>The ESP32-CAM comes with an OV2640 camera module, a 2MP camera that supports a maximum resolution of 1632x1232. The picture settings can be modified in software, which can change the brightness, exposure, saturation, etc.</p> 163 164<p><br /></p> 165 166<p>The ESP32-CAM can enter a deep-sleep state, where it only draws 20μA-150μA depending on the usage of the ULP coprocessor. The ESP32-CAM can wake up from deep sleep using an external wakeup <a href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/sleep_modes.html">as described on Espressifâs website</a>.</p> 167 168<h3> HC-SR501 Passive Infrared Sensor </h3> 169 170<p><img src="/assets/img/HummingbirdCam/PIR.jpg" alt="PIR Module" class="width-45" /></p> 171<center> HC-SR501 Module. </center> 172 173<p><br /></p> 174 175<p>The HC-SR501 passive infrared (PIR) sensor is used to detect motion. It accepts an input voltage range from 5V to 20V and outputs a 3.3V signal when it detects motion. The time the signal is high and the detection range can be adju
175sted using the potentiometers on the board. The module also has two modes: single-trigger mode, where the output pulses for the set duration, or continuous mode, where the output stays high as long as it detects movement.</p> 176 177<p><br /></p> 178 179<h3> 18650 Lithium-Ion Battery</h3> 180 181<p><img src="/assets/img/HummingbirdCam/18650.jpg" alt="18650 Battery" class="width-40" /></p> 182<center> An 18650 battery. </center> 183<p><br /> 184<br /></p> 185 186<p>I chose to use an 18650 battery from an old Raspberry Pi handheld project I worked on back in 2017. The one I used has a 2000mAh capacity. 187<br /></p> 188 189<p><img src="/assets/img/HummingbirdCam/18650shield.jpg" alt="18650 Shield" class="width-45" /></p> 190<center> 18650 battery shield. </center> 191<p><br /> 192<br /></p> 193 194<p>Additionally, I used a modified 18650 Raspberry Pi shield from the same project, which essentially manages the power usage of the battery. It allows the battery to recharge from a 5V input and it steps up the 3.7V from the battery to a 5V output.</p> 195 196<p><br /></p> 197 198<h3> Crayon Box </h3> 199 200<p><img src="/assets/img/HummingbirdCam/CrayonBox.jpg" alt="Crayon Box" class="width-45" /></p> 201<center> A "Super Stacker" crayon box. </center> 202 203<p><br /></p> 204 205<p>Believe it or not, the case is actually a crayon box. I used this as the projectâs enclosure because itâs small, readily available, and extremely low-cost: theyâre only $1 each at the local supermarket. Itâs also clear enough to take decent pictures through it while still offering some degree of protection from the elements.</p> 206 207<p><br /></p> 208 209<p>I tested the water resistance of the box by placing paper inside, closing it, and putting it in the shower for a few minutes. It keeps out most of the water on its own, but some drops managed to slip in. This is mitigated by either sealing or covering the edges with each use. Covering each edge from front to back with plastic wrap and tape keeps all droplets out. The seal can also be made tighter by placing a thick tape around the edge, where the lid touches the case. The case canât withstand being submerged for very long, so no underwater pictures.</p> 210 211<p><br /></p> 212 213<h3> Various Other Parts </h3> 214<p>To hold everything together, I used a solder board, female and male header pins, wires, and hot glue. A male USB cable was tucked inside and can be extended outside of the case to recharge the battery. A small switch was added to turn the device on and off. A Dremel was used to make a hole in the lid for the sensor to fit through.</p> 215 216<p><img src="/assets/img/HummingbirdCam/hummcaminside.jpg" alt="Inside" class="width-55" /></p> 217<center> The completed Hummingbird Cam - version 1. </center> 218<p><br /> 219I initially used zip-ties to hold the camera in place, but I cut two slots on either side of the case later on for reusable Velcro straps.</p> 220 221<p><br /></p> 222 223<p>There is a header on the left side of the solder board for connecting a serial programmer, and a jumper for grounding IO-0 to put the ESP32-S into download mode. Programming the ESP32-CAM is tedious, as the jumper has to be moved back and forth when testing new code.</p> 224 225<p><br /></p> 226 227<p>Note: I used a BJT circuit to pull a pin on the ESP32-CAM to ground whenever the PIR module triggered, but I later learned that I didnât need it; the software does support wakeup from a HIGH signal. I may still be able to use the circuit for a future purpose that Iâll discuss later.</p> 228 229<p><br /></p> 230 231<h2> Programming </h2> 232<p>The Arduino IDE is used to program the ESP32-CAM, with an additional extension provided by Espressif. The code is written in C++. An external serial programmer is required to program the board, as it doesnât have a USB port. The code I used for this can be found on <a href="https://github.com/bropple/HummingbirdCam">my Github profile</a>.</p> 233 234<p><br /></p> 235 236<h2> Results </h2> 237 238<p><img src="/assets/img/HummingbirdCam/camsetup.jpg" alt="Camera Setup" class="width-55" /></p> 239<center> The placement of the Hummingbird Cam - before the addition of Velcro straps. </center> 240<p><br /></p> 241 242<p>The Hummingbird Cam functioned as intended when set up next to a hummingbird feeder. It sometimes triggers from the wind blowing the feeder and nearby plants around, but in most cases it captures the intended subjects. Below are some of the best photos taken so far:</p> 243 244<p><br /></p> 245 246<p><img src="/assets/img/HummingbirdCam/hummhover.jpg" alt="Hummingbird1" class="width-75" /></p> 247<center> Hovering hummingbird. </center> 248<p><br /> 249<img src="/assets/img/HummingbirdCam/hummhoverleft.jpg" alt="Hummingbird2" class="width-75" /></p> 250<center> A hummingbird approaching from the left. </center> 251<p><br /> 252<img src="/assets/img/HummingbirdCam/hummhoverright.jpg" alt="Hummingbird3" class="width-75" /></p> 253<center> A hummingbird looking away from the camera. </center> 254<p><br /> 255<img src="/assets/img/HummingbirdCam/hummbackperch.jpg" alt="Camera Setup" class="width-75" /></p> 256<center> A perched hummingbird facing away from the camera. </center> 257<p><br /> 258<img src="/assets/img/HummingbirdCam/hummbehind.jpg" alt="Camera Setup" class="width-75" /></p> 259<center> A hummingbird hovering right in front of the camera. </center> 260<p><br /> 261<img src="/assets/img/HummingbirdCam/hummface.jpg" alt="Camera Setup" class="width-75" /></p> 262<center> A hummingbird facing the camera from the opposite side of the feeder. </center> 263<p><br /> 264<img src="/assets/img/HummingbirdCam/hummface2.jpg" alt="Camera Setup" class="width-75" /></p> 265<center> A perched hummingbird, still flapping its wings. </center> 266<p><br /></p> 267 268<p>There were also a couple of interesting moments captured by the camera, but they are less clear:</p> 269 270<p><br /></p> 271 272<p><img src="/assets/img/HummingbirdCam/weirdhumm1.jpg" alt="Camera Setup" class="width-75" /></p> 273<center> Two hummingbirds fighting. </center> 274<p><br /> 275<img src="/assets/img/HummingbirdCam/weirdhumm2.jpg" alt="Camera Setup" class="width-75" /></p> 276<center> A hummingbird sticking its tongue out. </center> 277<p><br /></p> 278 279<p>The Hummingbird Cam works reasonably well, but there are still a few issues to work out. The brightness and saturation in some of the photos are far too high. This seems to have the worst impact during the day, when the sun shines brightest on that side of the house. It takes better photos during the afternoon and evening. These parameters can be adju
279sted to an extent in software.</p> 280 281<p><br /></p> 282 283<p>The case used to protect the electronics also adds a slight blue tint to the images. This can easily be corrected on a computer, but it is possible to do this on the ESP32-CAM right after taking a picture.</p> 284 285<p><br /></p> 286 287<h2> Future Work </h2> 288<p>Iâve looked into adding more features to the Hummingbird Cam, as it is pretty simple in its current state. Some of the features Iâd like to add are listed below:</p> 289 290<figure class="highlight"><pre><code class="language-html" data-lang="html">1. Power usage monitoring 2912. Photos with the proper timestamp 2923. A hardware user interface 2934. A Bluetooth interface that can be accessed through an Android app 2945. Temperature sensors, for inside and outside the enclosure 2956. A better charging port for the 18650 shield</code></pre></figure> 296 297<p>Implementing these features using only the ESP32-CAM to control all the peripherals may present an issue. Below is a schematic of the ESP32-CAM development board:</p> 298 299<p><img src="/assets/img/HummingbirdCam/esp32camdiag.webp" alt="ESP32-CAM Schematic" class="width-95" /></p> 300<center> The schematics of the ESP32-CAM module. </center> 301<p><br /></p> 302 303<p>The top right-hand corner of the schematics shows the two 8-pin headers on either side of the module. Every pin is either designated for power, ground, download mode, or a signal line for the SD card and camera. If I used these pins for anything else, it would potentially interfere with using the SD card. The only pins that wonât interfere with the camera and SD card are U0TXD and U0RXD: the pins used for serial communication. Since I want to use both the SD card and the camera, I want to avoid connecting anything else to those pins, except HS2_DATA3 as the ext0 RTC wakeup pin.</p> 304 305<p><br /></p> 306 307<p><img src="/assets/img/HummingbirdCam/ardunano.jpg" alt="Arduino Nano" class="width-45" /></p> 308<center> An Arduino Nano, an ATmega328p development board. </center> 309<p><br /></p> 310 311<p>Iâve contemplated adding an Arduino Nano (with some bidirectional level shifters) inside the case as a companion device. The Arduino would be able to exchange information with the ESP32-CAM using serial communication on U0TXD and U0RXD, and would consume less power than leaving WiFi or Bluetooth on.</p> 312 313<p><br /></p> 314 315<p>The Arduino could also have an extra benefit: It can eliminate the need for an external programmer, since it can be programmed as one. If the BJT pull-down circuit is connected to an Arduino output at the base, and the collector output is changed to pull down IO-0 on the ESP32-CAM, the Arduino could ground the download pin on the ESP32-CAM automatically before programming.</p> 316 317<p><br /></p> 318 319<p><img src="/assets/img/HummingbirdCam/oledtemp.jpg" alt="Parts" class="width-40" /></p> 320<center> Left: A 0.96" i2c OLED display. Right: A DS18B20 one-wire temperature sensor. </center> 321 322<p><img src="/assets/img/HummingbirdCam/RTCbutton.jpg" alt="More Parts" class="width-40" /></p> 323<center> Left: A DS3231 RTC module. Right: Soft push buttons. </center> 324<p><br /></p> 325 326<p>When not being used to program the ESP32-CAM, the Arduino can be switched to a different mode to support peripherals like a small i2c display, an i2c real-time clock (RTC), some one-wire temperature sensors, and several buttons. The Arduino can read the voltage level of the battery and the output of a Hall Effect sensor using its ADC inputs. The Arduino could then communicate with the ESP32-CAM over the same serial pins it uses to program it. When not in use, the Arduino can enter deep sleep mode, similarly to the ESP32-CAM.</p> 327 328<p><br /></p> 329 330<p>As of now, I think I am limited to a single GPIO pin for wakeup, since ext1 wakeup mode uses pins that arenât exposed on this board. To get around this, I can have the Arduino send a code over serial as it triggers the wakeup and have the ESP32-CAM enter a different mode as it receives it. This would only need a few milliseconds to process, and would be sufficient to know the difference between a motion trigger wakeup and an Arduino wakeup.</p> 331 332<p><br /></p> 333 334<p>The WiFi capability of the ESP32-CAM could be used to update its own internal RTC at periodic intervals or after receiving a command; however, its RTC is not very accurate and has no battery backup. It would be better in my case to use a more accurate RTC module with a small battery backup to store time information, and only update it as needed.</p> 335 336<p><br /></p> 337 338<p>These proposed additions require testing to see if it will work. I already have all the parts I need to get this working, so a future post will describe how this goes.</p> 339 340<p><br /></p> 341 342<h2> Device Schematics </h2> 343<p>The schematics are pretty simple for this version: 344<img src="/assets/img/HummingbirdCam/HummingbirdCamV1.jpg" alt="Hummingbird Cam Schematics" class="width-95" /></p> 345<center> The schematics for the Hummingbird Cam - Version 1. </center> 346 347<p><br /></p> 348 349<h2> Conclusion </h2> 350<p>This post has described the purpose, programming, construction, and deployment of the Hummingbird Cam. It succeeded in capturing many interesting photos of hummingbirds. I hope to improve the device so I can use it in different situations and to photograph other kinds of animals. I will make a post describing the features I add when theyâre finished. Thanks for reading!</p> 351 352 </section> 353</div> 354 355<div id="top" class="top-btn" onclick="moveTop()"> 356 <i class="fas fa-chevron-up"></i> 357</div> 358 359<!-- Disqus --> 360 361 362<!-- Footer --> 363<footer> 364 <div class="footer"> 365 Page content: Copyright © 2020 366 <a href="https://github.com/bropple">Benjamin Ropple</a>. 367 Powered by Jekyll using modified 368 <a href="https://github.com/naye0ng/Grape-Theme">Grape Theme. 369 </div> 370</footer> 371 372
373<script> 374 var lastScrollTop = 0; 375 window.onscroll = function () { 376 var st = document.body.scrollTop || document.documentElement.scrollTop; 377 if (st > 250) { 378 document.getElementById("top").style.display = "block" 379 if (st > lastScrollTop) { 380 document.getElementById("top").style.opacity = 0 381 } else { 382 document.getElementById("top").style.opacity = 1 383 } 384 } else { 385 document.getElementById("top").style.opacity = 0 386 if (st > lastScrollTop) { 387 document.getElementById("top").style.display = "none" 388 } 389 } 390 lastScrollTop = st <= 0 ? 0 : st; 391 } 392 function moveTop() { 393 document.body.scrollTop = 0 394 document.documentElement.scrollTop = 0 395 } 396</script>
396 397 </div> 398</body> 399 400</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.