I run a woodshop and I’m trying to create a sensor that both monitors particulate matter in the air, as well as noise levels in decibels. I’ve got the particulate monitor working, but I can’t get the microphone to work. The sensors show up listed in Home Assistant for “Average Loudness” and “Peak Loudness”, but both report “Unknown.” This is my first ESPHome project and I’m sure I’m missing something. Here’s the kit I’m using:
- Sparkfun ESP32-C6
- Adafruit I2S MEMS Microphone Breakout - ICS-43434
- Adafruit PMSA003I Air Quality Breakout - STEMMA QT / Qwiic- Connected with the Qwicc connector
Here’s my yaml in Home Assistant:
esphome:
name: air-sensor
friendly_name: Air Sensor
esp32:
board: esp32-c6-devkitc-1
framework:
type: esp-idf
# Enable logging
logger:
level: DEBUG
# Enable Home Assistant API
api:
encryption:
key: "yadda yadda yadda"
ota:
- platform: esphome
password: "yadda yadda yadda"
# i2c for air sensor
i2c:
sda: 6
scl: 7
scan: true
#i2s for microphone
i2s_audio:
i2s_lrclk_pin: GPIO1
i2s_bclk_pin: GPIO2
sensor:
- platform: pmsa003i
pm_1_0:
name: "PM1.0"
pm_2_5:
name: "PM2.5"
pm_10_0:
name: "PM10.0"
pmc_0_3:
name: "PMC >0.3µm"
pmc_0_5:
name: "PMC >0.5µm"
pmc_1_0:
name: "PMC >1µm"
pmc_2_5:
name: "PMC >2.5µm"
pmc_5_0:
name: "PMC >5µm"
pmc_10_0:
name: "PMC >10µm"
update_interval: 5s
- platform: sound_level
id: sound_level_meter
microphone: mic_breakout
measurement_duration: 1000ms
passive: True
peak:
name: "Peak Loudness"
rms:
name: "Average Loudness"
microphone:
- platform: i2s_audio
id: mic_breakout
i2s_din_pin: GPIO3
adc_type: external
pdm: false
sample_rate: 48000
bits_per_sample: 32bit
channel: left
use_apll: true
# Button to soft restart, which fixes a problem where the air sensor doesn't initialize properly
button:
- platform: restart
name: "Air Sensor Restart"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: 192.168.1.105
gateway: 192.168.1.1
subnet: 255.255.255.0
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Air-Sensor Fallback Hotspot"
password: "yada yada yada"
captive_portal:
Here’s the log file I get:
INFO ESPHome 2025.10.1
INFO Reading configuration /config/esphome/air-sensor.yaml...
INFO Starting log output from 192.168.1.105 using esphome API
INFO Successfully resolved air-sensor @ 192.168.1.105 in 0.000s
INFO Successfully connected to air-sensor @ 192.168.1.105 in 0.089s
INFO Successful handshake with air-sensor @ 192.168.1.105 in 0.080s
[18:04:38.775][I][app:185]: ESPHome version 2025.10.1 compiled on Oct 17 2025, 17:42:37
[18:04:38.775][C][wifi:679]: WiFi:
[18:04:38.776][C][wifi:458]: Local MAC: yadda yadda yadda
[18:04:38.776][C][wifi:465]: IP Address: 192.168.1.105
[18:04:38.781][C][wifi:469]: SSID: yadda yadda yadda
[18:04:38.781][C][wifi:469]: BSSID: yadda yadda yadda
[18:04:38.781][C][wifi:469]: Hostname: 'air-sensor'
[18:04:38.781][C][wifi:469]: Signal strength: -48 dB ▂▄▆█
[18:04:38.781][C][wifi:469]: Channel: 11
[18:04:38.781][C][wifi:469]: Subnet: 255.255.255.0
[18:04:38.781][C][wifi:469]: Gateway: 192.168.1.1
[18:04:38.781][C][wifi:469]: DNS1: 0.0.0.0
[18:04:38.781][C][wifi:469]: DNS2: 0.0.0.0
[18:04:38.781][C][logger:261]: Logger:
[18:04:38.781][C][logger:261]: Max Level: DEBUG
[18:04:38.781][C][logger:261]: Initial Level: DEBUG
[18:04:38.787][C][logger:267]: Log Baud Rate: 115200
[18:04:38.787][C][logger:267]: Hardware UART: USB_SERIAL_JTAG
[18:04:38.788][C][logger:274]: Task Log Buffer Size: 768
[18:04:38.788][C][logger:280]: Level for 'i2s': DEBUG
[18:04:38.790][C][logger:280]: Level for 'microphone': DEBUG
[18:04:38.790][C][logger:280]: Level for 'sound_level_meter': DEBUG
[18:04:38.804][C][i2c.idf:081]: I2C Bus:
[18:04:38.804][C][i2c.idf:082]: SDA Pin: GPIO6
[18:04:38.804][C][i2c.idf:082]: SCL Pin: GPIO7
[18:04:38.804][C][i2c.idf:082]: Frequency: 50000 Hz
[18:04:38.806][C][i2c.idf:092]: Recovery: bus successfully recovered
[18:04:38.806][C][i2c.idf:102]: Results from bus scan:
[18:04:38.806][C][i2c.idf:108]: Found device at address 0x12
[18:04:38.806][C][i2c.idf:108]: Found device at address 0x36
[18:04:38.824][C][i2s_audio.microphone:079]: Microphone:
[18:04:38.824][C][i2s_audio.microphone:079]: Pin: 3
[18:04:38.824][C][i2s_audio.microphone:079]: PDM: NO
[18:04:38.824][C][i2s_audio.microphone:079]: DC offset correction: NO
[18:04:38.838][C][pmsa003i:041]: PMSA003I:
[18:04:38.842][C][pmsa003i:042]: Address: 0x12
[18:04:38.844][C][restart.button:015]: Restart Button 'Air Sensor Restart'
[18:04:38.844][C][restart.button:018]: Icon: 'mdi:restart'
[18:04:38.860][C][captive_portal:116]: Captive Portal:
[18:04:38.879][C][esphome.ota:093]: Over-The-Air updates:
[18:04:38.879][C][esphome.ota:093]: Address: 192.168.1.105:3232
[18:04:38.879][C][esphome.ota:093]: Version: 2
[18:04:38.879][C][esphome.ota:100]: Password configured
[18:04:38.879][C][safe_mode:018]: Safe Mode:
[18:04:38.879][C][safe_mode:018]: Successful after: 60s
[18:04:38.879][C][safe_mode:018]: Invoke after: 10 attempts
[18:04:38.879][C][safe_mode:018]: Duration: 300s
[18:04:38.893][C][web_server.ota:241]: Web Server OTA
[18:04:38.895][C][api:222]: Server:
[18:04:38.895][C][api:222]: Address: 192.168.1.105:6053
[18:04:38.895][C][api:222]: Listen backlog: 4
[18:04:38.895][C][api:222]: Max connections: 8
[18:04:38.898][C][api:229]: Noise encryption: YES
[18:04:38.911][C][mdns:179]: mDNS:
[18:04:38.911][C][mdns:179]: Hostname: air-sensor
[18:04:38.915][C][sound_level:022]: Sound Level Component:
[18:04:38.915][C][sound_level:022]: Measurement Duration: 100 ms
[18:04:38.916][C][sound_level:015]: Peak: 'Peak Loudness'
[18:04:38.916][C][sound_level:015]: State Class: 'measurement'
[18:04:38.916][C][sound_level:015]: Unit of Measurement: 'dB'
[18:04:38.916][C][sound_level:015]: Accuracy Decimals: 1
[18:04:38.920][C][sound_level:025]: Device Class: 'sound_pressure'
[18:04:38.920][C][sound_level:015]: RMS: 'Average Loudness'
[18:04:38.920][C][sound_level:015]: State Class: 'measurement'
[18:04:38.920][C][sound_level:015]: Unit of Measurement: 'dB'
[18:04:38.920][C][sound_level:015]: Accuracy Decimals: 1
[18:04:38.922][C][sound_level:025]: Device Class: 'sound_pressure'
[18:04:40.706][D][sensor:131]: 'PM1.0': Sending state 0.00000 µg/m³ with 2 decimals of accuracy
[18:04:40.707][D][sensor:131]: 'PM2.5': Sending state 1.00000 µg/m³ with 2 decimals of accuracy
[18:04:40.707][D][sensor:131]: 'PM10.0': Sending state 1.00000 µg/m³ with 2 decimals of accuracy
[18:04:40.712][D][sensor:131]: 'PMC >0.3µm': Sending state 195.00000 #/0.1L with 0 decimals of accuracy
[18:04:40.713][D][sensor:131]: 'PMC >0.5µm': Sending state 162.00000 #/0.1L with 0 decimals of accuracy
[18:04:40.713][D][sensor:131]: 'PMC >1µm': Sending state 0.00000 #/0.1L with 0 decimals of accuracy
[18:04:40.713][D][sensor:131]: 'PMC >2.5µm': Sending state 0.00000 #/0.1L with 0 decimals of accuracy
[18:04:40.727][D][sensor:131]: 'PMC >5µm': Sending state 0.00000 #/0.1L with 0 decimals of accuracy
[18:04:40.727][D][sensor:131]: 'PMC >10µm': Sending state 0.00000 #/0.1L with 0 decimals of accuracy
I can’t get the log file to produce anything regarding the microphone on i2s. I’ve got everything connected using a breadboard and I’ve tested continuity between posts and that seems good to my novice eyes.
Again, this is my first ESPHome and ESP32 project, so I’m probably missing something simple, but I just want to have a graph on Home Assistant that shows decibel levels over time.
Thanks in advance for any help you all can provide.