Skip to content

Instantly share code, notes, and snippets.

@EverythingSmartHome
Last active February 23, 2024 00:18
  • Star 31 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save EverythingSmartHome/055fbdde31a607ef9d695d5cac780e94 to your computer and use it in GitHub Desktop.
ESP32 & ESPHome Voice Assistant
esphome:
name: esp32-mic-speaker
friendly_name: esp32-mic-speaker
on_boot:
- priority: -100
then:
- wait_until: api.connected
- delay: 1s
- if:
condition:
switch.is_on: use_wake_word
then:
- voice_assistant.start_continuous:
esp32:
board: esp32dev
framework:
type: esp-idf
version: recommended
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esp32-Mic-Speaker"
password: "9vYvAFzzPjuc"
i2s_audio:
i2s_lrclk_pin: GPIO27
i2s_bclk_pin: GPIO26
microphone:
- platform: i2s_audio
id: mic
adc_type: external
i2s_din_pin: GPIO13
pdm: false
speaker:
- platform: i2s_audio
id: big_speaker
dac_type: external
i2s_dout_pin: GPIO25
mode: mono
voice_assistant:
microphone: mic
use_wake_word: false
noise_suppression_level: 2
auto_gain: 31dBFS
volume_multiplier: 2.0
speaker: big_speaker
id: assist
switch:
- platform: template
name: Use wake word
id: use_wake_word
optimistic: true
restore_mode: RESTORE_DEFAULT_ON
entity_category: config
on_turn_on:
- lambda: id(assist).set_use_wake_word(true);
- if:
condition:
not:
- voice_assistant.is_running
then:
- voice_assistant.start_continuous
on_turn_off:
- voice_assistant.stop
- lambda: id(assist).set_use_wake_word(false);
@cebik16-2
Copy link

cebik16-2 commented Dec 12, 2023

hi all
@andrejsoucek, have you succeeded?

i cant start the mic INMP441 on a ESP-WROOM-32.

LOGS for LOGS for esp32.board.framework.type: arduino

[D][voice_assistant:422]: State changed from IDLE to START_PIPELINE
[D][voice_assistant:428]: Desired state set to START_MICROPHONE
[D][voice_assistant:124]: microphone not running
[D][voice_assistant:206]: Requesting start...
[D][voice_assistant:422]: State changed from START_PIPELINE to STARTING_PIPELINE
[D][voice_assistant:124]: microphone not running
[D][voice_assistant:124]: microphone not running
[D][voice_assistant:124]: microphone not running
[D][voice_assistant:443]: Client started, streaming microphone
[D][voice_assistant:422]: State changed from STARTING_PIPELINE to START_MICROPHONE
[D][voice_assistant:428]: Desired state set to STREAMING_MICROPHONE
[D][voice_assistant:159]: Starting Microphone
[D][voice_assistant:422]: State changed from START_MICROPHONE to STARTING_MICROPHONE
[D][voice_assistant:529]: Event Type: 0
[E][voice_assistant:656]: Error: no_wake_word - No wake word detected
[D][voice_assistant:522]: Signaling stop...
[D][voice_assistant:422]: State changed from STARTING_MICROPHONE to STOP_MICROPHONE
[D][voice_assistant:428]: Desired state set to IDLE
[D][voice_assistant:422]: State changed from STOP_MICROPHONE to STOPPING_MICROPHONE
[D][light:036]: 'Light' Setting:
[D][light:047]:   State: ON
[D][light:085]:   Transition length: 0.5s
[D][switch:016]: 'Use wake word' Turning OFF.
[D][switch:055]: 'Use wake word': Sending state OFF
[D][voice_assistant:529]: Event Type: 2
[D][voice_assistant:619]: Assist Pipeline ended
[D][voice_assistant:422]: State changed from STOPPING_MICROPHONE to IDLE
[D][light:036]: 'Light' Setting:
[D][light:047]:   State: OFF
[D][light:085]:   Transition length: 0.5s
[D][voice_assistant:529]: Event Type: 1
[D][voice_assistant:532]: Assist Pipeline running
[D][voice_assistant:529]: Event Type: 9
[D][voice_assistant:529]: Event Type: 0
[E][voice_assistant:656]: Error: wake-stream-failed - Unexpected error during wake-word-detection

LOGS for esp32.board.framework.type: esp-idf

[W][component:214]: Component api took a long time for an operation (0.05 s).
[W][component:215]: Components should block for at most 20-30ms.
[D][api.connection:1089]: Home Assistant 2023.12.1 (192.168.0.192): Connected successfully
[D][voice_assistant:422]: State changed from IDLE to START_PIPELINE
[D][voice_assistant:428]: Desired state set to START_MICROPHONE
[D][voice_assistant:124]: microphone not running
[D][voice_assistant:206]: Requesting start...
[D][voice_assistant:422]: State changed from START_PIPELINE to STARTING_PIPELINE
[D][voice_assistant:124]: microphone not running
[D][voice_assistant:124]: microphone not running
[D][voice_assistant:124]: microphone not running
[D][voice_assistant:443]: Client started, streaming microphone
[D][voice_assistant:422]: State changed from STARTING_PIPELINE to START_MICROPHONE
[D][voice_assistant:428]: Desired state set to STREAMING_MICROPHONE
[D][voice_assistant:159]: Starting Microphone
[D][voice_assistant:422]: State changed from START_MICROPHONE to STARTING_MICROPHONE
[D][esp-idf:000]: I (14472) I2S: DMA Malloc info, datalen=blocksize=1024, dma_buf_count=4

