reSpeaker XVF3800 USB 麦克风阵列与 XIAO ESP32S3 I2S 测试
本项目作为测试代码,用于验证 XIAO ESP32S3 与 ReSpeaker XVF3800 USB 4-Mic Array 之间 I2S 接口的功能。目标是确认通过 I2S 总线进行的数据传输和接收工作正常。为了实现这一目标,代码生成合成方波音频信号并将其写入 I2S 接口。然后从 XVF3800 麦克风阵列读取音频数据并验证接收样本的完整性。
目标
本项目的主要目标是测试和验证 I2S 传输(TX)和接收(RX)操作。它旨在确保 ReSpeaker XVF3800 麦克风阵列能够成功通过 I2S 将音频数据发送回 ESP32S3。通过这样做,它为两个设备之间的 I2S 通信建立了可靠的基线,为更高级的音频和语音处理应用铺平了道路。
工作原理
在设置阶段,代码初始化串行通信并使用立体声配置和 32 位采样宽度启动 I2S 接口。I2S 引脚根据 ESP32S3 的硬件映射进行配置。在传输(TX)阶段,通过切换音频信号的幅度值生成 440 Hz 方波。总共将 32,000 个样本写入 I2S 总线。在接收(RX)阶段,代码从 XVF3800 麦克风阵列读取 32,000 个样本。然后计算这些样本中有多少是非零且有效的。如果接收到超过 16,000 个有效样本,测试通过。如果没有,则进行第二次读取尝试。如果结果仍然低于阈值,测试标记为失败。
代码
#include "AudioTools.h"
const int sampleRate = 16000; // Hz
const int frequency = 440; // Hz square wave
const int amplitude = 500; // peak value
const int halfWavelength = sampleRate / frequency;
AudioInfo info(sampleRate, 2, 32); // stereo, 32-bit
I2SStream i2s;
I2SConfig cfg;
int32_t sample = amplitude;
int count = 0;
void printSamplesAndCount(int &nonZero) {
nonZero = 0;
bool truncated = false;
for (int i = 0; i < 32000; i++) {
int32_t rxSample;
size_t n = i2s.readBytes((uint8_t*)&rxSample, sizeof(rxSample));
if (n == sizeof(rxSample)) {
if (rxSample != 0 && rxSample != 0xFFFFFFFF) {
nonZero++;
}
if (i < 200) {
Serial.printf("%d ", rxSample);
} else if (!truncated) {
Serial.print("... (truncated)");
truncated = true;
}
}
}
Serial.println();
}
void setup() {
Serial.begin(115200);
while (!Serial);
AudioLogger::instance().begin(Serial, AudioLogger::Info);
cfg = i2s.defaultConfig(RXTX_MODE); // full duplex
cfg.copyFrom(info);
cfg.pin_bck = 8;
cfg.pin_ws = 7;
cfg.pin_data = 44; // TX data pin
cfg.pin_data_rx = 43; // RX data pin
cfg.is_master = true;
i2s.begin(cfg);
Serial.println("I2S full-duplex test start");
}
void loop() {
// 1) Generate and write 32k samples of square wave
for (int i = 0; i < 32000; i++) {
if (count % halfWavelength == 0) {
sample = -sample; // toggle polarity for square wave
}
i2s.write((uint8_t*)&sample, sizeof(sample));
count++;
}
// 2) First read attempt
int nonZero = 0;
Serial.println("First read attempt:");
printSamplesAndCount(nonZero);
Serial.printf("Valid samples: %d\n", nonZero);
// 3) Check pass/fail or do second attempt
if (nonZero > 16000) {
Serial.println("I2S RX PASS!");
} else {
Serial.println("Valid samples below threshold, trying second read...");
nonZero = 0;
Serial.println("Second read attempt:");
printSamplesAndCount(nonZero);
Serial.printf("Valid samples: %d\n", nonZero);
if (nonZero > 16000) {
Serial.println("I2S RX PASS!");
} else {
Serial.println("I2S RX FAIL!");
}
}
Serial.println("Test complete");
while (true); // stop here
}
技术支持与产品讨论
感谢您选择我们的产品!我们在这里为您提供不同的支持,以确保您使用我们产品的体验尽可能顺畅。我们提供多种沟通渠道,以满足不同的偏好和需求。