[M5Cardputer] How can I use the onboard microphone with ESP_I2S.h library?
-
I have a M5Stack Cardputer, which has an onboard SPM1423 microphone. In the official example code, it is driven by M5Stack's
M5Cardputer.h
andMic_Class.hpp
, and it works.
In arduino-esp32, it provides another I2S library namedESP_I2S.h
, which provides another way to use ESP32's I2S. I tried its exampleRecord_to_WAV.ino
, and changed theSD_MMC.h
intoSD.h
. I modified the pins, set the recording time to 1 second, and it did wrote a WAV file into the TF card. But I cannot find a way to initialize the I2S properly to receive correct data.
Here is my full code:/* ESP32-S2-EYE I2S record to WAV example This simple example demonstrates using the I2S library to record 5 seconds of audio data and write it to a WAV file on the SD card. Don't forget to select the OPI PSRAM, 8MB flash size and Enable USB CDC on boot in the Tools menu! Created for arduino-esp32 on 18 Dec, 2023 by Lucas Saavedra Vaz (lucasssvaz) */ #include "ESP_I2S.h" #include "FS.h" #include <SD.h> #include <M5GFX.h> M5GFX tft; uint16_t RGB888toRGB565(uint32_t rgb888) { return ((rgb888 & 0x00F80000) >> 8) | ((rgb888 & 0x0000FC00) >> 5) | ((rgb888 & 0x000000F8) >> 3); } const uint8_t I2S_SCK = 43; const uint8_t I2S_WS = -1; const uint8_t I2S_DIN = 46; const uint8_t SD_CMD = 14; const uint8_t SD_CLK = 40; const uint8_t SD_DATA0 = 39; void setup() { // Create an instance of the I2SClass I2SClass i2s; // Create variables to store the audio data uint8_t *wav_buffer; size_t wav_size; // Initialize the serial port tft.init(); tft.startWrite(); tft.setBrightness(64); tft.fillScreen(RGB888toRGB565(0x66CCFF)); tft.setCursor(0, 0); tft.setTextColor(RGB888toRGB565(0x003399)); tft.println("Initializing I2S bus..."); // Set up the pins used for audio input i2s.setPins(I2S_SCK, -1, -1, I2S_DIN); // Initialize the I2S bus in standard mode if (!i2s.begin(I2S_MODE_PDM_RX, 16000, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO, I2S_STD_SLOT_RIGHT)) { tft.println("Failed to initialize I2S bus!"); return; } tft.println("I2S bus initialized."); tft.println("Initializing SD card..."); // Set up the pins used for SD card access SPI.begin(40, 39, 14, 12);/*SCLK, MISO, MOSI, CS*/ SPI.setFrequency(40000000); // Mount the SD card if (!SD.begin()) { tft.println("Failed to initialize SD card!"); return; } tft.println("SD card initialized."); tft.println("Recording 1 second of audio data..."); // Record 5 seconds of audio data wav_buffer = i2s.recordWAV(1, &wav_size); // Create a file on the SD card File file = SD.open("/test.wav", FILE_WRITE); if (!file) { tft.println("Failed to open file for writing!"); return; } tft.println("Writing audio data to file..."); tft.printf("Size: %d bytes\n", wav_size); // Write the audio data to the file if (file.write(wav_buffer, wav_size) != wav_size) { tft.println("Failed to write audio data to file!"); return; } // Close the file file.close(); free(wav_buffer); tft.println("Application complete."); while (true); } void loop() {}
Please pay attention to the I2S initialization code.
I tried several different codes to init the I2S, but none of them could get the correct audio data.if (!i2s.begin(I2S_MODE_PDM_RX, 16000, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO, I2S_STD_SLOT_RIGHT)) {
This one fills 0x2987 into the WAV file, and it records no sound.
if (!i2s.begin(I2S_MODE_STD, 16000, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO, I2S_STD_SLOT_RIGHT)) {
This one fills noise into the WAV file.
if (!i2s.begin(I2S_MODE_PDM_TX, 16000, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO, I2S_STD_SLOT_RIGHT)) {
This one writes a 0 byte WAV file.
I have modified the other options of this function, but failed.How can I use the onboard microphone with
ESP_I2S.h
library?