[D][voice_assistant:529]: Event Type: 1
[D][voice_assistant:532]: Assist Pipeline running
[D][voice_assistant:422]: State changed from STARTING_MICROPHONE to STREAMING_MICROPHONE
[D][voice_assistant:529]: Event Type: 9
[D][binary_sensor:036]: 'API Connection': Sending state ON
ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:6608
load:0x40078000,len:15060
ho 0 tail 12 room 4
load:0x40080400,len:3816
entry 0x40080698
I (29) boot: ESP-IDF 4.4.5 2nd stage bootloader
I (29) boot: compile time 17:50:26
I (29) boot: chip revision: v3.0
I (32) boot.esp32: SPI Speed      : 40MHz
I (37) boot.esp32: SPI Mode       : DIO
I (41) boot.esp32: SPI Flash Size : 4MB
I (46) boot: Enabling RNG early entropy source...
I (51) boot: Partition Table:
I (55) boot: ## Label            Usage          Type ST Offset   Length
I (62) boot:  0 otadata          OTA data         01 00 00009000 00002000
I (70) boot:  1 phy_init         RF data          01 01 0000b000 00001000
I (77) boot:  2 app0             OTA app          00 10 00010000 001c0000
I (85) boot:  3 app1             OTA app          00 11 001d0000 001c0000
I (92) boot:  4 nvs              WiFi data        01 02 00390000 0006d000
I (100) boot: End of partition table
I (104) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=24f84h (151428) map
I (167) esp_image: segment 1: paddr=00034fac vaddr=3ffb0000 size=02f80h ( 12160) load
I (172) esp_image: segment 2: paddr=00037f34 vaddr=40080000 size=080e4h ( 32996) load
I (187) esp_image: segment 3: paddr=00040020 vaddr=400d0020 size=9202ch (598060) map
I (403) esp_image: segment 4: paddr=000d2054 vaddr=400880e4 size=0c394h ( 50068) load
I (434) boot: Loaded app from partition at offset 0x10000
I (434) boot: Disabling RNG early entropy source...
I (445) cpu_start: Pro cpu up.
I (446) cpu_start: Starting app cpu, entry point is 0x40081ce4
I (0) cpu_start: App cpu up.
I (460) cpu_start: Pro cpu start user code
I (460) cpu_start: cpu freq: 160000000
I (460) cpu_start: Application information:
I (464) cpu_start: Project name:     esp32-mic
I (469) cpu_start: App version:      2023.11.6
I (475) cpu_start: Compile time:     Dec 12 2023 17:49:47
I (481) cpu_start: ELF file SHA256:  1a7bb39ea0c1dff9...
I (487) cpu_start: ESP-IDF:          4.4.5
I (491) cpu_start: Min chip rev:     v0.0
I (496) cpu_start: Max chip rev:     v3.99 
I (501) cpu_start: Chip rev:         v3.0
I (506) heap_init: Initializing. RAM available for dynamic allocation:
I (513) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (519) heap_init: At 3FFB6FC8 len 00029038 (164 KiB): DRAM
I (525) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (531) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (538) heap_init: At 40094478 len 0000BB88 (46 KiB): IRAM
I (545) spi_flash: detected chip: generic
I (549) spi_flash: flash io: dio
I (554) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.

@andrejsoucek
Copy link

@cebik16-2 no, I gave up, it is s3 n16r8 wroom 32

@cebik16-2
Copy link

what do you use?

@andrejsoucek
Copy link

what do you use?

ESP32-WROOM with CP2102, USB-C

@strusic
Copy link

strusic commented Dec 20, 2023

Responces that I got from speaker are very crakly sounding. How to get rid of that?

@soogaard20
Copy link

hi all

i hope somebody can help me, i get those errors, ps im pretty new to esp :)

me set is

board: ESP32-WROOM-32
mic: INMP441
amp: MAX98357A
Speaker - zero (waiting for is to come)

INFO Reading configuration /config/esphome/esphome-web-3259a8.yaml...
Failed config

i2s_audio: [source /config/esphome/esphome-web-3259a8.yaml:28]

Component not found: i2s_audio.
i2s_lrclk_pin: GPIO27
i2s_bclk_pin: GPIO26
microphone: [source /config/esphome/esphome-web-3259a8.yaml:32]

Component not found: microphone.

  • platform: i2s_audio
    id: mic
    adc_type: external
    i2s_din_pin: GPIO13
    pdm: False
    speaker: [source /config/esphome/esphome-web-3259a8.yaml:39]

Component not found: speaker.

  • platform: i2s_audio
    id: big_speaker
    dac_type: external
    i2s_dout_pin: GPIO25
    mode: mono
    voice_assistant: [source /config/esphome/esphome-web-3259a8.yaml:46]

Component not found: voice_assistant.
microphone: mic
use_wake_word: False
noise_suppression_level: 2
auto_gain: 31dBFS
volume_multiplier: 2.0
speaker: big_speaker
id: assist
switch.template: [source /config/esphome/esphome-web-3259a8.yaml:55]
platform: template
name: Use wake word
id: use_wake_word
optimistic: True

[restore_mode] is an invalid option for [switch.template]. Did you mean [restore_state]?
restore_mode: RESTORE_DEFAULT_ON [source /config/esphome/esphome-web-3259a8.yaml:59]
entity_category: config

Unable to find action with the name 'voice_assistant.start_continuous'.
on_turn_on: [source /config/esphome/esphome-web-3259a8.yaml:62]
- lambda: id(assist).set_use_wake_word(true);
- [source /config/esphome/esphome-web-3259a8.yaml:63]
if: [source /config/esphome/esphome-web-3259a8.yaml:64]
condition: [source /config/esphome/esphome-web-3259a8.yaml:65]
not: [source /config/esphome/esphome-web-3259a8.yaml:66]

        Unable to find condition with the name 'voice_assistant.is_running'.
        - [source /config/esphome/esphome-web-3259a8.yaml:66]
          voice_assistant.is_running
    then: 
      - voice_assistant.start_continuous

on_turn_off: [source /config/esphome/esphome-web-3259a8.yaml:70]

Unable to find action with the name 'voice_assistant.stop'.
- [source /config/esphome/esphome-web-3259a8.yaml:70]
  voice_assistant.stop
