The Idea
In a local shop I bought the cheapest (3.9 Euro) mechanical alarm clock I found, to scavenge the internal clock for this animated carousel.
![](https://cdn.hackaday.io/images/1272601701703857724.jpg)
However the casing was too nice not to be used in any other way.
![](https://cdn.hackaday.io/images/7439791701703937496.jpg)
So I decided to place an esp32-cam inside it with batteries, to be used as an extemporary webcam to watch kids, pets, cooking and so on at a distance.
The circuit
I composed the circuit using boards I had in my "wonder box", but they can be easily bought on AliExpress, EBay or Amazon.
![](https://cdn.hackaday.io/images/8052471701704309020.png)
Note the two 1 MOhm resistors, needed to reduce the battery voltage just to be measured by the ESP32 Analog to Digital Converter.
The assembly
See the positioning of the devices.
![](https://cdn.hackaday.io/images/1340721701721067617.jpg)
- The ESP32-cam board is fixed with some plastic foam glued to the chassis
- The TP4056 Battery Charger board has the USB charger socket back oriented
- The two batteries will be positioned on the bottom side of the case to lower the center of gravity.
- Bottom left there's a small optional antenna, found in an old WiFi router.
Antenna (optional)
![](https://cdn.hackaday.io/images/1580991701761221741.png)
It can be easily built with a small piece of tin. See here the specifications.
Time
OK, I got a beautiful WiFi Camera but I lost the main function for a clock! Therefore, according to a friend of mine, I used a NeoPixel 12 RGB LEDs ring to recreate hours and minutes.
The EspHome is programmed to:
- Flash for 1 second the red LED indicating the hours
- Flash for 1 second the green LED indicating the minutes (0 5 10 15 20 25 30 35 40 45 50 55)
- Stay blank for 1 second
- (repeat)
ESPHome programming
The YAML code is the following
esphome:
name: esp32-cam
friendly_name: ESP32-CAM
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
# Enable connection to my home hotspot
wifi:
networks:
- ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esp32-Cam Fallback Hotspot"
password: "Xy2wARLvmF24"
# Enable the WiFi info
text_sensor:
- platform: wifi_info
ip_address:
name: ESP IP Address
ssid:
name: ESP Connected SSID
bssid:
name: ESP Connected BSSID
mac_address:
name: ESP Mac Wifi Address
scan_results:
name: ESP Latest Scan Results
dns_address:
name: ESP DNS Address
captive_portal:
# Enable SNTP server time synchronization
time:
- platform: sntp
id: sntp_time
timezone: Europe/Rome
# enable the NeoPixel 12 LED's ring
display:
- platform: addressable_light
id: led_matrix_display
addressable_light_id: light_ring
width: 12
height: 1
update_interval: 1000ms
lambda: |-
// Define colors
Color red = Color(0xFF0000);
Color green = Color(0x00FF00);
Color blue = Color(0x0000FF);
Color black = Color(0x000000);
// set timing to be repeated every 3 seconds
int currentSeconds = id(sntp_time).now().second % 3;
int currentPos;
if(currentSeconds == 0){
// flash hours
currentPos = (id(sntp_time).now().hour + 12 - 4) % 12;
it.line(currentPos,0,currentPos,0,red);
}else if (currentSeconds == 1){
// flash minutes
currentPos = id(sntp_time).now().minute/5;
currentPos = (currentPos + 12 - 4) % 12;
it.line(currentPos,0,currentPos,0,green);
}else{
// clear everything
it.line(0,0,0,0,black);
}
# Enable ESP32 camera
esp32_camera:
external_clock:
pin: GPIO0
frequency: 20MHz
i2c_pins:
sda: GPIO26
scl: GPIO27
data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
vsync_pin: GPIO25
href_pin: GPIO23
pixel_clock_pin: GPIO22
power_down_pin: GPIO32
# Image settings
name: esp32-cam
resolution: 1024x768
jpeg_quality: 10
#brightness: 1
agc_gain_ceiling: 8X
# ESP32 Camera web server
esp32_camera_web_server:
- port: 8080
mode: stream
- port: 8081
mode: snapshot
sensor:
# Measure the battery voltage (3.7V nominal)
- platform: adc
pin: GPIO33
name: "esp32-cam battery voltage"
update_interval: 10s
accuracy_decimals: 1
attenuation: 11dB
filters:
- multiply: 2.0 # The voltage divider requires us to multiply by 2.0
- platform: wifi_signal # Reports the WiFi signal strength/RSSI in dB
name: "WiFi Signal dB"
id: wifi_signal_db
update_interval: 60s
entity_category: "diagnostic"
- platform: copy # Reports the WiFi signal strength in %
source_id: wifi_signal_db
name: "WiFi Signal Percent"
filters:
- lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
unit_of_measurement: "Signal %"
entity_category: "diagnostic"
device_class: ""
# Turn on/off a green LED connected to GPIO13
switch:
- platform: gpio
pin: GPIO13
id: gpio13_green_led
name: "esp32-cam green led"
- platform: gpio
pin: GPIO4
id: gpio4_bright_led
name: "esp32-cam bright led"
# The 12 LEDs nepoixel ring
light:
- id: light_ring
platform: neopixelbus
type: GRB
variant: WS2812
pin: GPIO12
num_leds: "12"
method: ESP32_I2S_1
name: "NeoPixel Light"