Skip to main content

使用 XIAO ESP32S3 进行 reSpeaker Flex I2S 测试

本项目作为一个测试示例,用于验证 XIAO ESP32S3ReSpeaker Flex 之间 I2S 接口的功能。目标是确认通过 I2S 总线进行的数据发送和接收是否正常工作。为此,示例会生成一个合成的方波音频信号并将其写入 I2S 接口,然后从 ReSpeaker Flex 麦克风阵列读取音频数据,并验证接收样本的完整性。

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

工作原理

该示例测试 XIAO ESP32S3 与 ReSpeaker Flex 之间的全双工 I2S 通信。它会生成一个 440 Hz 的方波信号,并持续将其写入 I2S 发送端,同时从麦克风阵列读取输入音频样本。对接收到的数据进行分析,统计有效(非零)样本数量,作为基本的完整性检查。根据有效样本的数量,程序判断 I2S 接收通路是否正常工作。

#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, 16-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
}


技术支持与产品讨论

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

Loading Comments...