Hi,
I’m trying to configure an M5StickC Plus 2 with voice assistant. I managed to get the microphone to work as best I could. I was able to display the response on the screen, but there is a problem with the text being long and if it goes off the screen, there are errors in the logs.
I’ve a SPK2 HAT speaker, which I would like to configure. But I can’t find the right configuration, because the microphone and speaker use the same GPIO0 and the two cannot work together.
There is also the speaker (buzzer) on the GPIO2, which must be deactivated for the microphone to work.
Shematic:
-
M5StickC Plus 2
-
SPK2 HAT
an arduino example to operate the microphone and speaker, if it helps.
my config.yaml ( not perfect, but works )
substitutions:
name: m5stickc-plus2-voice
friendly_name: M5StickC PLUS2 Voice
esphome:
name: ${name}
name_add_mac_suffix: false
friendly_name: ${friendly_name}
project:
name: m5stack.atom-echo-voice-assistant
version: "1.0"
min_version: 2023.11.1
platformio_options:
upload_speed: 115200
on_boot:
- priority: 600
then:
- output.turn_on: output_high
on_shutdown:
- priority: 600
then:
- output.turn_off: output_high
esp32:
board: m5stick-c
framework:
type: esp-idf
flash_size: 8MB
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "xxxxxxxxx"
ota:
password: "xxxxxxxx"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
improv_serial:
esp32_improv:
authorizer: none
script:
- id: reset_led
then:
- if:
condition:
switch.is_on: use_wake_word
then:
- light.turn_on:
id: led
else:
- light.turn_off: led
output:
- platform: ledc
pin: GPIO19
id: led_pwm
# Buzzer output
- platform: ledc
pin:
number: GPIO2
id: buzzer
inverted: false
# Backlight TFT LCD
- platform: ledc
pin: 27
inverted: false
id: backlight
# Battery output
- platform: gpio
id: output_high
pin:
number: GPIO4
mode:
output: true
spi:
clk_pin: GPIO13
mosi_pin: GPIO15
i2s_audio:
- id: mic_adc
i2s_lrclk_pin:
number: GPIO0
# allow_other_uses: true
ignore_strapping_warning: true
# - id: spk_adc
# i2s_lrclk_pin:
# number: GPIO0
# allow_other_uses: true
# ignore_strapping_warning: true
# i2s_bclk_pin: GPIO26
microphone:
- platform: i2s_audio
id: echo_microphone
i2s_din_pin: GPIO34
adc_type: external
channel: left
i2s_audio_id: mic_adc
# bits_per_sample: 16bit
# sample_rate: 44100
pdm: true
#speaker:
# - platform: i2s_audio
# dac_type: internal
# i2s_audio_id: spk_adc
# mode: right
#speaker:
# - platform: i2s_audio
# id: echo_speaker
# i2s_dout_pin: GPIO25
# i2s_audio_id: mic_adc
# dac_type: external
# mode: mono
voice_assistant:
id: va
microphone: echo_microphone
# speaker: echo_speaker
noise_suppression_level: 2
auto_gain: 31dBFS
volume_multiplier: 2.0
vad_threshold: 3
on_listening:
- light.turn_on:
id: led
effect: "Listening"
on_stt_vad_end:
- light.turn_on:
id: led
effect: "Listening"
on_tts_start:
- text_sensor.template.publish:
id: tts
state: !lambda 'return x;'
- light.turn_on:
id: led
brightness: 60%
- delay: 100ms
- light.turn_off: led
on_end:
- delay: 100ms
# - wait_until:
# not:
# speaker.is_playing:
- script.execute: reset_led
on_error:
- light.turn_on:
id: led
effect: "Error"
- delay: 2s
- script.execute: reset_led
- script.wait: reset_led
on_client_connected:
- if:
condition:
switch.is_on: use_wake_word
then:
- voice_assistant.start_continuous:
- script.execute: reset_led
on_client_disconnected:
- if:
condition:
switch.is_on: use_wake_word
then:
- voice_assistant.stop:
- light.turn_off: led
binary_sensor:
- platform: gpio
pin:
number: GPIO37
inverted: true
name: Button A
disabled_by_default: true
entity_category: diagnostic
id: a_button
on_click:
min_length: 50ms
max_length: 350ms
then:
- if:
condition:
switch.is_off: use_wake_word
then:
- if:
condition: voice_assistant.is_running
then:
- voice_assistant.stop:
- script.execute: reset_led
else:
- output.turn_off: buzzer
- voice_assistant.start:
else:
- voice_assistant.stop
- delay: 1s
- script.execute: reset_led
- script.wait: reset_led
- voice_assistant.start_continuous:
- platform: gpio
pin:
number: GPIO39
inverted: true
name: Button B
disabled_by_default: true
entity_category: diagnostic
on_click:
min_length: 50ms
max_length: 350ms
then:
- light.toggle: display_bl
light:
- platform: monochromatic
id: led
name: None
disabled_by_default: true
entity_category: config
output: led_pwm
effects:
- pulse:
name: "Listening"
transition_length: 1s
update_interval: 1s
min_brightness: 0%
max_brightness: 30%
- pulse:
name: "Error"
transition_length: 0.25s
update_interval: 0.25s
min_brightness: 0%
max_brightness: 100%
# Backlight TFT LCD
- platform: monochromatic
output: backlight
name: Backlight
id: display_bl
restore_mode: RESTORE_DEFAULT_ON
sensor:
- platform: uptime
id: uptime_sec
update_interval: 60s
internal: true
switch:
- platform: template
name: Use wake word
id: use_wake_word
restore_mode: ALWAYS_OFF
optimistic: true
entity_category: config
on_turn_on:
- lambda: id(va).set_use_wake_word(true);
- if:
condition:
not:
- voice_assistant.is_running
then:
- output.turn_off: buzzer
- voice_assistant.start_continuous
- script.execute: reset_led
on_turn_off:
- voice_assistant.stop
- lambda: id(va).set_use_wake_word(false);
- script.execute: reset_led
- platform: restart
name: Restart
entity_category: "diagnostic"
time:
- platform: homeassistant
id: my_time
text_sensor:
- platform: template
name: "text-to-speech"
id: tts
- platform: template
id: stickc_uptime
name: Uptime
lambda: |-
int seconds = (id(uptime_sec).state);
int days = seconds / (24 * 3600);
seconds = seconds % (24 * 3600);
int hours = seconds / 3600;
seconds = seconds % 3600;
int minutes = seconds / 60;
seconds = seconds % 60;
if ( days ) {
return { (to_string(days) +"d " + to_string(hours) +"h " + to_string(minutes) +"m "+ to_string(seconds) +"s ").c_str() };
} else if ( hours ) {
return { (to_string(hours) +"h " + to_string(minutes) +"m "+ to_string(seconds) +"s ").c_str() };
} else if ( minutes ) {
return { (to_string(minutes) +"m "+ to_string(seconds) +"s ").c_str() };
} else {
return { (to_string(seconds) +"s ").c_str() };
}
icon: mdi:clock-start
update_interval: 60s
entity_category: "diagnostic"
font:
- file: "gfonts://Roboto"
id: roboto
size: 18
glyphs: "<>!'%()/+,-_.:;*=°?#0123456789AÀBCDEÉÈÊFGHIJKLMNOPQRSTUVWXYZ aàbcdeéèêfghijklmnopqrstuvwxyzôöç"
color:
- id: my_white
red: 100%
green: 100%
blue: 100%
- id: my_blue
red: 0%
green: 0%
blue: 100%
- id: my_red
red: 100%
green: 0%
blue: 0%
- id: my_green
red: 0%
green: 100%
blue: 0%
- id: my_yellow
red: 100%
green: 100%
blue: 0%
- id: my_orange
red: 100%
green: 50%
blue: 0%
# 1.14 inch, 135*240 Colorful TFT LCD, ST7789v2
display:
- platform: ili9xxx
model: st7789v
cs_pin: GPIO5
dc_pin: GPIO14
reset_pin: GPIO12
rotation: 90
dimensions:
height: 240
width: 135
offset_height: 40
offset_width: 52
# Required or the colors are all inverted, and Black screen is White
invert_colors: true
lambda: |-
it.strftime(30, 2, id(roboto), id(my_blue), "%H:%M:%S %d/%m/%y", id(my_time).now());
it.printf(5, 28, id(roboto), id(my_white), "Réponse:");
it.printf(5, 54, id(roboto), id(my_green), id(tts).state.c_str());
external_components:
- source: github://pr#5230
components:
- esp_adf
refresh: 0s
esp_adf:
[20:08:16][D][voice_assistant:439]: State changed from STOPPING_MICROPHONE to AWAITING_RESPONSE
[20:08:18][D][voice_assistant:563]: Event Type: 4
[20:08:18][D][voice_assistant:591]: Speech recognised as: "éteindre cuisine"
[20:08:18][D][voice_assistant:563]: Event Type: 5
[20:08:18][D][voice_assistant:596]: Intent started
[20:08:18][D][voice_assistant:563]: Event Type: 6
[20:08:18][D][voice_assistant:563]: Event Type: 7
[20:08:18][D][voice_assistant:619]: Response: "Éteint"
[20:08:18][D][text_sensor:064]: 'text-to-speech': Sending state 'Éteint'
[20:08:18][D][light:036]: 'M5StickC PLUS2 Voice' Setting:
[20:08:18][D][light:051]: Brightness: 60%
[20:08:18][D][light:085]: Transition length: 1.0s
I’m looking for people who could help me in this project, who would have better skills than me.
To be able to configure the microphone and speaker and have a portable voice assistant.
Thank you in advance and sorry for my english.