- lambda: id(assist).set_use_wake_word(false);

@soogaard20
Copy link

hi all

i hope somebody can help me, i get those errors, ps im pretty new to esp :)

me set is

board: ESP32-WROOM-32

mic: INMP441
amp: MAX98357A
Speaker - zero (waiting for is to come)
INFO Reading configuration /config/esphome/esphome-web-3259a8.yaml... Failed config

i2s_audio: [source /config/esphome/esphome-web-3259a8.yaml:28]

Component not found: i2s_audio. i2s_lrclk_pin: GPIO27 i2s_bclk_pin: GPIO26 microphone: [source /config/esphome/esphome-web-3259a8.yaml:32]

Component not found: microphone.

  • platform: i2s_audio
    id: mic
    adc_type: external
    i2s_din_pin: GPIO13
    pdm: False
    speaker: [source /config/esphome/esphome-web-3259a8.yaml:39]

Component not found: speaker.

  • platform: i2s_audio
    id: big_speaker
    dac_type: external
    i2s_dout_pin: GPIO25
    mode: mono
    voice_assistant: [source /config/esphome/esphome-web-3259a8.yaml:46]

Component not found: voice_assistant. microphone: mic use_wake_word: False noise_suppression_level: 2 auto_gain: 31dBFS volume_multiplier: 2.0 speaker: big_speaker id: assist switch.template: [source /config/esphome/esphome-web-3259a8.yaml:55] platform: template name: Use wake word id: use_wake_word optimistic: True

[restore_mode] is an invalid option for [switch.template]. Did you mean [restore_state]? restore_mode: RESTORE_DEFAULT_ON [source /config/esphome/esphome-web-3259a8.yaml:59] entity_category: config

Unable to find action with the name 'voice_assistant.start_continuous'. on_turn_on: [source /config/esphome/esphome-web-3259a8.yaml:62] - lambda: id(assist).set_use_wake_word(true); - [source /config/esphome/esphome-web-3259a8.yaml:63] if: [source /config/esphome/esphome-web-3259a8.yaml:64] condition: [source /config/esphome/esphome-web-3259a8.yaml:65] not: [source /config/esphome/esphome-web-3259a8.yaml:66]

        Unable to find condition with the name 'voice_assistant.is_running'.
        - [source /config/esphome/esphome-web-3259a8.yaml:66]
          voice_assistant.is_running
    then: 
      - voice_assistant.start_continuous

on_turn_off: [source /config/esphome/esphome-web-3259a8.yaml:70]

Unable to find action with the name 'voice_assistant.stop'.
- [source /config/esphome/esphome-web-3259a8.yaml:70]
  voice_assistant.stop
- lambda: id(assist).set_use_wake_word(false);

to help others

it was because i use a old ESP program in addon store on Home assistant 🤦‍♂️

@cebik16-2
Copy link

do someone have some spare time to help me with this to make it work please, im gonna go crazy XD

@n00btotal
Copy link

n00btotal commented Dec 28, 2023

My setup:

Hardware:

Microphone: INMP441
Amp: MAX98357
Speaker: 3 watt mini speaker 8 ohm

I also have been banging my head against this wall for a while. Like @Somerley , @andiewill and @strusic I get lots of crackling noise. Both from speaker, but also from the recordings from the wake words and commands enabled by adding the following to my home assistant configuration.yaml:

assist_pipeline:
  debug_recording_dir: /share/assist_pipeline 

Crackling noise aside, it DOES work, but not as well I expect! The crackling noise heavily disrupts the speech recognition. I've enabled GPU powered speech-to-text on a Proxmox container that runs a docker, and it is blazing fast and really good, taking into account all the disruptions in the recordings. Without the disruptions/crackling noise, this setup would be so awesome! It really eats my brain all these crackling noises!

I've search the web, many suggestnings of fixing solderings, cables etc, splitting i2s to in/out. I've tried everything. Nothing seems to work. Except this one suggestion, that is outside the realm of possibilities of ESPhome.

In that thread Vegethalia writes:

Ok I'll answer myself, just in case this serves someone else: The problem was that I had configured the I2S in 16 bit mode, and then I was only capturing the MSB of the bit stream. If I configured 24 bits, then the stream was garbled. The solution is to configure I2S in 32 bits mode and when reading, each sample takes 4 bytes and one must be discarted. Like this:

REAL_BYTES_X_SAMPLE=4;

i2s_read(I2S_NUM_0, (void*)dataOrig, buffSizeOrig, &bytesRead, portMAX_DELAY);
uint16_t samplesRead = bytesRead / REAL_BYTES_X_SAMPLE;
for (int i = 0; i < samplesRead; i++) {
    byteIndex = i * REAL_BYTES_X_SAMPLE;
    int32_t value = ((int32_t*)(dataOrig + byteIndex))[0]>>8;
}

Even though you can specify "bits_per_sample:" for your microphone, you can only set it to 16bit or 32bit. You are not able to specify that level of detail of the recordnings as suggested in the post.

After changing output to a media_player (and changing platform to arduino) the crackling noise disappeared from the response in the speakers, the recordings saved by home assistant is still crackling.. The crackling MUST something related to the I2S microphone on my system.

I've tried different GIPO:s for the I2S, trying to make guesses from the pinout for my board. But I've not found any pins that make any difference.

Code:

esphome:
  name: esp32-mic-speaker
  friendly_name: esp32-mic-speaker
  on_boot:
     - priority: -100
       then:
         - wait_until: api.connected
         - delay: 1s
         - if:
             condition:
               switch.is_on: use_wake_word
             then:
               - voice_assistant.start_continuous:

esp32:
  board: az-delivery-devkit-v4
  framework:
    type: arduino
    version: recommended

# Enable logging
logger:
  level: VERBOSE

# Enable Home Assistant API
api:
  encryption:
    key: "llorem ipsum"

