硬件准备
- 两个 ESP32 开发板
- MAX4466 模拟麦克风模块
- MQTT 服务器(例如 Mosquitto)
接线
- MAX4466 模块输出(AO) -> ESP32 ADC 引脚(如 GPIO 34)
软件准备
- 音频采集
- DAC 转码
- MQTT 发送和接收
代码实现
发送端:采集音频并通过 MQTT 发送
#include <WiFi.h>
#include <PubSubClient.h>
// Wi-Fi 设置信息
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
// MQTT 设置信息
const char* mqtt_server = "your_mqtt_broker_ip";
const int mqtt_port = 1883;
const char* mqtt_topic = "audio/pcm";
// ADC 引脚
const int adcPin = 34;
// Wi-Fi 客户端和 MQTT 客户端
WiFiClient espClient;
PubSubClient client(espClient);
void setup_wifi() {
delay(10);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
}
void reconnect() {
while (!client.connected()) {
Serial.print("Connecting to MQTT...");
if (client.connect("ESP32Client")) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
int adcValue = analogRead(adcPin); // 读取 ADC 值
char msg[10];
itoa(adcValue, msg, 10);
client.publish(mqtt_topic, msg); // 发送 ADC 值作为 PCM 数据
delay(10); // 控制采样率
}
接收端:接收 MQTT 数据并播放音频
#include <WiFi.h>
#include <PubSubClient.h>
#include <driver/dac.h>
// Wi-Fi 设置信息
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
// MQTT 设置信息
const char* mqtt_server = "your_mqtt_broker_ip";
const int mqtt_port = 1883;
const char* mqtt_topic = "audio/pcm";
// DAC 引脚
const int dacPin = 25;
// Wi-Fi 客户端和 MQTT 客户端
WiFiClient espClient;
PubSubClient client(espClient);
void setup_wifi() {
delay(10);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
}
void callback(char* topic, byte* payload, unsigned int length) {
payload[length] = '\0';
int adcValue = atoi((char*)payload);
// 将 ADC 值映射到 DAC 输出范围
int dacValue = map(adcValue, 0, 4095, 0, 255);
dacWrite(dacPin, dacValue); // 输出 DAC 值
}
void reconnect() {
while (!client.connected()) {
Serial.print("Connecting to MQTT...");
if (client.connect("ESP32Client")) {
Serial.println("connected");
client.subscribe(mqtt_topic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}
解释
-
Wi-Fi 连接:
- 发送端和接收端都连接到同一个 Wi-Fi 网络。
- 使用
WiFi.begin(ssid, password)
连接 Wi-Fi。
-
MQTT 连接:
- 使用
PubSubClient
库连接到 MQTT 服务器。 client.setServer(mqtt_server, mqtt_port)
设置 MQTT 服务器地址和端口。client.connect("ESP32Client")
连接到 MQTT 服务器。- 发送端使用
client.publish(mqtt_topic, msg)
发送数据。 - 接收端使用
client.subscribe(mqtt_topic)
订阅主题并接收数据。
- 使用
-
音频采集和发送:
- 发送端从 MAX4466 模块读取模拟音频信号,使用
analogRead(adcPin)
获取 ADC 值。 - 将 ADC 值转换为字符串并通过 MQTT 发送。
- 发送端从 MAX4466 模块读取模拟音频信号,使用
-
接收和播放音频:
- 接收端从 MQTT 接收音频数据,使用
callback
函数处理收到的消息。 - 将接收到的 ADC 值映射到 DAC 输出范围,使用
dacWrite(dacPin, dacValue)
输出到扬声器。
- 接收端从 MQTT 接收音频数据,使用
注意事项
- 采样率: 上述代码的采样率较低,实际应用中可能需要优化采样率和数据传输速率。
- 网络延迟: 确保网络连接稳定,避免因网络延迟导致的音频失真。
- 音质: 音频信号的质量取决于硬件配置和软件处理。可以使用更高级的音频处理算法和硬件提高音质。
通过上述步骤,你可以使用 ESP32 实现通过 MQTT 传输的无线对讲机功能。实际应用中可能需要根据具体需求进行优化和调整。