I have an ESP-WROOM-32 (4Mb flash, 520kb SRAM, 448kb ROM) and I am using it as both an i2s media player and an i2s speaker. The problem I’m encountering is that it boot loops when I try to include a certain amount of raw audio for the i2s speaker (using Create audio clip files for use with I²S Speakers — ESPHome as a guide).
This is my config:
esphome:
name: $name
name_add_mac_suffix: true
friendly_name: $display_name
project:
name: $project_name
version: $project_version
includes:
# https://esphome.io/guides/audio_clips_for_i2s
# ffmpeg -i doorbell_1.mp3 -f s8 -acodec pcm_s8 -ac 1 -ar 16000 doorbell1.raw
- audio/doorbell_sounds.h
esp32:
board: esp32dev
framework:
type: arduino
version: recommended
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
mdns:
disabled: false
api:
encryption:
key: $api_key
services:
- service: doorbell
then:
- speaker.play: !lambda 'return doorbell_sounds.at(id(doorbell).active_index().value());'
logger:
binary_sensor:
- platform: status
name: "Status"
entity_category: "diagnostic"
sensor:
- platform: uptime
name: "Uptime"
type: seconds
- platform: wifi_signal
id: wifi_signal_dbm
name: "WiFi signal strength"
update_interval: 30s
unit_of_measurement: dBm
entity_category: "diagnostic"
filters:
- sliding_window_moving_average:
window_size: 10
send_every: 10
i2s_audio:
i2s_lrclk_pin: GPIO27
i2s_bclk_pin: GPIO26
media_player:
- platform: i2s_audio
name: "Media player"
dac_type: external
i2s_dout_pin:
number: GPIO25
allow_other_uses: true
mode: mono
on_play:
- logger.log: "Playback started!"
on_pause:
- logger.log: "Playback paused!"
on_idle:
- logger.log: "Playback finished!"
speaker:
- platform: i2s_audio
dac_type: external
i2s_dout_pin:
number: GPIO25
allow_other_uses: true
mode: mono
select:
- platform: template
id: doorbell
name: "Doorbell sound"
options:
- "Doorbell 1"
- "Doorbell 2"
- "Doorbell 3"
optimistic: true
set_action:
- logger.log:
format: "Doorbell sound set to '%s'"
args: ["x.c_str()"]
The doorbell_sounds.h
file contains the raw binary audio (using the ffmpeg line in the yaml comment, then using xxd
according to the page mentioned above) and looks like this:
std::array<std::vector<unsigned char>, 3> doorbell_sounds = {
std::vector<unsigned char> {{
...
}},
std::vector<unsigned char> {{
...
}},
std::vector<unsigned char> {{
...
}}
};
The project compiles and flashes successfully, however it immediately boot loops saying that something is corrupt (it has memory addresses listed). If I keep only the first std::vector<unsigned char>
that’s defined in the array, it flashes and boots ok. However, trying to add more than just that first sound seems to push it over the edge. I tested with various setups to confirm that it seems to be data size related.
When it compiles though, it says that the binary takes only 73% of the space, so it doesn’t seem like it’s exceeding available space. Also, the board is configured as esp32dev
which defaults to 320kb RAM, but the board I have apparently has 520kb (I’m assuming it’s the SRAM that is the RAM) - I don’t know if that might have any impact or not.
From the ESPHome docs, PSRAM is supposedly auto-enabled when needed, but I don’t believe my board has PSRAM on it (if it’s needed, I do have some different boards with 16Mb).
Am I missing something in my config, or am I doing something wrong with how the audio should be stored? As it is now, it seems to work (the raw audio needs a bit of fixing; it gets cut off when it plays) but I’d like to be able to store multiple audio clips.