現象
ESP32のスケッチ例のCameraWebServerに対し、I2Sによる音声ファイル再生を足したところ、音声が全く再生されなかった。Webサーバーで画像取得はできる。
音声出力ライブラリ:ESP32-audioI2S
#include "Arduino.h"
#include "WiFi.h"
#include "Audio.h"
#include "SD.h"
#include "FS.h"
// Digital I/O used
#define SD_CS 5
#define SPI_MOSI 23
#define SPI_MISO 19
#define SPI_SCK 18
#define I2S_DOUT 25
#define I2S_BCLK 27
#define I2S_LRC 26
//カメラピン定義は省略
void startCameraServer();
Audio audio;
String ssid = "*******";
String password = "*******";
void setup() {
pinMode(SD_CS, OUTPUT); digitalWrite(SD_CS, HIGH);
SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
Serial.begin(115200);
SD.begin(SD_CS);
WiFi.disconnect();
WiFi.mode(WIFI_STA);
WiFi.begin(ssid.c_str(), password.c_str());
Serial.print("Camera Ready! Use 'http://");
Serial.print(WiFi.localIP());
Serial.println("' to connect");
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
audio.setVolume(21); // 0...21
audio.connecttoFS(SD, "/320k_test.mp3");
cameraInit(); //この関数内でカメラの設定が成されているが省略
startCameraServer();
}
void loop()
{
audio.loop();
}
対策
Audioの定義でI2Sのポート番号を変えてあげるとうまくいく。
Audio audio(false, 3, 1);
使用したライブラリだと、上記定義の3番目の引数がI2Sポート番号(ポート1に設定)。
全く知らなかったがスケッチ例の esp_camera.h の中ではカメラの制御にI2Sのポート0を使っているらしく、I2S音声出力がポート0だとリソース競合してしまう。なので、I2S音声出力のポート番号を変えてあげる必要がある。別のライブラリを使っても同じことだと思う。大体のESP32は2つのI2Sポートを持っていると思うが、デバイスによっては無いのかもしれないのでそこも確認が必要。今回使ったデバイスはESP32-S3でした。
所感
ESP32のカメラ関係のドキュメントをよーく読んでみると、I2Sのポートを使っていると書いてあり、ここでようやく対策をひらめきました。いやぁ、これは気が付きづらい。そして、オーディオライブラリでポート指定できるようになっていなかったら路頭に迷うところでした。