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 channels
es8388.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.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.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.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);
}