ota:
  password: "lorem ipsum"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp32-Mic-Speaker"
    password: "loremipsum"


i2s_audio:
  - id: i2s_out
    i2s_lrclk_pin: GPIO21
    i2s_bclk_pin: GPIO22
  - id: i2s_in
    i2s_lrclk_pin: GPIO26
    i2s_bclk_pin: GPIO25

microphone:
  - platform: i2s_audio
    i2s_audio_id: i2s_in
    id: mic
    adc_type: external
    i2s_din_pin: GPIO13
    pdm: false
    bits_per_sample: 32bit

media_player:
  - platform: i2s_audio
    name: "esp_speaker"
    id: media_player_speaker
    i2s_audio_id: i2s_out
    dac_type: external
    i2s_dout_pin: GPIO33   
    mode: mono
    
voice_assistant:
  microphone: mic
  use_wake_word: false
  noise_suppression_level: 4
  auto_gain: 31dBFS
  volume_multiplier: 2
  media_player: media_player_speaker
  id: assist

switch:
  - platform: template
    name: Use wake word
    id: use_wake_word
    optimistic: true
    restore_mode: RESTORE_DEFAULT_ON
    entity_category: config
    on_turn_on:
      - lambda: id(assist).set_use_wake_word(true);
      - if:
          condition:
            not:
              - voice_assistant.is_running
          then:
            - voice_assistant.start_continuous
    on_turn_off:
      - voice_assistant.stop
      - lambda: id(assist).set_use_wake_word(false);

I've purchased other I2S mics, but they are four weeks away. Any suggestions on how to remove the crackling from the INMP441 recordnings ?

@alior101
Copy link

alior101 commented Dec 29, 2023 via email

@alior101
Copy link

alior101 commented Dec 29, 2023 via email

@alior101
Copy link

alior101 commented Dec 30, 2023 via email

@n00btotal
Copy link

I've tried changing bits_per_sample: 32bit back and forth, but crackling is still there. I'll attach a sound (with no recording, just the constant crackling).

crackling_sound_azdelivery_esp32.mp4

@andiewill
Copy link

I've tried changing bits_per_sample: 32bit back and forth, but crackling is still there. I'll attach a sound (with no recording, just the constant crackling).

crackling_sound_azdelivery_esp32.mp4

I had to redo my code again and made a slight change due to using a strapping pin in the first esp32, which messed around with my how the VA worked, after loosing my original config due to server issues, through trial and error again i got it working well with no crackling, the only thing different to your config and mine is that you are using the media player and i am using speaker and of course lights etc, my config below FYI, also using the latest HA.

`
ap:
ssid: "Esp32-Mic-Speaker"
password: "9vYvAFzzPjuc"

captive_portal:

i2s_audio:

  • id: i2s_out
    i2s_lrclk_pin: GPIO27
    i2s_bclk_pin: GPIO26
  • id: i2s_in
    i2s_lrclk_pin: GPIO14
    i2s_bclk_pin: GPIO21

microphone:

  • platform: i2s_audio
    i2s_audio_id: i2s_in
    id: mic
    i2s_din_pin: GPIO13
    adc_type: external
    pdm: false
    bits_per_sample: 32bit

speaker:

  • platform: i2s_audio
    i2s_audio_id: i2s_out
    id: big_speaker
    i2s_dout_pin: GPIO25
    dac_type: external
    mode: mono

voice_assistant:
microphone: mic
id: assist
speaker: big_speaker
use_wake_word: false
noise_suppression_level: 2
auto_gain: 31dBFS
on_listening:
- light.turn_on:
id: led
blue: 100%
red: 0%
green: 0%
brightness: 100%
effect: pulse
on_tts_start:
- light.turn_on:
id: led
blue: 0%
red: 0%
green: 100%
effect: pulse
on_tts_end:
- light.turn_on:
id: led
blue: 60%
red: 20%
green: 20%
effect: pulse
on_end:
- delay: 100ms
- wait_until:
not:
speaker.is_playing:
- script.execute: reset_led
on_error:
- light.turn_on:
id: led
blue: 0%
red: 100%
green: 0%
brightness: 100%
effect: pulse
- delay: 1s
- script.execute: reset_led
- lambda: |-
if (code == "wake-provider-missing" || code == "wake-engine-missing") {
id(use_wake_word).turn_off();
}
light:

  • platform: esp32_rmt_led_strip
    rgb_order: RGB
    pin: GPIO33
    num_leds: 2
    rmt_channel: 0
    chipset: ws2812
    name: "led"
    id: led
    effects:
    • pulse:
    • pulse:
      name: "Fast Pulse"
      transition_length: 0.5s
      update_interval: 0.5s
      min_brightness: 0%
      max_brightness: 100%
    • pulse:
      name: "Slow Pulse"
      transition_length: 1s # defaults to 1s
      update_interval: 2s
    • random:
    • random:
      name: Random Effect With Custom Values
      transition_length: 5s
      update_interval: 7s
    • strobe:
    • strobe:
      name: Strobe Effect With Custom Values
      colors:
      - state: true
      brightness: 100%
      red: 100%
      green: 90%
      blue: 20%
      duration: 500ms
      - state: false
      duration: 250ms
      - state: true
      brightness: 100%
      red: 0%
      green: 100%
      blue: 0%
      duration: 500ms
    • flicker:
    • flicker:
      name: Flicker Effect With Custom Values
      alpha: 95%
      intensity: 1.5%
    • addressable_rainbow:
    • addressable_rainbow:
      name: Rainbow Effect With Custom Values
      speed: 10
      width: 50
    • addressable_color_wipe:
    • addressable_color_wipe:
      name: Color Wipe Effect With Custom Values
      colors:
      - red: 100%
      green: 100%
      blue: 100%
      num_leds: 1
      - red: 0%
      green: 0%
      blue: 0%
      num_leds: 1
      add_led_interval: 100ms
      reverse: false
    • addressable_random_twinkle:
    • addressable_random_twinkle:
      name: Random Twinkle Effect With Custom Values
      twinkle_probability: 5%
      progress_interval: 32ms
    • addressable_fireworks:
    • addressable_fireworks:
      name: Fireworks Effect With Custom Values
      update_interval: 32ms
      spark_probability: 10%
      use_random_color: false
      fade_out_rate: 120

script:

  • id: reset_led
    then:
    • if:
      condition:
      switch.is_on: use_wake_word
      then:
      - light.turn_on:
      id: led
      blue: 100%
      red: 100%
      green: 0%
      brightness: 100%
      effect: none
      else:
      - light.turn_off: led

switch:

  • platform: template
    name: Use wake word
    id: use_wake_word
    optimistic: true
    restore_mode: RESTORE_DEFAULT_ON
    entity_category: config
    on_turn_on:
    • lambda: id(assist).set_use_wake_word(true);
    • if:
      condition:
      not:
      - voice_assistant.is_running
      then:
      - voice_assistant.start_continuous
    • script.execute: reset_led
      on_turn_off:
    • voice_assistant.stop
    • lambda: id(assist).set_use_wake_word(false);
    • script.execute: reset_led
  • platform: template
    name: Use Listen Light
    id: use_listen_light
    optimistic: true
    restore_mode: RESTORE_DEFAULT_ON
    entity_category: config
    on_turn_on:
    • script.execute: reset_led
      on_turn_off:
    • script.execute: reset_led

external_components:

  • source: github://pr#5230
    components:
    • esp_adf
      refresh: 0s
      `

