Skip to main content

使用 Xiao ESP32S3 通过 MQTT 传输 reSpeaker Flex 音频流

概述

本项目演示如何将嵌入 XIAO ESP32S3 开发板的 reSpeaker Flex 麦克风阵列采集到的音频进行流式传输,并以 .wav 文件的形式发送到 MQTT broker。音频通过 I2S 采集,编码为 WAV 格式,并通过 MQTT 发布。

reSpeaker Flex XVF3800 线性阵列搭配 XIAO ESP32S3 reSpeaker Flex XVF3800 环形阵列搭配 XIAO ESP32S3

Arduino MQTT Client

功能概览

此示例程序将完成以下工作:

  • 连接到指定的 WiFi 网络。
  • 连接到 MQTT broker(例如 test.mosquitto.org)。
  • 使用 I2S 从搭配 XIAO ESP32S3 的 reSpeaker Flex XVF3800 采集实时音频
  • 将音频编码为 WAV 格式
  • 将音频作为单条 MQTT 消息发布。
  • 使用 poll() 保持 MQTT 连接处于活动状态。

Arduino 代码

在上传前请先更新以下字段:

const char* ssid = "your-SSID";
const char* password = "your-WIFI-password";
const char* broker = "test.mosquitto.org";
const char* topic = "flex/audio.wav";
int port = 1883;

完整代码(约传输 3 秒音频)

#include "WiFi.h"                // For WiFi connectivity
#include "ArduinoMqttClient.h" // For MQTT communication
#include "AudioTools.h" // For handling I2S audio and WAV encoding

// Define how much audio data to send
#define MQTT_PACKET_SIZE 1024 // Size of each MQTT data packet (in bytes)
#define NUM_PACKETS 375 // Number of packets to send (~3 seconds of audio at 16kHz)

// WiFi network credentials
const char* ssid = "your-SSID"; // Replace with your WiFi SSID
const char* password = "your-WIFI-password"; // Replace with your WiFi password

// MQTT broker configuration
const char* broker = "test.mosquitto.org"; // Public test MQTT broker
const char* topic = "flex/audio.wav"; // Topic to publish audio to
int port = 1883; // Standard MQTT port

// Create MQTT and WiFi clients
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

// Configure audio: 16kHz sample rate, stereo (2 channels), 32-bit per sample
AudioInfo info(16000, 2, 32);
I2SStream i2s_in; // I2S audio input stream
I2SConfig i2s_config; // I2S hardware configuration

// Stream that encodes audio in WAV format and sends it via MQTT
EncodedAudioStream out_stream(&mqttClient, new WAVEncoder());
StreamCopy copier(out_stream, i2s_in, MQTT_PACKET_SIZE); // Handles copying I2S data into the MQTT stream

// Connect to WiFi network
void connectWiFi() {
Serial.printf("Connecting to WiFi: %s\n", ssid);
WiFi.begin(ssid, password); // Start WiFi connection
while (WiFi.status() != WL_CONNECTED) { // Wait until connected
Serial.print(".");
delay(1000);
}
Serial.println("\nConnected to WiFi!");
}

// Connect to MQTT broker
void connectMQTT() {
mqttClient.setId("xvf3800_stream"); // Set MQTT client ID
Serial.printf("Connecting to MQTT broker: %s\n", broker);

if (!mqttClient.connect(broker, port)) { // Try to connect to MQTT
Serial.print("MQTT connection failed! Code: ");
Serial.println(mqttClient.connectError());
while (true); // Stop here if connection fails
}

Serial.println("Connected to MQTT broker!");
}

// Set up I2S audio input configuration
void setupI2SInput() {
i2s_config = i2s_in.defaultConfig(RX_MODE); // Set RX mode for audio input
i2s_config.copyFrom(info); // Apply audio format to config

// Assign correct GPIO pins for XVF3800
i2s_config.pin_bck = 8; // Bit clock
i2s_config.pin_ws = 7; // Word select (LR clock)
i2s_config.pin_data = 44; // Not used for RX, but required by lib
i2s_config.pin_data_rx = 43; // Data input pin from XVF3800
i2s_config.is_master = false; // XVF3800 provides clock, so this board acts as slave

i2s_in.begin(i2s_config); // Initialize I2S input with given config
Serial.println("I2S input started.");
}

void setup() {
Serial.begin(115200); // Start serial monitor
AudioLogger::instance().begin(Serial, AudioLogger::Info); // Enable audio debug logs

connectWiFi(); // Connect to WiFi
connectMQTT(); // Connect to MQTT
setupI2SInput(); // Configure and start I2S audio input

out_stream.begin(info); // Initialize WAV encoder with audio format

// Start a new MQTT message and reserve enough space for the full audio stream
mqttClient.beginMessage(topic, MQTT_PACKET_SIZE * NUM_PACKETS, true);

// Copy audio from microphone (I2S) into MQTT stream
copier.copyN(NUM_PACKETS); // Copies a fixed number of packets (3 seconds of audio)

mqttClient.endMessage(); // Finalize the MQTT message and send it
Serial.println("Audio stream sent via MQTT!");
}

void loop() {
mqttClient.poll(); // Keep MQTT connection alive (important if broker expects pings)
delay(5000); // Optional delay, useful if recording repeatedly
}

使用串口监视器(115200 波特率)确认连接和流式传输状态。

pir

Python 脚本(用于接收并保存音频)

import paho.mqtt.client as mqtt

broker = "test.mosquitto.org"
port = 1883
topic = "flex/audio.wav"
output_file = "output.wav"
audio_data = bytearray()

def on_message(client, userdata, msg):
global audio_data
print("🔊 Received audio message")
audio_data.extend(msg.payload)

with open(output_file, "wb") as f:
f.write(audio_data)
print(f"✅ WAV file saved as: {output_file}")

client = mqtt.Client()
client.on_message = on_message

print(f"Connecting to MQTT broker {broker}...")
client.connect(broker, port, 60)

client.subscribe(topic)
print(f"📡 Subscribed to: {topic}")
client.loop_forever()

收听音频

文件保存完成后(output.wav),只需使用任意音频播放器打开,例如:

  • VLC
  • Windows Media Player
  • Audacity(用于分析)

技术支持与产品讨论

感谢您选择我们的产品!我们将为您提供多种支持,确保您在使用我们产品的过程中体验顺畅。我们提供多种沟通渠道,以满足不同的偏好和需求。

Loading Comments...