Working ESPHome config for ttgo ESP32 camera board with microphone

I recently purchased the version of the ttgo camera with the microphone and have been able to get it working in Home Assistant with ESPHome. The configuration is different than other versions of the board so I am posting this for others that might be interested. I am not (yet) doing anything with the microphone itself but the camera, button, PIR sensor, and display all work. You should note the following:

  1. I purchased this item on Aliexpress - https://www.aliexpress.com/item/32968767440.html?spm=a2g0s.9042311.0.0.3da24c4dkWWbwq - I purchased the “color” with the microphone and the fish eye lens.
  2. The seller’s documentation shows the wrong GPIO pins for the button and PIR sensor. I have sent them a message about this.
  3. This gist which I learned about from a Dr. ZZZs video was very helpful. It doesn’t actually work but it provides a pretty good outline of how to setup one of these boards. - https://gist.github.com/Snipercaine/d8345571563536e9661422c3509d1119
  4. This github repo shows the correct pinout and has a working ESPHome config for the camera section - https://github.com/lewisxhe/esp32-camera-series
  5. The order that you list the data pins for the camera does matter. I originally listed them in the order listed on Aliexpress image which is exactly backwards from the config that actually works.
  6. I made a handful of other changes, some were required to get it to work and some were personal preferences. I’m happy to answer questions.
substitutions:
  devicename: ttgocam
  friendly_name: Doorbell
  ip_address: 192.168.2.251

esphome:
  name: $devicename
  platform: ESP32
  #board: esp-wrover-kit
  board: esp32dev

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: $ip_address
    gateway: 192.168.2.1
    subnet: 255.255.255.0
# Enable logging
logger:

# Enable Home Assistant API
api:
ota:
binary_sensor:
  - platform: gpio
    pin: 
      number: GPIO19
      mode: INPUT
      inverted: False
    name: $friendly_name Motion
    device_class: motion
    filters:
      - delayed_off: 1s
  - platform: gpio
    pin:
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: True
    name: $friendly_name Button
    filters:
      - delayed_off: 50ms
  - platform: status
    name: $friendly_name Status
sensor:
  - platform: wifi_signal
    name: $friendly_name WiFi Signal
    update_interval: 10s
  - platform: uptime
    name: $friendly_name Uptime
esp32_camera:
  name: $friendly_name Camera
  external_clock:
    pin: GPIO4
    frequency: 20MHz
  i2c_pins:
    sda: GPIO18
    scl: GPIO23
  data_pins: [GPIO34, GPIO13, GPIO14, GPIO35, GPIO39, GPIO12, GPIO15, GPIO36]
  vsync_pin: GPIO5
  href_pin: GPIO27
  pixel_clock_pin: GPIO25
 # power_down_pin: GPIO26
  resolution: 640x480
  jpeg_quality: 10
  vertical_flip: true
  horizontal_mirror: false
i2c:
  sda: GPIO21
  scl: GPIO22
font:
  - file: "fonts/times-new-roman.ttf"
    id: tnr1
    size: 20
  - file: "fonts/times-new-roman.ttf"
    id: tnr2
    size: 24
time:
  - platform: homeassistant
    id: homeassistant_time
display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    address: 0x3C
    rotation: 180
    lambda: |-
      it.strftime(64, 0, id(tnr1), TextAlign::TOP_CENTER,"%m-%d-%Y", id(homeassistant_time).now());
      it.strftime(64, 64, id(tnr2), TextAlign::BASELINE_CENTER, "%I:%M:%S%p", id(homeassistant_time).now());
8 Likes

Are you able to use the microphone and play the sound on your PC speakers for example?

If so, would be a good component for a doorbell.

1 Like

So the website shows 3 pins for the microphone, SCK, WS, SDO. Based on this I think it’s a digital microphone that uses I2S. I don’t see a component for this in ESPHome so I don’t think it’s currently supported. There are examples of this for arduino/ESPs online so it can, of course, be added by using existing libraries and modifying these examples. This is “on my todo list” but to be honest it’s a pretty long list so we’ll see if I get to it before someone else does.

I have quite a few ESP based DYI “things” I’ve built now and I really feel like I need to take the packaging to the next level and make things look more professional. It seems I am going to have to tackle 3D printing before I worry about microphone support.

1 Like

I realized after posting this that the camera image is flipped horizontally. This config fixes that:

substitutions:
  devicename: ttgocam
  friendly_name: Doorbell
  ip_address: 192.168.2.251

esphome:
  name: $devicename
  platform: ESP32
  #board: esp-wrover-kit
  board: esp32dev

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: $ip_address
    gateway: 192.168.2.1
    subnet: 255.255.255.0
# Enable logging
logger:

# Enable Home Assistant API
api:
ota:
binary_sensor:
  - platform: gpio
    pin: 
      number: GPIO19
      mode: INPUT
      inverted: False
    name: $friendly_name Motion
    device_class: motion
    filters:
      - delayed_off: 1s
  - platform: gpio
    pin:
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: True
    name: $friendly_name Button
    filters:
      - delayed_off: 50ms
  - platform: status
    name: $friendly_name Status
