Hello,
I am currently desperatly trying to get a NMP441 microphone properly working with a ESP32.
The code I am using seems to work but when I send the data off to my server hosted on a rpi the audio sounds broken and is just a very loud noise. My guess is that I am parsing the data from the microphone wrong. To setup the code and trying to understand what using the I2S interface means I used this doku and this github repo
This is the code for setting up the mic:
// i2s config
const i2s_config_t i2s_config = {
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX), // receive
.sample_rate = SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, // 32 bits per sample
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, // use right channel
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // interrupt level 1
.dma_buf_count = 64, // number of buffers
.dma_buf_len = SAMPLES_PER_BUFFER};
// pin config
const i2s_pin_config_t pin_config = {
.bck_io_num = gpio_sck, // serial clock, sck
.ws_io_num = gpio_ws, // word select, ws
.data_out_num = I2S_PIN_NO_CHANGE, // only used for speakers
.data_in_num = gpio_sd // serial data, sd
};
Serial.println("-----Mic Controller-----");
// config i2s driver and pins
// fct must be called before any read/write
esp_err_t err = i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
if (err != ESP_OK)
{
Serial.printf("Failed installing the driver: %d\n", err);
}
err = i2s_set_pin(I2S_PORT, &pin_config);
if (err != ESP_OK)
{
Serial.printf("Failed setting pin: %d\n", err);
}
Serial.println("I2S driver installed! :-)");
Serial.println("------------------------");
This the code for reading from the i2s peripheral:
// 44KHz (SAMPLE_RATE) * Byte per sample * time in seconds = total size in bytes
const size_t recordSize = (SAMPLE_RATE * I2S_BITS_PER_SAMPLE_32BIT / 8) * recordTime; //recordTime = 2s
// size in bytes
size_t totalReadSize = 0;
// 32 bits per sample set in config * 1024 samples per buffers = total bits per buffer
char *samples = (char *)calloc(totalBitsPerBuffer, sizeof(char));
// number of bytes read
size_t bytesRead;
Serial.println("Start recording...");
// read until wanted size is reached
while (totalReadSize < recordSize)
{
// read to buffer
esp_err_t err = i2s_read(I2S_PORT, (void *)samples, totalBitsPerBuffer, &bytesRead, portMAX_DELAY);
// check if error occurd, if so stop recording
if (err != ESP_OK)
{
Serial.println("Error while recording!");
break;
}
// check if bytes read works → yes
/*
for (int i = 0; i < bytesRead; i++)
{
uint8_t sample = (uint8_t) samples[i];
Serial.print(sample);
} */
// add read size to total read size
totalReadSize += bytesRead;
}
HttpController httpController("http://192.168.2.100:8080");
httpController.postRequest("/esp/audio", "application/octet-stream", "", (uint8_t *)samples, totalReadSize);
The httpController just sends a simple request to my node server.
The node server saves the send data in the following way:
app.post('/esp/audio', (req, res) => {
console.log(`Got ${req.body.length} I2S bytes`);
fs.appendFile('audio.raw', req.body, () => {
res.sendStatus(200);
});
});
After that I transform the audio to a .wav file.
I am probably not in the correct forum but I am pretty desperate atm to be honest.
Thanks in advance for any help!
Have a great weekend!