reSpeaker Flex with XIAO ESP32S3 I2S Test
This project serves as a test sketch to verify the functionality of the I2S interface between the XIAO ESP32S3 and the ReSpeaker Flex. The goal is to confirm that data transmission and reception through the I2S bus are working correctly. To achieve this, the sketch generates a synthetic square wave audio signal and writes it to the I2S interface. It then reads audio data from the ReSpeaker Flex microphone array and verifies the integrity of the received samples.
| reSpeaker Flex XVF3800 Linear with XIAO ESP32S3 | reSpeaker Flex XVF3800 Circular with XIAO ESP32S3 | |
|---|---|---|
![]() | ![]() | |
How It Works
This sketch tests full-duplex I2S communication between the XIAO ESP32S3 and the ReSpeaker Flex. It generates a 440 Hz square wave signal and continuously writes it to the I2S transmit line while simultaneously reading incoming audio samples from the microphone array. The received data is analyzed to count valid (non-zero) samples as a basic integrity check. Based on the number of valid samples, the program determines whether the I2S receive path is functioning correctly.
#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
}
Tech Support & Product Discussion
Thank you for choosing our products! We are here to provide you with different support to ensure that your experience with our products is as smooth as possible. We offer several communication channels to cater to different preferences and needs.