sensor:
  - platform: wifi_signal
    name: $friendly_name WiFi Signal
    update_interval: 10s
  - platform: uptime
    name: $friendly_name Uptime
esp32_camera:
  name: $friendly_name Camera
  external_clock:
    pin: GPIO4
    frequency: 20MHz
  i2c_pins:
    sda: GPIO18
    scl: GPIO23
  data_pins: [GPIO34, GPIO13, GPIO14, GPIO35, GPIO39, GPIO12, GPIO15, GPIO36]
  vsync_pin: GPIO5
  href_pin: GPIO27
  pixel_clock_pin: GPIO25
 # power_down_pin: GPIO26
  resolution: 640x480
  jpeg_quality: 10
  vertical_flip: true
  horizontal_mirror: true
i2c:
  sda: GPIO21
  scl: GPIO22
font:
  - file: "fonts/times-new-roman.ttf"
    id: tnr1
    size: 20
  - file: "fonts/times-new-roman.ttf"
    id: tnr2
    size: 24
time:
  - platform: homeassistant
    id: homeassistant_time
display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    address: 0x3C
    rotation: 180
    lambda: |-
      it.strftime(64, 0, id(tnr1), TextAlign::TOP_CENTER,"%m-%d-%Y", id(homeassistant_time).now());
      it.strftime(64, 64, id(tnr2), TextAlign::BASELINE_CENTER, "%I:%M:%S%p", id(homeassistant_time).now());
3 Likes

Hi. Thank you for posting this.
It’s working great.
Where do I put the font file, to make the configuration compile?

Kind regards,
Esben

It’s been quite a while since I set this up . . . I just took a look and I see two copies of the file. One is in the same directory as the yaml file and the other is in a /fonts subdirectory. I’m not sure which one is correct.

BobG, do you have any ideas for getting the microphone to work? I was thinking of scouring github for some python packages that may work and contacting the manufacturer. Any other ideas?

I haven’t looked into this. My initial thoughts would be to find a c++ example of using a microphone on an esp32 board and incorporating that into an ESPHome custom sensor.

BobG, good idea. Let me see if I can find that - will get back to you asap.

Thanks for sharing. My TTGO-Cam (purchased in July 2020 from aliexpress) has a different pin allowcation. I’ve posted my conifg below, hope it saves somebody some time.

substitutions:
  friendly_name: Doorbell ESP

esphome:
  name: doorbellcam
  platform: ESP32
  board: esp-wrover-kit

wifi:
  ssid: "urssid"
  password: "urpaswrd"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Doorbellcam Fallback Hotspot"
    password: "urfbpaswrd"

captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

binary_sensor:
  - platform: gpio
    pin: 
      number: GPIO19
      mode: INPUT
      inverted: False
    name: $friendly_name Motion
    device_class: motion
    filters:
      - delayed_off: 1s
  - platform: gpio
    pin:
      number: GPIO15
      mode: INPUT_PULLUP
      inverted: True
    name: $friendly_name Button
    filters:
      - delayed_off: 50ms
  - platform: status
    name: $friendly_name Status
sensor:
  - platform: wifi_signal
    name: $friendly_name WiFi Signal
    update_interval: 10s
  - platform: uptime
    name: $friendly_name Uptime
esp32_camera:
  name: $friendly_name Camera
  external_clock:
    pin: GPIO4
    frequency: 20MHz
  i2c_pins:
    sda: GPIO18
    scl: GPIO23
  data_pins: [GPIO34, GPIO13, GPIO14, GPIO35, GPIO39, GPIO38, GPIO37, GPIO36]
  vsync_pin: GPIO5
  href_pin: GPIO27
  pixel_clock_pin: GPIO25
  resolution: 640x480
  jpeg_quality: 10
  vertical_flip: true
  horizontal_mirror: true
i2c:
  sda: GPIO21
  scl: GPIO22
font:
  - file: "fonts/times-new-roman.ttf"
    id: tnr1
    size: 20
  - file: "fonts/times-new-roman.ttf"
    id: tnr2
    size: 24
time:
  - platform: homeassistant
    id: homeassistant_time
display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    address: 0x3C
    rotation: 180
    lambda: |-
      it.strftime(64, 0, id(tnr1), TextAlign::TOP_CENTER,"%m-%d-%Y", id(homeassistant_time).now());
      it.strftime(64, 64, id(tnr2), TextAlign::BASELINE_CENTER, "%I:%M:%S%p", id(homeassistant_time).now());
4 Likes

Thanks for sharing and help!

3 Likes

Thanks for your help!
I had your same configuration but also needed to modify main.cpp code for it to work as specified on another thread.
Just in case anyone else happens to have the same issue.

Hey Dturgel, were you ever able to get the microphone working please?

Thanks

Hi I have problems getting the camera to work. Apparently I have a V1.6.2 version of the board. If I compile the sketch without the camera part everything works nicely. However If I add

esp32_camera:
  name: $friendly_name Camera
  external_clock:
    pin: GPIO4
    frequency: 20MHz
  i2c_pins:
    sda: GPIO18
    scl: GPIO23
  data_pins: [GPIO34, GPIO13, GPIO14, GPIO35, GPIO39, GPIO38, GPIO37, GPIO36]
  vsync_pin: GPIO5
  href_pin: GPIO27
  pixel_clock_pin: GPIO25
  jpeg_quality: 10
  vertical_flip: true
  horizontal_mirror: false

I cannot even connect to the board anymore via wifi. Although OTA works.

The problem seems to be the missing pullup for GPIO14.
Therefore I added these lines:

binary_sensor:
  - platform: gpio
    name: DummyIO14
    internal: true # sensor will not be exposed to Home Assistant
    pin:
      number: GPIO14
      mode: INPUT_PULLUP

Good luck :+1:
Instead of name: and internal: you can simply use id: DummyIO14 and the sensor will also not be exposed to Home Assistant.

Thanks! this is great - no more errors. I managed to get the board live without this addition once and have been struggling to get it to work for a week. Was prepared to bin it thinking I bricked it. @Mikrofarad - one question though, is it normal that the dummy sensor updates its status continuously? Any way to reduce the frequency?

@PaulAntonDeen fyi

Sorry, I don’t know any solution. What I did is changing the logging level:

logger:
  level: Error  # During development set it to Debug

You can use a filter:

  - platform: gpio
    id: dummy
    pin:
      number: GPIO14
      mode: INPUT_PULLUP
    filters:
      - delayed_on: 1000ms
1 Like

Hi All, I have the same or similar TTGO-Camera, and just got it working with the help from your above comments - thanks lots all <3

Mine is on version 1.7 though, and totally different GPIO pin config. Please see my config below for reference in case it helps anyone else <3

(I’ve hashed out secrets and changed name, ip addr, and printing text for security reasons) :wink:

esphome:
name: multifunctiondevice01

substitutions:
friendly_name: MF01

esp32:
board: esp32dev

Enable logging

logger:

Enable Home Assistant API

api:
encryption:
key: “whatevers”

ota:
password: “whatevers”

wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: 10.10.10.2
gateway: 10.10.10.1
subnet: 255.255.255.0

binary_sensor:

  • platform: gpio
    pin:
    number: GPIO33
    mode: INPUT
    inverted: False
    name: Motion
    device_class: motion
    filters:
    • delayed_off: 1s
  • platform: gpio
    pin:
    number: GPIO34
    #mode: INPUT_PULLUP
    mode: INPUT
    inverted: True
    name: $friendly_name Button
    filters:
    • delayed_off: 50ms
  • platform: gpio
    id: dummy
    pin:
    number: GPIO14
    mode: INPUT_PULLUP
    filters:
    • delayed_on: 1000ms
  • platform: status
    name: $friendly_name Status
    sensor:
  • platform: wifi_signal
    name: $friendly_name WiFi Signal
    update_interval: 10s
  • platform: uptime
    name: $friendly_name Uptime
    esp32_camera:
    name: $friendly_name Camera
    external_clock:
    pin: GPIO32
    frequency: 20MHz
    i2c_pins:
    sda: GPIO13
    scl: GPIO12
    data_pins: [GPIO5, GPIO14, GPIO4, GPIO15, GPIO18, GPIO23, GPIO36, GPIO39]
    vsync_pin: GPIO27
    href_pin: GPIO25
    pixel_clock_pin: GPIO19

power_down_pin: GPIO26

resolution: 640x480
jpeg_quality: 10
vertical_flip: true
horizontal_mirror: true
i2c:
sda: GPIO21
scl: GPIO22
font:

  • file: “fonts/times-new-roman.ttf”
    id: tnr1
    size: 18
  • file: “fonts/times-new-roman.ttf”
    id: tnr2
    size: 24
    time:
  • platform: homeassistant
    id: homeassistant_time
    display:
  • platform: ssd1306_i2c
    model: “SSD1306 128x64”
    address: 0x3C
    rotation: 180
    lambda: |-
    it.strftime(64, 0, id(tnr1), TextAlign::TOP_CENTER,“My House”, id(homeassistant_time).now());
    it.strftime(64, 32, id(tnr2), TextAlign::CENTER,“Go Away!”, id(homeassistant_time).now());
    it.strftime(64, 64, id(tnr1), TextAlign::BASELINE_CENTER, “%H:%M:%S”, id(homeassistant_time).now());

ok, apologies for the above, the formatting got ruined by this site X-)
you’ll just need to look at the original posts and apply my GPIO pin changes (there’s a lot of them, as basically they nearly all change!) :slight_smile: Hope this helps <3