@ibrummel
Copy link

ibrummel commented Jan 6, 2024

I know this is likely to get buried, but just for everyone that is still struggling with this process here is my working config file for an INMP441 microphone and a PCM5102 DAC as the sound output. This device functions with wakeword detection and as a media player from HA. I spent a week bashing my head against this before I found out that my issue was actually network related. The firewall on my HA server (running HA container) was not allowing the UDP connection from the ESP32 devices. I have not been able to narrow down which port is used for the mic streaming so right now I just all all UDP from the IP address of my ESP32 allowed in ufw.

Wiring as Follows:

ESP32 Pin Label INMP441 Pin Label PCM5102 Pin Label
5V VIN
3.3V VDD, L/R
GND GND GND
GPIO33 SCK BCK
GPIO25 WS LCK
GPIO22 DIN
GPIO32 SD

I did need to solder connections to the PCM5102 in order to get reliable audio. With jumper wires on a breadboard, the audio would cut out regularly and the whole set up needed to be held "just right" to have any audio at all.

Working config on a generic ESP32 dev kit:

esphome:
  # Working configuration for internet radio but no working voice
  name: hava-media
  friendly_name: HAVA-media
  on_boot:
    - priority: -100
      then:
        - wait_until: api.connected
        - delay: 1s
        - if:
            condition:
              switch.is_on: use_wake_word
            then:
              - voice_assistant.start_continuous:

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:
  baud_rate: 115200
  level: DEBUG

# Enable Home Assistant API
api:
  encryption:
    key: ""

ota:
  password: ""

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

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

captive_portal:

i2s_audio:
  - id: i2s_in
    i2s_lrclk_pin: GPIO25 #INMP441 WS | PCM5102 LCK 
    i2s_bclk_pin: GPIO33 # INMP441 SCK | PCM5102 BCK

media_player:
  - platform: i2s_audio
    name: "esp_speaker"
    id: media_player_speaker
    i2s_audio_id: i2s_in
    dac_type: external
    i2s_dout_pin: GPIO22   #  PCM5102 DIN
    mode: stereo

microphone:
  - platform: i2s_audio
    adc_type: external
    pdm: false
    id: mic_i2s
    channel: left # L/R pin pulled high
    bits_per_sample: 32bit
    i2s_audio_id: i2s_in
    i2s_din_pin: GPIO32  #INMP441 SD

output:
    # onboard
  - platform: ledc
    pin: GPIO2
    id: onboard_led
    inverted: false

light:
  - platform: monochromatic
    output: onboard_led
    id: response_light
    name: "Onboard LED"
    default_transition_length: 0.1s

voice_assistant:
  id: va
  microphone: mic_i2s
  media_player: media_player_speaker
  noise_suppression_level: 0
  auto_gain: 10dBFS
  volume_multiplier: 2.0
  on_listening:
    - light.turn_on: response_light
  on_end:
    - light.turn_off: response_light

switch:
  - platform: template
    name: Use wake word
    id: use_wake_word
    optimistic: true
    restore_mode: RESTORE_DEFAULT_ON
    entity_category: config
    on_turn_on:
      - lambda: id(va).set_use_wake_word(true);
      - if:
          condition:
            not:
              - voice_assistant.is_running
          then:
            - voice_assistant.start_continuous

    on_turn_off:
      - voice_assistant.stop
      - lambda: id(va).set_use_wake_word(false);

@Krull56
Copy link

Krull56 commented Jan 7, 2024

@ibrummel , where are speaker and/or media_player in the Yaml config ?

@ibrummel
Copy link

ibrummel commented Jan 9, 2024

@Krull56 My apologies. I must have copy pasted out of the wrong file. I have a lot of things open. I have updated my original post with the correct code as well as adding some notes on wiring.

@BlackCube4
Copy link

I am trying to get this to work with a ESP32 C3 Super Mini. Has anyone tried that before?

@Xornop
Copy link

Xornop commented Feb 1, 2024

