I wanted a small, battery-powered timelapse camera. First I tried mobile phones but they were not stable in the long term. Previously I’d used a Raspberry Pi which is good, but not battery friendly, a bit big, and a bit of an overkill. A PiZero would be an alternative (untried).
Instead, I choose a ESP32-Cam which can:
- go to deep-sleep (10uA for the ESP, Cam to be tested) overnight
- save JPG files from its mini camera (but good enough) to SD card
- connect to WiFi to transmit / control
- be small and cheap!
I use the following:
- ESP32-Cam from diymore.cc which is similar to AI-Thinker
- 18650 LiPo battery (I would get one with low-voltage protection next time)
- Adafruit Solar Charger
- 3v to 5v USB step up (from battery output to 5V* for Cam)
- FTDI Programmer to flash the firmware
- 1W 6V solar panel (20cmx20cm)
* Note 5V is required for the ESP32-Cam, although the ESP32 needs only 3.3V.
I used a 3.3V / 5V (switchable via toggle) FDTI programmer. I used 5V thinking that I’d supply 5V to VCC and 3.3V to the RX/TX pins. Oops! It actually supplies 5V to RX/TX pins too. Seems ok but better to select 3.3V to get this on the RX/TX and grab a 5V breakout pin to power the board.
A 1W solar panel provides 4Wh/W (Brisbane) x 1W = 4Wh per day.
This is 4Wh / 3.3V = 1.2Ah per day @ 3.3V. Say 1000mA/day. The 18650 battery is 2600mAh, so needs 2.6 days to charge!
Power consumption of the camera is to be tested. ESP32 is 50mA and only 10uA alseep. Maybe 50mA average (?), or 2600mAh / 50mA = 52h on battery. On panels, maybe 50mA * 10h = 500 mAh/day required. To find out!
Lack of GPIO!
The ESP32 needs to know the state of the battery and solar, so it can control itself. It uses the Adafruit solar controller’s output. It also uses time-of-day to off when dark (a PE cell would be an alternative).
Reading voltage required two GPIO pins. However, these are NOT AVAILABLE on the ESP-32 cam. All broken out pins appear to be used by either the SD card or UART or camera. GPIO16 didn’t work. I couldn’t use the SD card pins. The only option I see is to use the TX/RX pins (GPIO1, GPIO3). These are not connected to the ADC so cannot read analog. Also this means serial is not available, but RemoteDebugger library is possible.
GPIO3 (RX) works to read the open-drain of the “charging” or “done” indicator. I can’t get GPIO1 (TX) to read, nor GPIO16. GPIO2 works but is used by the SD card. This comment agrees with the TX/RX issue. Hence only a single digital input is available – either “charging” or “done”. As the least worst, I’ll use “done” to signal that uploading should start.
Hence, the following is ideal, but not possible:
Since the maximum possible voltage is 6V (“the voltage at L+ can rise to whatever comes out of your solar panel”), I use a voltage divider to halve the voltages before measuring with the ESP32’s ADC.
|Lowish Battery, solar powering||L+ > B+ (by < 150mV)|
B+ > 3.2V
|Low Battery||B+ <= 3.2V||Deep sleep|
|Good solar, battery > 50%||L+ > B+ (by > 150mV)|
B+ > 3.5V
|No solar, battery > 50%||L+ < B+|
B+ > 3.5V
|No solar, battery < 50%||L+ < B+|
B+ <= 3.5V
Image File Transfer
Wifi Minimal means upload limited snapshots of the current images, while Wifi Full means upload all images. Some upload options:
- Dropbox based library
- Upload to a server running Apache or similiar, via HTTP
- scp or ftp : no libraries?
The dropbox option looks simplest.
Movie Creation and Monitoring
The general approach is to get the image files to a server as simply as possible. Then do complex stuff on the server.
The latest image is copied to a known location for a webserver to display. A more advanced system would copy one file a minute (or so) to the webserver, which could then have a simliar forward/back viewer to preview the movie.
Every hour (or so), a script runs to create an hour-long movies. It would have to work out which movies are to be updated, based on new images. Use python and ffmpeg, and TimeLapseMovieMaker to create videos.
A “movie-to-now” could be created by joining the hourly movies together.
Also, each day a daily movie could be made.
Images can be deleted once an hourly movie is made. However, how to handle the case where late-arriving images need to be added to an old movie? Perhaps some kind of simple database is required to track images and movies? Or a simple metric of delete-when-7 days old-and-movie-is-make?
Some of the elements are similar to “Blobs” software, but sufficiently different to warrant a new project.
- Implement different tasks (upload, camera, etc) via FreeRTOS.
- Use WifiManger to connect to station or use AP, as required.
- On hard-reset (or some other signal such as flag on web server / physical button / every 1 hour), run configuration webserver.
- Camera loop can sleep between takes
- Time Task to check internet time / RTC (for timestamps)
- Power Task to check power supply and set flags / control operation. Related: sleep when dark.
- Minimal upload can be done after image is taken. If so (i.e. enough battery/solar), it just uploads current image (every nth image) and closes WiFi.
- Full upload as a permanent task which runs when possible.
The separate tasks check their own conditions and block if not required, then a sleep_idle_hook to sleep whenever possible. This is event-driven.
( An option would be to run in a loop, executing tasks when conditions are met. This is a more procedural style. )