How to Build a Water-Resistant, Battery-Operated, Low-Power, Motion-Activated, 5 Mega-Pixel WiFi Camera
This project shows you how to build a WiFi camera that sleeps until activated by a microwave motion sensor. It carefully conserves power to maximize battery life. (You can expect to get one or two weeks of use from the battery.) The camera takes great color pictures and movies in a range of sizes from 320x240px to 2592x1944px. The camera's Adafruit Feather M0 sends the pictures to a CGI for image processing and storage. (See the JPEG Catcher project for further details.) There is no SD card in this project. The images are stored "in-your-cloud" where the CGI is hosted. This project teaches you how to move relatively large hunks of data like the camera's 8MB image buffer in small hunks like the WINC1500's 1400 byte MTU over WiFi to a server. It does this using the old-school method of base64 encoding the binary image data. This makes the data into a stream of visible characters that get piped into the CGI on standard input. That stream looks like this JSON object:
[{"name": "battery_percent", "value": "99"},{"name": "json_file", "content_type": "image/jpeg", "value": ""}]
with the empty value of "value" replaced with the Base64 encoded image data. The CGI decodes the data back into binary format and saves it to storage. From there a web server makes the images browsable. See the JPEG Catcher Project for details. The camera has a wide assortment of settings that control all aspects of picture taking. The Camera Settings Project provides a mobile-responsive web page for adjusting those settings. This means you won't have to compile a new binary and load it into the Feather just to adjust the camera's exposure, brightness, or contrast, et cetera. The settings are passed from the web page to a web socket server in the form of Google flatBuffers. This is the new-school way to move relatively-small, fixed length, data structures around the web in binary format. The flatBuffers project provides libraries in many languages so that it's easy to go from JavaScript to C++ and back. This project includes both old and new school data communication methods for at least two reasons;
- There is still a whole lot of legacy code in use and not every robotics/embedded project starts from scratch. Often new technology must be integrated with old technology; CAN bus, MQTT, and Base64 are just a few examples.
- The Internet of Things needs very efficient, low-power, machine-to-machine communication and projects like flatBuffers are a good solution. The need is so ubiquitous it's essential that everyone in the robotics/embedded space is familiar with such solutions.
I used platformio to build this project. If you plan to do the same you'll need to create a platformio.ini file. It should look something like the one below. Replace the items in all-caps with your own configuration.
[common]
lib_deps_external =
https://github.com/arduino-libraries/WiFi101.git
[env:adafruit_feather_m0]
platform = atmelsam
board= adafruit_feather_m0
framework = arduino
upload_port = /dev/YOUR_TTY_DEVICE
upload_speed = 115200
lib_deps = ${common.lib_deps_external}
build_flags =
'-DWIFI_SSID="YOUR WIFI ACCESS POINT SSID"'
'-DWIFI_PASS="YOUR WIFI PASSWORD"'
'-DHTTP_HOST="IP ADDRESS OF YOUR CGI/WEBSOCKET SERVER"'
'-DHTTP_HOST_PORT=4444'
'-DSOCKET_PORT=8880'
'-DHTTP_HOST_URL="/cgi-bin/jpeg_catcher"'
'-std=c++14'
'-std=gnu++14'
build_unflags =
'-std=gnu++11'
- Adafruit Feather M0 WiFi - ATSAMD21 + ATWINC1500
- FeatherWing Proto - Prototyping Add-on For All Feather Boards
- Stacking Headers for Feather - 12-pin and 16-pin female headers
- Lithium Ion Battery Pack - 3.7V 6600mAh
- Uxcell 80mm x 110mm x 70mm ABS Junction Box with PC Transparent Cover
- 8mm Mini 1NO 2Pin Metal Momentary Push Button Switch
- Mini Toggle Switch SPST with Waterproof Cap
- Panel Mount 2.1mm DC barrel jack
- USB to 2.1mm Male Barrel Jack Cable
- Pololu 5V Step-Up Voltage Regulator U1V11F5
- Arducam Mini Module Camera Shield 5MP Plus OV5642 Camera Module
- RCWL-0516 Motion Detection Sensor
- Optional - Fused Silica Optical Glass Disk 1 in. X 0.125 in
- I replaced the stock 90 degree headers on the camera with straight headers to better suit my enclosure. Since I have a de-soldering gun this was relatively easy for me to do.
- In the past I've gotten junction boxes with transparent covers that are very clear and see-through. That wasn't the case this time so I installed the (optional) glass disk as a porthole for the camera to see through.
- After field testing I learned that the Feather can't charge the battery when the 5V regulators are on the battery bus. These now have a switch for "run mode" (on) and "charge mode" (off).
It now seems obvious in hindsight that the motion sensor never wanted to be perched on top of the prototyping board. That put it too close to the Feather and it's 2.4 MHz WiFi radio. The sensor uses the same band. Field testing gave very weird and inconsistent motion detection results so I added a cable to the sensor and used some museum putty to stick it to the inside front cover away from the Feather. This immediately gave excellent and reliable detection results.
Detections now occur as expected. Most happen as the subject moves toward the sensor and away from it. They also happen when a large enough subject (a firetruck or delivery van) sweeps past in the street.
To ge the best color balance take at least four shots together. The camera seems to need that many frames to get the color correct.
- Thank you to wblommaert for his Arduino Websocket Client.
- Thank you to Marty Stepp for his base 64 encoding and decoding library.
- Thank you to the FlatBuffers contributors for the Google FlatBuffers project.
If you find a bug please create an issue. If you'd like to contribute please send a pull request.
I used Doxygen to create the project documentation. You can read it here.
The following were helpful references in the development of this project.
- ArduCAM
- WebSockets
- RCWL-0516 Microwave Motion Sensor