Sometimes I boot the esp and then suddenly it is giving a whole bunch of log lines within the same second, the cycle over and over. Code without light works fine.
[14:28:18][E][voice_assistant:646]: Error: no_wake_word - No wake word detected
[14:28:18][D][voice_assistant:512]: Signaling stop...
[14:28:18][D][voice_assistant:412]: State changed from STARTING_PIPELINE to STOP_MICROPHONE
[14:28:18][D][voice_assistant:418]: Desired state set to IDLE
[14:28:18][D][voice_assistant:412]: State changed from STOP_MICROPHONE to IDLE
[14:28:18][D][voice_assistant:519]: Event Type: 2
[14:28:18][D][voice_assistant:609]: Assist Pipeline ended
[14:28:18][D][voice_assistant:412]: State changed from IDLE to START_PIPELINE
[14:28:18][D][voice_assistant:418]: Desired state set to START_MICROPHONE
[14:28:18][D][voice_assistant:512]: Signaling stop...
[14:28:18][D][voice_assistant:118]: microphone not running
[14:28:18][D][voice_assistant:200]: Requesting start...
[14:28:18][D][voice_assistant:412]: State changed from START_PIPELINE to STARTING_PIPELINE
[14:28:18][D][voice_assistant:519]: Event Type: 1
[14:28:18][D][voice_assistant:522]: Assist Pipeline running
[14:28:18][D][voice_assistant:118]: microphone not running
[14:28:18][D][voice_assistant:519]: Event Type: 9
[14:28:18][D][voice_assistant:118]: microphone not running
[14:28:18][D][voice_assistant:519]: Event Type: 0
Just over and over within the same second. Sometimes restarting it works, sometimes it starts working on its own. How to fix?
I used the original code.
Sometimes it wont even start the code after unplug/replug. Then the speaker starts crackling loudly, sometimes not. Very buggy.

@Xornop
Copy link

Xornop commented Feb 1, 2024

@BlackCube4 I read somewhere that won't work. Did you make it work anyway?

@joshfedo
Copy link

joshfedo commented Feb 2, 2024

@Xornop That logging loop is what you would expect to see. When a wake word is detected the logs will start showing the intent flow.

Unfortunately there are issues with ESP home and i2s/voice assist. After getting everything working on the hardware side Im able to trigger one or two commands before the assist pipe line just stops running.

[10:16:42][D][voice_assistant:519]: Event Type: 7 [10:16:42][D][voice_assistant:575]: Response: "The office lights have been turned on." [10:16:42][VV][scheduler:032]: set_timeout(name='', timeout=0) [10:16:42][VV][scheduler:226]: Running timeout '' with interval=0 last_execution=108935 (now=108948) [10:16:42][VV][api.service:920]: on_voice_assistant_event_response: VoiceAssistantEventResponse { event_type: VOICE_ASSISTANT_TTS_END data: VoiceAssistantEventData { name: 'url' value: 'http://192.168.1.165:8123/api/tts_proxy/2a7ce8cec50032f5696e5e16702bb5339ec37ebe_en-us_03ed9f9845_cloud.wav' } } [10:16:42][D][voice_assistant:519]: Event Type: 8 [10:16:42][D][voice_assistant:595]: Response URL: "http://192.168.1.165:8123/api/tts_proxy/2a7ce8cec50032f5696e5e16702bb5339ec37ebe_en-us_03ed9f9845_cloud.wav" [10:16:42][VV][scheduler:032]: set_timeout(name='', timeout=0) [10:16:42][D][voice_assistant:412]: State changed from AWAITING_RESPONSE to STREAMING_RESPONSE [10:16:42][D][voice_assistant:418]: Desired state set to STREAMING_RESPONSE [10:16:42][W][component:214]: Component api took a long time for an operation (0.07 s). [10:16:42][W][component:215]: Components should block for at most 20-30ms. [10:16:42][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:42][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:42][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:42][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:42][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][scheduler:032]: set_timeout(name='speaker-timeout', timeout=5000) [10:16:43][VV][api.service:920]: on_voice_assistant_event_response: VoiceAssistantEventResponse { event_type: VOICE_ASSISTANT_TTS_STREAM_END } [10:16:43][D][voice_assistant:519]: Event Type: 99 [10:16:43][D][voice_assistant:665]: TTS stream end [10:16:43][D][voice_assistant:283]: End of audio stream received [10:16:43][D][voice_assistant:412]: State changed from STREAMING_RESPONSE to RESPONSE_FINISHED [10:16:43][D][voice_assistant:418]: Desired state set to RESPONSE_FINISHED [10:17:04][VV][api.service:558]: on_ping_request: PingRequest {} [10:17:04][VV][api.service:043]: send_ping_response: PingResponse {} [10:17:08][VV][api.connection:132]: Sending keepalive PING... [10:17:08][VV][api.service:037]: send_ping_request: PingRequest {} [10:17:08][VV][api.service:567]: on_ping_response: PingResponse {} [10:17:33][VV][scheduler:226]: Running interval '' with interval=60000 last_execution=101421 (now=161421) [10:17:44][VV][api.service:558]: on_ping_request: PingRequest {} [10:17:44][VV][api.service:043]: send_ping_response: PingResponse {} [10:18:08][VV][api.service:558]: on_ping_request: PingRequest {} [10:18:08][VV][api.service:043]: send_ping_response: PingResponse {} [10:18:24][VV][api.service:558]: on_ping_request: PingRequest {} [10:18:24][VV][api.service:043]: send_ping_response: PingResponse {} [10:18:33][VV][scheduler:226]: Running interval '' with interval=60000 last_execution=161421 (now=221421)

The device will just keeping pinging until it is rebooted. Once rebooted I can run 1-2 commands and then i run into the same issue. Looking around on the forms im seeing other have the same issue.

@BlackCube4
Copy link

@BlackCube4 I read somewhere that won't work. Did you make it work anyway?

I got it to work fine~ish

@Xornop
Copy link

Xornop commented Feb 4, 2024

@Xornop That logging loop is what you would expect to see. When a wake word is detected the logs will start showing the intent flow.

Not within the same second, it completely freezes up the esp.

@reidprichard
Copy link

reidprichard commented Feb 14, 2024

