I'm working on a project that requires an autonomous device to record audio (44.1 kHz, 16 bits minimum).
It works well with the following hardware:
ESP32 32S, PMOD I2S2, Micro SD Card Module, Sandisk Extreme Pro. The project is not powered by any switching device, and caps are placed on all the Vcc pins for every board. The sound source is limited in voltage, so it never clips (max value is around 0.05). It works fine on a protoboard.
This setup works great, but it would be better to run it on a Super Mini C3. The pins are available, and the peripherals are sufficient.
However, I'm having issues with oscillations and noise. I'm testing just the audio loopback, and it's a bit noisy (it sounds like clipping). This is without SD card recording, just with the SPI port initialized.
Also, the data saved on the SD card is incorrect (I made a mistake when saving values).
Has anyone tried this before? I couldn't find threads about I2S and C3 Mini boards.
Also, the original code I was using on the ESP32 32S is not the same, since the driver was updated and it won't compile on de C3.
The code for the C3 is:
Code: Select all
#include "driver/i2s_std.h"
#include "driver/gpio.h"
#include <SPI.h>
#include "SdFat.h"
#define PM_MCK GPIO_NUM_4 // PMOD Master ClocK, Limited by hardware. DO NOT CHANGE!
#define PM_WS GPIO_NUM_3 // PMOD Word Select
#define PM_BCK GPIO_NUM_2 // PMOD Bit ClocK
#define PM_SDIN GPIO_NUM_1 // PMOD Serial Data IN
#define PM_SDOUT GPIO_NUM_0 // PMOD Serial Data OUT
#define SD_CS 5 // SD Chip Select (SS)
#define SD_CLK 6 // SD Clock (SCK)
#define SD_MOSI 7 // SD Master Out Slave In (MOSI)
#define SD_MISO 8 // SD Master In Slave Out (MISO)
#define sampleRate 44100 // PMOD I2S2 sample rate.
#define BUFFER_SIZE 128 // Audio buffer size. 512, 1024, 2048, ...
// ... More variables
i2s_chan_handle_t tx_handle;
i2s_chan_handle_t rx_handle;
//... Init code
void setup_I2S() {
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle);
i2s_std_config_t std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(sampleRate),
.slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
.gpio_cfg = {
.mclk = PM_MCK,
.bclk = PM_BCK,
.ws = PM_WS,
.dout = PM_SDOUT,
.din = PM_SDIN,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
i2s_channel_init_std_mode(tx_handle, &std_cfg);
i2s_channel_init_std_mode(rx_handle, &std_cfg);
i2s_channel_enable(tx_handle);
i2s_channel_enable(rx_handle);
}
// ... Audio loopback. Don't pay attention to the myFile.write. Without those lines of code the loopback is still noisy.
while (millis() < endTime) {
i2s_channel_read(rx_handle, &rxbuf[0], 256, &readsize, 1000);
i2s_channel_write(tx_handle, &rxbuf[0], 256, &writtesize, 1000);
if (readsize == 256) {
for (int i = 0; i < 128; i++) {
l_in[i] = rxbuf[2 * i];
}
int written = myFile.write((byte *)l_in, BUFFER_SIZE);
if (written == 0) {
written = myFile.write((byte *)l_in, BUFFER_SIZE);
if (written == 0) {
written = myFile.write((byte *)l_in, BUFFER_SIZE);
}
}
}
}
// ... Beforo going to sleep:
i2s_channel_disable(rx_handle);
i2s_del_channel(rx_handle);
i2s_channel_disable(tx_handle);
i2s_del_channel(tx_handle);
Serial.end();
esp_deep_sleep_start();