1.环境配置: 参考Arduino IDE上手教程完成IDE安装, 并根据实际使用的开发板安装对应的板管理, 与需要的驱动库。
2.使用到的驱动库:
3.使用到的硬件产品:
Module Audio集成了STM32主控用于实现耳机接口标准切换,灯光控制,耳机插入检测(仅通道2可用),麦克风输入模式配置等功能。
device.setHPMode(AUDIO_HPMODE_NATIONAL);
函数切换耳机接口标准以实现兼容。OMTP
(AUDIO_HPMODE_NATIONAL),CTIA
(AUDIO_HPMODE_AMERICAN)。#include "M5Unified.h"#include "audio_i2c.hpp"#include "es8388.hpp"#include "driver/i2s.h" #define SYS_I2C_SDA_PIN 21#define SYS_I2C_SCL_PIN 22#define SYS_I2S_MCLK_PIN 0#define SYS_I2S_SCLK_PIN 19#define SYS_I2S_LRCK_PIN 27#define SYS_I2S_DOUT_PIN 2#define SYS_I2S_DIN_PIN 34#define SYS_SPI_MISO_PIN 38#define SYS_SPI_MOSI_PIN 23#define SYS_SPI_CLK_PIN 18#define SYS_SPI_CS_PIN 4 AudioI2c device; ES8388 es8388(&Wire, SYS_I2C_SDA_PIN, SYS_I2C_SCL_PIN); void setup(){ M5.begin(); Serial.begin(115200); device.begin(&Wire, SYS_I2C_SCL_PIN, SYS_I2C_SCL_PIN); device.setHPMode(AUDIO_HPMODE_NATIONAL); // device.setHPMode(AUDIO_HPMODE_AMERICAN); device.setMICStatus(AUDIO_MIC_OPEN); device.setRGBBrightness(100); for (int i = 0; i <= 2; i++) { device.setRGBLED(i, 0x0000ff); }} void loop(){ bool isHPInsert = device.getHPInsertStatus(); if (isHPInsert) { Serial.println("Headphone Inserted"); } else { Serial.println("Headphone Removed"); } delay(500);}
在完成初始化后,通过调用以下API配置输入输出接口通道选择与音量增益等参数。
// Use input 1 for both channelses8388.setADCInput(ADC_INPUT_LINPUT1_RINPUT1); // Use input 2 for both channels// es8388.setADCInput(ADC_INPUT_LINPUT2_RINPUT2); es8388.setDACOutput(DAC_OUTPUT_OUT1);es8388.setADCVolume(100);es8388.setDACVolume(40);es8388.setMicGain(MIC_GAIN_24DB);es8388.setMixSourceSelect(MIXADC, MIXADC);es8388.setBitsSample(ES_MODULE_ADC, BIT_LENGTH_16BITS);es8388.setSampleRate(SAMPLE_RATE_44K);
使用TRS音频信号接口接线方式,配置通道1接入MIC输入,通道2音频输出,实现实时读取MIC输入数据和播放。
#include "M5Unified.h"#include "audio_i2c.hpp"#include "es8388.hpp"#include "driver/i2s.h"AudioI2c device; #define SYS_I2C_SDA_PIN 21#define SYS_I2C_SCL_PIN 22#define SYS_I2S_MCLK_PIN 0#define SYS_I2S_SCLK_PIN 19#define SYS_I2S_LRCK_PIN 27#define SYS_I2S_DOUT_PIN 2#define SYS_I2S_DIN_PIN 34#define SYS_SPI_MISO_PIN 38#define SYS_SPI_MOSI_PIN 23#define SYS_SPI_CLK_PIN 18#define SYS_SPI_CS_PIN 4 ES8388 es8388(&Wire, SYS_I2C_SDA_PIN, SYS_I2C_SCL_PIN); uint16_t rxbuf[256], txbuf[256];size_t readsize = 0;byte error, address;const uint32_t color[] = {0xFF0000, 0xFF0000, 0xFF0000, 0x00FF00, 0xFFFF00, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF};i2s_config_t i2s_config = {.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX), .sample_rate = 44100, .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, .communication_format = I2S_COMM_FORMAT_STAND_I2S, .intr_alloc_flags = 0, .dma_buf_count = 8, .dma_buf_len = 512, .use_apll = false, .tx_desc_auto_clear = true, .fixed_mclk = 0}; i2s_pin_config_t pin_config = { .mck_io_num = SYS_I2S_MCLK_PIN, .bck_io_num = SYS_I2S_SCLK_PIN, .ws_io_num = SYS_I2S_LRCK_PIN, .data_out_num = SYS_I2S_DOUT_PIN, .data_in_num = SYS_I2S_DIN_PIN,}; void setup(){ M5.begin(); Serial.begin(115200); device.begin(&Wire, SYS_I2C_SCL_PIN, SYS_I2C_SCL_PIN); device.setHPMode(AUDIO_HPMODE_NATIONAL); device.setMICStatus(AUDIO_MIC_OPEN); device.setRGBBrightness(100); Serial.printf("getHPMode:%d\n", device.getHPMode()); Serial.printf("getMICStatus:%d\n", device.getMICStatus()); for (int i = 0; i <= 2; i++) { device.setRGBLED(i, color[i + 3]); // Output the hexadecimal value of the current color Serial.printf("Set RGB to %06X\n", (unsigned int)color[i + 3]); Serial.printf("get RGB to %06X\n", device.getRGBLED(i)); } Serial.println("Read Reg ES8388 : "); if (!es8388.init()) Serial.println("Init Fail"); es8388.setADCInput(ADC_INPUT_LINPUT1_RINPUT1); es8388.setMicGain(MIC_GAIN_24DB); es8388.setADCVolume(100); // The volume output should not exceed 40, otherwise there will be noise or current sounds es8388.setDACVolume(40); es8388.setDACOutput(DAC_OUTPUT_OUT1); es8388.setMixSourceSelect(MIXADC, MIXADC); es8388.setBitsSample(ES_MODULE_ADC, BIT_LENGTH_16BITS); es8388.setSampleRate(SAMPLE_RATE_44K); uint8_t *reg; for (uint8_t i = 0; i < 53; i++) { reg = es8388.readAllReg(); Serial.printf("Reg-%02d = 0x%02x\r\n", i, reg[i]); } // i2s i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); i2s_set_pin(I2S_NUM_0, &pin_config);} void loop(){ i2s_read(I2S_NUM_0, &rxbuf[0], 256 * 2, &readsize, 1000); for (int i = 0; i < 256; i++) { // direct transfer too txbuff txbuf[i] = rxbuf[i]; // txbuf[i] = 0; //mute } // play received buffer i2s_write(I2S_NUM_0, &txbuf[0], 256 * 2, &readsize, 1000);}
配置通道2音频输出,加载MicroSD卡中存储的WAV文件,并进行播放。使用前需添加wav文件至MicroSD卡,并插入至主控设备卡槽中。
#include "M5Unified.h"#include "audio_i2c.hpp"#include "es8388.hpp"#include "driver/i2s.h"#include <SPI.h>#include <SD.h>AudioI2c device; #define SYS_I2C_SDA_PIN 21#define SYS_I2C_SCL_PIN 22#define SYS_I2S_MCLK_PIN 0#define SYS_I2S_SCLK_PIN 19#define SYS_I2S_LRCK_PIN 27#define SYS_I2S_DOUT_PIN 2#define SYS_I2S_DIN_PIN 34#define SYS_SPI_MISO_PIN 38#define SYS_SPI_MOSI_PIN 23#define SYS_SPI_CLK_PIN 18#define SYS_SPI_CS_PIN 4 ES8388 es8388(&Wire, SYS_I2C_SDA_PIN, SYS_I2C_SCL_PIN);void i2s_write_task(void *arg);uint16_t rxbuf[256], txbuf[256];size_t readsize = 0;byte error, address;const uint32_t color[] = {0xFF0000, 0xFF0000, 0xFF0000, 0x00FF00, 0xFFFF00, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF};i2s_config_t i2s_config = {.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX), .sample_rate = 44100, .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, .communication_format = I2S_COMM_FORMAT_STAND_I2S, .intr_alloc_flags = 0, .dma_buf_count = 8, .dma_buf_len = 512, .use_apll = false, .tx_desc_auto_clear = true, .fixed_mclk = 0}; i2s_pin_config_t pin_config = { .mck_io_num = SYS_I2S_MCLK_PIN, .bck_io_num = SYS_I2S_SCLK_PIN, .ws_io_num = SYS_I2S_LRCK_PIN, .data_out_num = SYS_I2S_DOUT_PIN, .data_in_num = SYS_I2S_DIN_PIN,}; void setup(){ M5.begin(); Serial.begin(115200); device.begin(&Wire, SYS_I2C_SCL_PIN, SYS_I2C_SCL_PIN); device.setHPMode(AUDIO_HPMODE_NATIONAL); device.setMICStatus(AUDIO_MIC_OPEN); device.setRGBBrightness(100); Serial.printf("getHPMode:%d\n", device.getHPMode()); Serial.printf("getMICStatus:%d\n", device.getMICStatus()); for (int i = 0; i <= 2; i++) { device.setRGBLED(i, color[i + 3]); // Output the hexadecimal value of the current color Serial.printf("Set RGB to %06X\n", (unsigned int)color[i + 3]); Serial.printf("get RGB to %06X\n", device.getRGBLED(i)); } Serial.println("Read Reg ES8388 : "); if (!es8388.init()) Serial.println("Init Fail"); es8388.setADCVolume(100); es8388.setDACVolume(80); es8388.setDACOutput(DAC_OUTPUT_OUT1); es8388.setMixSourceSelect(MIXADC, MIXADC); es8388.setBitsSample(ES_MODULE_ADC, BIT_LENGTH_16BITS); es8388.setSampleRate(SAMPLE_RATE_44K); uint8_t *reg; for (uint8_t i = 0; i < 53; i++) { reg = es8388.readAllReg(); Serial.printf("Reg-%02d = 0x%02x\r\n", i, reg[i]); } // i2s i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); i2s_set_pin(I2S_NUM_0, &pin_config); if (SD.begin(SYS_SPI_CS_PIN)) { Serial.println("SD card initialized successfully"); } else { Serial.println("Failed to initialize SD card. Retrying..."); } xTaskCreate(i2s_write_task, "i2s_write_task", 1024 * 8, NULL, 6, NULL);} void loop(){} void i2s_write_task(void *arg){ // Open the WAV file // Replace with the path of your WAV file File file = SD.open("/hello.wav", "r"); if (!file) { Serial.println("Failed to open WAV file for reading"); vTaskDelete(NULL); } // Obtain the file size and print size_t fileSize = file.size(); Serial.printf("File size: %d bytes\n", fileSize); // Skip the WAV file header (44 bytes) file.seek(44); uint8_t txbuf[1024]; while (1) { // Check whether the end of the file has been reached if (file.available() == 0) { // Go back to the beginning of the file in order to replay it file.seek(44); } // Read data size_t bytesRead = file.read(txbuf, sizeof(txbuf)); // If data is read if (bytesRead > 0) { size_t bytesWritten = 0; esp_err_t result = i2s_write(I2S_NUM_0, txbuf, bytesRead, &bytesWritten, portMAX_DELAY); // Check the writing result if (result != ESP_OK) { Serial.printf("I2S write error: %d\n", result); } } else { // If there is no more data, exit the loop break; } } // Close the file file.close(); vTaskDelete(NULL);}
Module Audio侧边集成了3颗可编程RGB LED,可参考以下案例进行控制。
#include "M5Unified.h"#include "audio_i2c.hpp"#include "es8388.hpp"#include "driver/i2s.h" #define SYS_I2C_SDA_PIN 21#define SYS_I2C_SCL_PIN 22 AudioI2c device; void setup(){ M5.begin(); Serial.begin(115200); Serial.println("Module Audio Init..."); while (!device.begin(&Wire, SYS_I2C_SDA_PIN, SYS_I2C_SCL_PIN)) { delay(1000); }; Serial.println("Module Audio Init OK!"); device.setRGBBrightness(100);} void loop(){ for (int i = 0; i <= 2; i++) { device.setRGBLED(i, 0xff0000); } delay(1000); for (int i = 0; i <= 2; i++) { device.setRGBLED(i, 0x00ff00); } delay(1000); for (int i = 0; i <= 2; i++) { device.setRGBLED(i, 0x0000ff); } delay(1000);}