Introduction
Voice is the most natural human interface. Yet most smart devices still rely on buttons, apps, or scheduled timers. What if you could give your ESP32 the ability to hear, understand, and act — not just on simple keywords, but on complex, context-aware commands?
I2S MEMS microphones, such as the INMP441, have made high-quality audio capture affordable and compact. When paired with a microcontroller like the ESP32, they open the door to real-time audio processing at the edge. But the real magic happens when that edge device is connected to an AI agent that can interpret the audio, make decisions, and trigger automation across your entire ecosystem.
This article explores how to integrate an I2S MEMS microphone (INMP441) with the ASI Biont AI agent. You will learn which connection methods work best, how the AI handles audio data, and see a complete end-to-end example of a voice-controlled smart home scenario — all without writing a single line of boilerplate integration code.
Why Connect an Audio Device to an AI Agent?
A standalone ESP32 with an INMP441 can detect loudness or run a basic keyword spotting model (e.g., "Hey Alexa"). But it cannot:
- Understand natural language commands like "turn off the living room lights and set the thermostat to 22°C"
- Handle noise filtering and speaker diarization
- Integrate with other smart home devices (lights, locks, HVAC) without custom middleware
- Learn from past interactions to improve accuracy over time
By connecting the microphone to ASI Biont, you offload all the complex AI processing — speech-to-text, intent classification, entity extraction, and decision-making — to a powerful cloud-based agent. The ESP32 simply captures audio, sends it over Wi-Fi, and receives actionable commands back. This architecture keeps the edge device cheap and simple while giving you access to state-of-the-art language models.
Which Connection Method Does ASI Biont Use?
For an I2S MEMS microphone connected to an ESP32, the most practical integration method is MQTT. Here is why:
| Criteria | MQTT | HTTP API | WebSocket |
|---|---|---|---|
| Real-time streaming | Excellent (pub/sub) | Poor (polling) | Good |
| Low bandwidth | Yes | No (headers) | Yes |
| ESP32 library support | Mature (PubSubClient) | Good | Limited |
| Two-way communication | Native | Requires polling | Native |
ASI Biont connects to MQTT brokers via the paho-mqtt library inside the execute_python tool. The user simply provides the broker address, topic structure, and authentication credentials in the chat. The AI agent then writes and runs a Python script that:
- Subscribes to a topic where the ESP32 publishes audio data (e.g., audio/inmp441/raw)
- Preprocesses the audio (noise reduction, VAD — Voice Activity Detection)
- Sends cleaned audio to a speech-to-text model (OpenAI Whisper or local model via transformers)
- Extracts intents and slots using a language model (e.g., openai or huggingface_hub)
- Publishes commands back to a topic (e.g., cmnd/living_room/light) that the ESP32 or other devices subscribe to
Alternative: Hardware Bridge for Serial Audio
If the ESP32 sends audio over a wired serial connection (e.g., UART to a PC), you can use the Hardware Bridge method. The user runs bridge.py on their PC, specifying the COM port (e.g., COM3) and baud rate. ASI Biont then sends commands via the industrial_command tool with protocol serial://. This is useful when Wi-Fi is unreliable or when you need a dedicated audio capture station with a Raspberry Pi.
Complete Use Case: Voice-Controlled Smart Home with INMP441 + ESP32 + ASI Biont
Overview
Goal: When a user speaks "Turn off the bedroom lamp and play white noise", the system should:
1. Capture audio on the ESP32 via INMP441
2. Send it over MQTT to ASI Biont
3. ASI Biont transcribes the audio, extracts the intent ("turn_off_device", "play_sound") and entities ("bedroom lamp", "white noise")
4. ASI Biont publishes commands to the appropriate MQTT topics
5. ESP32 (or other smart plugs) execute the commands
Step 1: Hardware Setup
Components:
- ESP32 DevKit V1
- INMP441 MEMS microphone (I2S interface)
- Breadboard and jumper wires
Wiring:
| INMP441 Pin | ESP32 Pin |
|---|---|
| VDD | 3.3V |
| GND | GND |
| L/R | GND (left channel) |
| DOUT | GPIO32 (I2S data in) |
| BCLK | GPIO26 (I2S bit clock) |
| WS | GPIO25 (I2S word select) |
Step 2: ESP32 Firmware (Arduino IDE)
The ESP32 captures audio in chunks (e.g., 512 samples at 16 kHz), applies a simple voice activity detector (VAD) based on energy threshold, and publishes the raw PCM data over MQTT only when speech is detected.
#include <WiFi.h>
#include <PubSubClient.h>
#include <driver/i2s.h>
// Wi-Fi and MQTT credentials
const char* ssid = "your-ssid";
const char* password = "your-password";
const char* mqtt_server = "test.mosquitto.org";
const char* topic_audio = "audio/inmp441/raw";
WiFiClient espClient;
PubSubClient client(espClient);
// I2S configuration
#define I2S_WS 25
#define I2S_SD 32
#define I2S_SCK 26
#define I2S_PORT I2S_NUM_0
#define SAMPLE_RATE 16000
#define BUFFER_SIZE 512
int16_t samples[BUFFER_SIZE];
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
client.setServer(mqtt_server, 1883);
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = I2S_COMM_FORMAT_I2S,
.intr_alloc_flags = 0,
.dma_buf_count = 8,
.dma_buf_len = 64
};
i2s_pin_config_t pin_config = {
.bck_io_num = I2S_SCK,
.ws_io_num = I2S_WS,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = I2S_SD
};
i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
i2s_set_pin(I2S_PORT, &pin_config);
}
void loop() {
if (!client.connected()) reconnect();
client.loop();
size_t bytes_read;
i2s_read(I2S_PORT, samples, BUFFER_SIZE * 2, &bytes_read, portMAX_DELAY);
// Simple VAD: if average amplitude > threshold, publish
int32_t sum = 0;
for (int i = 0; i < BUFFER_SIZE; i++) sum += abs(samples[i]);
if (sum / BUFFER_SIZE > 500) {
client.publish(topic_audio, (uint8_t*)samples, bytes_read);
}
delay(10);
}
Note: For production, consider adding a proper VAD library (e.g., WebRTC VAD ported to ESP32) and sending audio in compressed format (Opus) to save bandwidth.
Step 3: ASI Biont Integration (No Code Required from User)
The user opens the chat with ASI Biont and describes:
"Connect to MQTT broker at test.mosquitto.org, subscribe to topic audio/inmp441/raw. Audio is raw 16-bit PCM at 16 kHz, mono. Transcribe using Whisper, extract intent and entities, and publish commands to cmnd/#. For example, if user says 'turn off bedroom lamp', publish to cmnd/bedroom/lamp with payload 'OFF'. If user says 'play white noise', publish to cmnd/bedroom/speaker with payload 'WHITE_NOISE'."
The AI agent automatically generates and runs the following Python script inside execute_python:
import paho.mqtt.client as mqtt
import json
import numpy as np
import openai
from scipy.signal import butter, lfilter
# Configuration
BROKER = "test.mosquitto.org"
TOPIC_AUDIO = "audio/inmp441/raw"
TOPIC_CMD_PREFIX = "cmnd"
# Audio buffer
buffer = b""
def butter_bandpass(lowcut, highcut, fs, order=5):
nyq = 0.5 * fs
low = lowcut / nyq
high = highcut / nyq
b, a = butter(order, [low, high], btype='band')
return b, a
def filter_audio(data, fs=16000):
b, a = butter_bandpass(300, 3400, fs, order=5)
return lfilter(b, a, data)
def on_message(client, userdata, msg):
global buffer
# Accumulate audio chunks until silence (or timeout)
buffer += msg.payload
# Simple VAD: if last chunk is silent, process
samples = np.frombuffer(buffer, dtype=np.int16).astype(np.float32)
if np.max(np.abs(samples[-512:])) < 300:
# Apply noise reduction (basic high-pass)
filtered = filter_audio(samples)
# Normalize and convert to float32 for Whisper
audio_float = filtered / 32768.0
# Transcribe
transcript = openai.Audio.transcribe("whisper-1", audio_float)
text = transcript["text"]
print(f"Transcribed: {text}")
# Intent extraction using GPT
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{"role": "system", "content": "Extract intent and entities from the command. Output JSON with 'intent' and 'entities'."},
{"role": "user", "content": text}
]
)
result = json.loads(response["choices"][0]["message"]["content"])
intent = result["intent"]
entities = result["entities"]
# Map to MQTT commands
if intent == "turn_off_device":
device = entities.get("device", "unknown")
client.publish(f"{TOPIC_CMD_PREFIX}/{device}/power", "OFF")
elif intent == "play_sound":
sound = entities.get("sound", "white_noise")
client.publish(f"{TOPIC_CMD_PREFIX}/speaker/play", sound.upper())
# Clear buffer
buffer = b""
mqtt_client = mqtt.Client()
mqtt_client.on_message = on_message
mqtt_client.connect(BROKER, 1883, 60)
mqtt_client.subscribe(TOPIC_AUDIO)
mqtt_client.loop_forever()
Important: The sandbox has a 30-second timeout, so for production use, the script should be run as a persistent service on a separate server. ASI Biont can generate the full production-ready script and provide deployment instructions.
Step 4: Automation Scenarios Unlocked
Once the audio pipeline is running, you can chain it with other devices:
- Voice-triggered lighting: "Set the kitchen lights to warm white" → ASI Biont publishes to
cmnd/kitchen/lightwith color temperature value. - Security alert: The ESP32 detects glass break (via frequency analysis) → sends audio → ASI Biont confirms with a second-stage model → sends SMS via Twilio.
- Energy saving: "Turn off all lights when nobody is in the room" → ASI Biont combines audio (silence) with PIR sensor data (via MQTT) to decide.
- Multi-room voice control: Multiple ESP32+INMP441 units publish to different topics (
audio/kitchen/raw,audio/bedroom/raw). ASI Biont uses speaker diarization to route commands to the correct room.
Why ASI Biont Eliminates the Need for Manual Integration
Traditional integration between a microphone and a voice assistant requires:
- Writing a speech-to-text service wrapper
- Setting up a message queue (RabbitMQ, Redis)
- Building a rule engine for intents
- Creating a command dispatcher
With ASI Biont, the user simply describes the task in natural language. The AI agent:
1. Selects the appropriate connection method (MQTT, Hardware Bridge, SSH, etc.)
2. Writes the entire Python integration script using real libraries (paho-mqtt, openai, scipy)
3. Tests it in the sandbox (if possible) or provides a ready-to-deploy script
4. Handles edge cases like reconnection, authentication, and error logging
There is no dashboard to configure, no 'add device' button to click. Everything happens through the chat. This is the fastest path from hardware prototype to production automation.
Conclusion
Integrating an I2S MEMS microphone (like INMP441) with an ESP32 and the ASI Biont AI agent turns a simple audio sensor into a powerful voice-controlled automation hub. By offloading speech recognition, intent parsing, and decision-making to a cloud-based AI, you keep the edge device simple and cheap while gaining access to state-of-the-art language models.
The MQTT connection method provides a reliable, low-latency bridge between the physical world and the AI agent. With ASI Biont, you don't need to write integration code from scratch — just describe your scenario in the chat, and the AI builds the entire pipeline in seconds.
Ready to make your devices listen? Go to asibiont.com and start your first voice-controlled automation today.
Comments