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.

However the casing was too nice not to be used in any other way.

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.

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. 

Antenna (optional)

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:

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"