pdf-icon

Arduino入門

2. デバイス&サンプル

Module Audio Arduino チュートリアル

1. 準備作業

2. 初期化

モジュールオーディオは STM32 メインコントロールを統合し、ヘッドホンインターフェースの標準切り替え、ライト制御、ヘッドホン挿入検出(チャンネル 2 のみ利用可能)、マイク入力モード設定などの機能を実現するために使用されます。

インターフェース規格選択
ヘッドホンジャックの規格によって配線順序が異なるため、
cpp
1 2
device.setHPMode(AUDIO_HPMODE_NATIONAL); // OMTP(国標)
// device.setHPMode(AUDIO_HPMODE_AMERICAN); // CTIA(美標)

を呼び出して、OMTP / CTIA を切り替え、互換性を確保してください。

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
#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_SDA_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);
}

3. 入力インターフェース設定

インターフェース使用説明
Module Audio には 2 系統の 3.5 mm オーディオジャック(チャンネル1 と チャンネル2)が搭載されています。
  • チャンネル1:3.5 mm TRS マイク入力専用
  • チャンネル2:3.5 mm TRRS 複合オーディオジャック対応(TRS 互換)
  • TRS 配線:チャンネル1 を MIC 入力に、チャンネル2 をオーディオ出力に接続。PC ヘッドセットなどマイクと出力が分離された機器に適しています。
  • TRRS 配線:チャンネル2 を複合入出力に接続。マイク付き有線ヘッドセットに対応し、TRS 機器とも互換性があります。

初期化後、以下の API を呼び出してチャンネル選択と音量/ゲインを設定します。

cpp
1 2 3 4 5 6 7 8 9 10 11 12
// 両チャンネルに入力1を使用
es8388.setADCInput(ADC_INPUT_LINPUT1_RINPUT1);
// 両チャンネルに入力2を使用
// 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);

4. 録音と再生

TRS 配線を使用し、チャンネル1 を MIC 入力、チャンネル2 をオーディオ出力に設定して、マイク入力データをリアルタイムで読み取り再生します。

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
#include "M5Unified.h"
#include "audio_i2c.hpp"
#include "es8388.hpp"
#include "driver/i2s.h"
AudioI2c device;
ES8388 es8388(&Wire, SYS_I2C_SDA_PIN, SYS_I2C_SCL_PIN);
uint16_t rxbuf[256], txbuf[256];
size_t readsize = 0;
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_SDA_PIN, SYS_I2C_SCL_PIN);
device.setHPMode(AUDIO_HPMODE_NATIONAL);
device.setMICStatus(AUDIO_MIC_OPEN);
device.setRGBBrightness(100);
if (!es8388.init()) Serial.println("Init Fail");
es8388.setADCInput(ADC_INPUT_LINPUT1_RINPUT1);
es8388.setMicGain(MIC_GAIN_24DB);
es8388.setADCVolume(100);
es8388.setDACVolume(40);
es8388.setDACOutput(DAC_OUTPUT_OUT1);
es8388.setBitsSample(ES_MODULE_ADC, BIT_LENGTH_16BITS);
es8388.setSampleRate(SAMPLE_RATE_44K);
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, portMAX_DELAY);
for (int i = 0; i < 256; i++) {
txbuf[i] = rxbuf[i];
}
i2s_write(I2S_NUM_0, &txbuf[0], 256 * 2, &readsize, portMAX_DELAY);
}

5. MicroSD 上の WAV 再生

チャンネル2 をオーディオ出力に設定し、MicroSD カードに保存された WAV ファイルを読み込んで再生します。使用前に WAV ファイルを MicroSD カードにコピーし、ホストデバイスのカードスロットに挿入してください。

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
#include "M5Unified.h"
#include "audio_i2c.hpp"
#include "es8388.hpp"
#include "driver/i2s.h"
#include <SPI.h>
#include <SD.h>
AudioI2c device;
ES8388 es8388(&Wire, SYS_I2C_SDA_PIN, SYS_I2C_SCL_PIN);
void i2s_write_task(void *arg);
i2s_config_t i2s_config = { /* 上述と同じ */ };
i2s_pin_config_t pin_config = { /* 上述と同じ */ };
void setup()
{
M5.begin();
Serial.begin(115200);
device.begin(&Wire, SYS_I2C_SDA_PIN, SYS_I2C_SCL_PIN);
device.setHPMode(AUDIO_HPMODE_NATIONAL);
device.setMICStatus(AUDIO_MIC_OPEN);
device.setRGBBrightness(100);
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);
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)
{
File file = SD.open("/hello.wav", FILE_READ);
if (!file) {
Serial.println("Failed to open WAV file for reading");
vTaskDelete(NULL);
}
file.seek(44); // WAV ヘッダーをスキップ
uint8_t buf[1024];
size_t bytesRead, bytesWritten;
while (true) {
if (file.available() == 0) {
file.seek(44);
}
bytesRead = file.read(buf, sizeof(buf));
if (bytesRead > 0) {
esp_err_t res = i2s_write(I2S_NUM_0, buf, bytesRead, &bytesWritten, portMAX_DELAY);
if (res != ESP_OK) {
Serial.printf("I2S write error: %d\n", res);
}
} else {
break;
}
}
file.close();
vTaskDelete(NULL);
}

6. RGB LED 制御

Module Audio の側面には 3 つのプログラマブル RGB LED が搭載されています。以下の例を参照して制御できます。

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
#include "M5Unified.h"
#include "audio_i2c.hpp"
#define SYS_I2C_SDA_PIN 21
#define SYS_I2C_SCL_PIN 22
AudioI2c device;
void setup()
{
M5.begin();
Serial.begin(115200);
while (!device.begin(&Wire, SYS_I2C_SDA_PIN, SYS_I2C_SCL_PIN)) {
delay(1000);
}
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);
}
On This Page