Skip to content

atom-echo.yaml

Files / atom-echo / atom-echo.yaml

Files in atom-echo/

DownloadRawYAML · 200 lines · 4.9 KB

From M5Stack Atom Echo on your own ESPHome build: push to talk, a doorbell, no internet. MIT licence: LICENSE.

atom-echo/atom-echo.yaml
# M5Stack Atom Echo (C008-C): our own ESPHome firmware. Guide: https://blog.jacq.cc/guides/atom-echo-own-firmware/
# Press the button to talk; no wake words, so the microphone is off the rest of the time.
# No Bluetooth, no fallback hotspot, no updates from the internet; API and network updates encrypted with one key.
# Hardware settings (pins, I2S, LED) are copied from ESPHome's official config:
# https://github.com/esphome/wake-word-voice-assistants/blob/main/m5stack-atom-echo/m5stack-atom-echo.yaml
esphome:
# Same name as the factory firmware (plus MAC suffix), so HA keeps the device: m5stack-atom-echo-4e8ebc
name: m5stack-atom-echo
name_add_mac_suffix: true
friendly_name: Atom Echo
min_version: 2026.9.0
project:
name: jacq.atom-echo-push-to-talk
version: "2026.10.17.2"
on_boot:
priority: -100
then:
- script.execute: led_off
esp32:
board: m5stack-atom
cpu_frequency: 240MHz
framework:
type: esp-idf
logger:
api:
encryption:
key: !secret api_key
ota:
# Network updates are encrypted with the API key; nothing else can upload firmware
- platform: esphome
encryption:
# No `ap:` or `captive_portal:`: if Wi-Fi fails it keeps retrying instead of opening a hotspot.
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
i2s_audio:
- id: i2s_audio_bus
i2s_lrclk_pin: GPIO33
i2s_bclk_pin: GPIO19
microphone:
- platform: i2s_audio
id: echo_microphone
i2s_din_pin: GPIO23
adc_type: external
pdm: true
sample_rate: 16000
correct_dc_offset: true
speaker:
- platform: i2s_audio
id: echo_speaker
i2s_dout_pin: GPIO22
dac_type: external
bits_per_sample: 16bit
sample_rate: 16000
channel: stereo # the Echo sounds poor in mono (ESPHome's note)
buffer_duration: 60ms
media_player:
- platform: speaker
name: None
id: echo_media_player
announcement_pipeline:
speaker: echo_speaker
format: WAV
buffer_size: 6000
volume_min: 0.4
volume_initial: 0.9
files:
# Built into the firmware, so the doorbell plays even if the network to HA is down
- id: doorbell_chime
file: doorbell-16k.wav
voice_assistant:
id: va
microphone:
microphone: echo_microphone
channels: 0
gain_factor: 4
media_player: echo_media_player
noise_suppression_level: 2
auto_gain: 31dBFS
on_listening:
- light.turn_on:
id: led
red: 0%
green: 0%
blue: 100%
brightness: 100%
effect: Slow Pulse
on_stt_vad_end:
- light.turn_on:
id: led
red: 0%
green: 0%
blue: 100%
brightness: 100%
effect: Fast Pulse
on_tts_start:
- light.turn_on:
id: led
red: 0%
green: 0%
blue: 100%
brightness: 100%
effect: none
on_end:
- wait_until:
condition:
- media_player.is_announcing:
timeout: 0.5s
- wait_until:
- not:
media_player.is_announcing:
- script.execute: led_off
on_error:
- light.turn_on:
id: led
red: 100%
green: 0%
blue: 0%
brightness: 100%
effect: none
- delay: 2s
- script.execute: led_off
binary_sensor:
# Push to talk: a press starts listening; HA stops it when you stop speaking, then answers.
# A press while it listens cancels. Not hold-to-talk: voice_assistant.stop on release makes
# HA abort the run (no answer), and ESPHome has no "audio finished" action (2026.9).
- platform: gpio
pin:
number: GPIO39
inverted: true
name: Button
id: echo_button
disabled_by_default: true
entity_category: diagnostic
on_press:
- if:
condition:
voice_assistant.is_running:
then:
- voice_assistant.stop:
else:
- media_player.stop:
announcement: true
- voice_assistant.start:
button:
# HA presses this to ring the doorbell (plays the chime stored in the firmware)
- platform: template
name: Doorbell chime
id: doorbell_chime_button
icon: mdi:bell-ring
on_press:
- media_player.speaker.play_on_device_media_file:
media_file: doorbell_chime
announcement: true
- platform: restart
name: Restart
entity_category: config
light:
- platform: esp32_rmt_led_strip
id: led
name: None
disabled_by_default: true
entity_category: config
pin: GPIO27
default_transition_length: 0s
chipset: SK6812
num_leds: 1
channel_colors: GRB
effects:
- pulse:
name: Slow Pulse
transition_length: 250ms
update_interval: 250ms
min_brightness: 50%
max_brightness: 100%
- pulse:
name: Fast Pulse
transition_length: 100ms
update_interval: 100ms
min_brightness: 50%
max_brightness: 100%
script:
- id: led_off
then:
- light.turn_off: led

Text, photos and drawings: CC BY 4.0. Code: MIT. Share and adapt them, crediting HomeLab Guides (blog.jacq.cc). Licence and privacy