Skip to main content

reSpeaker XVF3800 USB Mic Array 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 XVF3800 USB 4-Mic Array. 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 XVF3800 microphone array and verifies the integrity of the received samples.

pir

Objective

The primary objective of this project is to test and validate both I2S transmission (TX) and reception (RX) operations. It aims to ensure that the ReSpeaker XVF3800 microphone array can successfully send audio data back to the ESP32S3 over I2S. By doing so, it establishes a reliable baseline for I2S communication between the two devices, paving the way for more advanced audio and voice-processing applications.

How It Works

During the setup phase, the sketch initializes serial communication and starts the I2S interface using stereo configuration with 32-bit sample width. The I2S pins are configured according to the ESP32S3’s hardware mappings. In the transmit (TX) phase, a 440 Hz square wave is generated by toggling the amplitude value of the audio signal. A total of 32,000 samples are written to the I2S bus. In the receive (RX) phase, the sketch reads 32,000 samples from the XVF3800 microphone array. It then counts how many of these samples are non-zero and valid. If more than 16,000 valid samples are received, the test passes. If not, a second read attempt is made. If the result still falls below the threshold, the test is marked as failed.

Code

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

pir

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.

Loading Comments...