...I found out that my issue was actually network related. The firewall on my HA server (running HA container) was not allowing the UDP connection from the ESP32 devices. I have not been able to narrow down which port is used for the mic streaming so right now I just all all UDP from the IP address of my ESP32 allowed in ufw.

@ibrummel Thank you!!! I've been banging my head against the desk for an hour trying to figure this out. I would have never in a million years thought of a firewall issue - I'm so used to ESPHome devices working without messing with the firewall and never would have considered that this uses UDP.

@Sn00kiT
Copy link

Sn00kiT commented Feb 14, 2024

Has anyone managed the fix the crackling noise? As soon as i switch the wakeword option on. the speaker starts to make this crackling noise. changing the bitrate didn´t help. i tried another esp32 board/mic/amp, but the problem stays the same.

@rich33584
Copy link

Has anyone managed the fix the crackling noise? As soon as i switch the wakeword option on. the speaker starts to make this crackling noise. changing the bitrate didn´t help. i tried another esp32 board/mic/amp, but the problem stays the same.

Change the dout pin on the speaker. I have mine on GPIO12.

i2s_audio:
  - id: i2s_in
    i2s_lrclk_pin: GPIO25
    i2s_bclk_pin: GPIO26
  - id: i2s_out
    i2s_lrclk_pin: GPIO32
    i2s_bclk_pin: GPIO13

microphone:
  platform: i2s_audio 
  id: external_microphone 
  adc_type: external 
  i2s_audio_id: i2s_in
  i2s_din_pin: GPIO34
  pdm: false
  bits_per_sample: 32bit


speaker:
  platform: i2s_audio 
  id: external_speaker 
  dac_type: external
  i2s_audio_id: i2s_out
  i2s_dout_pin: GPIO12
  mode: mono 

@rich33584
Copy link

Anybody know how to limit the max volume with the Max98357?

Ive built 3 of these now:
https://youtube.com/shorts/-tBJXZdqqRw?si=Tfem5Rv8X2GZ0gWe
A couple things I have learned.
Be careful with the Microphone, the INMP441. If you get it too hot, you'll kill it. If you have a long delay between the command and the action, its more than likely the microphone.
I seem to have better luck building and wiring the voice assistant before loading the firmware onto it. So, get the basic firmware loaded, then build and wire the voice assistant. After that, load the final firmware.
If you are just seeing the basic firmware in the ESP32 interface, select "Clean Build Files" in ESP home by clicking the 3 dots, and then upload the firmware.
Spamming too many commands too quickly will freeze the pipeline. In normal use, you wont be sending 10 commands a minute, so slow down in testing.
The YAML im using. Credit goes to this guy:
https://github.com/ubergeek10/My-ESP32-Assistant

substitutions:
  voice_assist_idle_phase_id: '1'
  voice_assist_listening_phase_id: '2'
  voice_assist_thinking_phase_id: '3'
  voice_assist_replying_phase_id: '4'
  voice_assist_not_ready_phase_id: '10'
  voice_assist_error_phase_id: '11'
  voice_assist_muted_phase_id: '12'
esphome:
  name: bedroom-voice-assistant
  friendly_name: Bedroom Voice assistant

  on_boot:
    priority: 600
    then:
      - script.execute: control_led
      - delay: 30s
      - if:
          condition:
            lambda: return id(init_in_progress);
          then:
            - lambda: id(init_in_progress) = false;
            - script.execute: control_led

esp32:
  board: esp32dev
  framework:
    type: esp-idf


# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "snip"

ota:
  password: "snip"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Bedroom-Voice-Assistant"
    password: "snip"

esp_adf:
external_components:
  - source: github://pr#5230
    components:
    - esp_adf 
    refresh: 0s

captive_portal:

light:
  - platform: esp32_rmt_led_strip
    rgb_order: GRB
    pin: GPIO18
    num_leds: 3
    rmt_channel: 0
    chipset: WS2812
    name: "Status LED"
    id: led
    default_transition_length: 0s
    effects:
      - pulse:
          name: "extra_slow_pulse"
          transition_length: 800ms
          update_interval: 800ms
          min_brightness: 0%
          max_brightness: 30%
      - 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%

i2s_audio:
  - id: i2s_in
    i2s_lrclk_pin: GPIO25
    i2s_bclk_pin: GPIO26
  - id: i2s_out
    i2s_lrclk_pin: GPIO32
    i2s_bclk_pin: GPIO13

microphone:
  platform: i2s_audio 
  id: external_microphone 
  adc_type: external 
  i2s_audio_id: i2s_in
  i2s_din_pin: GPIO34
  pdm: false
  bits_per_sample: 32bit


speaker:
  platform: i2s_audio 
  id: external_speaker 
  dac_type: external
  i2s_audio_id: i2s_out
  i2s_dout_pin: GPIO12
  mode: mono 

voice_assistant:
  id: va
  microphone: external_microphone 
  speaker: external_speaker
  use_wake_word: true
  noise_suppression_level: 1
  auto_gain: 31dBFS
  volume_multiplier: 2.5

  on_listening:
    - lambda: id(voice_assistant_phase) = ${voice_assist_listening_phase_id};
    - script.execute: control_led

  on_stt_vad_end:
    - lambda: id(voice_assistant_phase) = ${voice_assist_thinking_phase_id};
    - script.execute: control_led

  on_tts_stream_start:
    - lambda: id(voice_assistant_phase) = ${voice_assist_replying_phase_id};
    - script.execute: control_led

  on_tts_stream_end:
    - lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
    - script.execute: control_led

  on_error: 
    - if:
        condition:
          lambda: return !id(init_in_progress);
        then:
          - lambda: id(voice_assistant_phase) = ${voice_assist_error_phase_id};
          - script.execute: control_led
          - delay: 1s
          - if:
              condition:
                switch.is_on: use_wake_word
              then:
                - lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
              else:
                - lambda: id(voice_assistant_phase) = ${voice_assist_muted_phase_id};
          - script.execute: control_led

  on_client_connected: 
    - if:
        condition:
          switch.is_on: use_wake_word
        then:
          - voice_assistant.start_continuous
          - lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
        else:
          - lambda: id(voice_assistant_phase) = ${voice_assist_muted_phase_id};
    - script.execute: control_led          

  on_client_disconnected: 
    - lambda: id(voice_assistant_phase) = ${voice_assist_not_ready_phase_id};
    - script.execute: control_led

switch:
  - platform: template
    name: Use Wake Word
    id: use_wake_word
    optimistic: true
    restore_mode: RESTORE_DEFAULT_ON
    on_turn_on:
      - if:
          condition:
            lambda: return !id(init_in_progress);
          then:
            - lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
            - if:
                condition:
                    not:
                      - voice_assistant.is_running
                then:
                  - voice_assistant.start_continuous
            - script.execute: control_led          
 
    on_turn_off:
      - if:
          condition:
            lambda: return !id(init_in_progress);
          then:
            - voice_assistant.stop
            - lambda: id(voice_assistant_phase) = ${voice_assist_muted_phase_id};
            - script.execute: control_led          

globals:
  - id: init_in_progress
    type: bool
    restore_value: no
    initial_value: 'true'
  - id: voice_assistant_phase
    type: int
    restore_value: no
    initial_value: ${voice_assist_not_ready_phase_id}
  
script:
  - id: control_led
    then:
      - if:
          condition:
            lambda: return !id(init_in_progress);
          then:
            - if:
                condition:
                    wifi.connected:
                then:
                  - if:
                      condition:
                          api.connected:
                      then:
                        - lambda: |
                            switch(id(voice_assistant_phase)) {
                              case ${voice_assist_listening_phase_id}:
                                id(led).turn_on().set_rgb(0, 0, 1).set_brightness(1.0).set_effect("none").perform();
                                break;
                              case ${voice_assist_thinking_phase_id}:
                                id(led).turn_on().set_rgb(0, 1, 0).set_effect("slow_pulse").perform();
                                break;
                              case ${voice_assist_replying_phase_id}:
                                id(led).turn_on().set_rgb(0, 0, 1).set_brightness(1.0).set_effect("fast_pulse").perform();
                                break;
                              case ${voice_assist_error_phase_id}:
                                id(led).turn_on().set_rgb(1, 1, 1).set_brightness(.5).set_effect("none").perform();
                                break;
                              case ${voice_assist_muted_phase_id}:
                                id(led).turn_off().perform();
                                break;
                              case ${voice_assist_not_ready_phase_id}:
                                id(led).turn_on().perform();
                                break;
                              default:
                                id(led).turn_on().set_rgb(1, 0, 0).set_brightness(0.2).set_effect("none").perform();
                                break;
                            }
                      else:
                        - light.turn_off:
                            id: led
                else:
                  - light.turn_off:
                      id: led
          else:
            - light.turn_on:
                id: led
                blue: 50%
                red: 50%
                green: 50%
                effect: "fast_pulse"

DEV board:
https://www.amazon.com/gp/product/B09GK74F7N/ref=ppx_yo_dt_b_asin_title_o03_s00?ie=UTF8&psc=1
Using the INMP441 for the mic
Max98357 for the amp
Led's:
https://www.amazon.com/gp/product/B09P8MH56K/ref=ppx_yo_dt_b_asin_title_o03_s00?ie=UTF8&th=1
Speaker assembly:
https://www.walmart.com/ip/onn-Small-Rugged-Speaker-with-Bluetooth-Wireless-Technology-Blue/883044562?athbdg=L1100&from=/search

The 3 I have built are running well and reliably. They dont like too much background noise, but some tweeking may help that. I have an automation that will mute my TV on wake word detection to help.
Im also running Home Assistant on a bare metal machine with an I7 and 16gb RAM

@Sn00kiT
Copy link

Sn00kiT commented Feb 16, 2024

Has anyone managed the fix the crackling noise? As soon as i switch the wakeword option on. the speaker starts to make this crackling noise. changing the bitrate didn´t help. i tried another esp32 board/mic/amp, but the problem stays the same.

Change the dout pin on the speaker. I have mine on GPIO12.

i2s_audio:
  - id: i2s_in
    i2s_lrclk_pin: GPIO25
    i2s_bclk_pin: GPIO26
  - id: i2s_out
    i2s_lrclk_pin: GPIO32
    i2s_bclk_pin: GPIO13

microphone:
  platform: i2s_audio 
  id: external_microphone 
  adc_type: external 
  i2s_audio_id: i2s_in
  i2s_din_pin: GPIO34
  pdm: false
  bits_per_sample: 32bit


speaker:
  platform: i2s_audio 
  id: external_speaker 
  dac_type: external
  i2s_audio_id: i2s_out
  i2s_dout_pin: GPIO12
  mode: mono 

Thank you that did the trick and also thank you for the post after that (-: !!!

@joshfedo
Copy link

@rich33584
That config seems to be working for me. Im still hitting some issues with TTS getting cut short or the wake work getting picked up by STT. But all in all its actually working better.

Heres a wire mapping for anyone who is going to try it out:
Mapping:

ESP32 (WROOM-32) MAX98357A (Speaker) I2S Microphone
GPIO33 DIN -
GPIO12 LRCLK -
GPIO13 BCLK -
GPIO34 - SD
GPIO25 - WS
GPIO26 - SCK
3.3V VDD VDD
GND GND GND

@rich33584
Copy link

@rich33584 That config seems to be working for me. Im still hitting some issues with TTS getting cut short or the wake work getting picked up by STT. But all in all its actually working better.

I seem to have spells of hours that it works perfectly, and then hours where the TTS is broken and crappy.
Not sure if its a wifi issue or if the ESP32 is just barely adequate to run these. I ordered som "Better" esp32 modules. Ill report back on them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment