ESP32を使って簡単にBlueToothスピーカが出来ます。 Googleで検索すると多くのサイトがヒットしますが、ここが一番参考になりました。ー> https://github.com/pschatzmann/ESP32-A2DP 。
まずはハード
I2Sボード(SPEC:PCM5102)に有るパッドを前処理して、ESP32と下記の様に配線しました。
I2Sボードのコントロールは3本の信号線で行います。LCK:GIPO25 DIN:GPIO26 BCK:GPIO27。音の確認はボードのジャックにイヤフォンを挿入して行いました。
プログラム
サイトにI2Sのピンを指定するスケッチ(下記)が有ります。これを元に
#include "AudioTools.h"
#include "BluetoothA2DPSink.h"
I2SStream i2s;
BluetoothA2DPSink a2dp_sink(i2s);
void setup() {
auto cfg = i2s.defaultConfig();
cfg.pin_bck = 14;
cfg.pin_ws = 15;
cfg.pin_data = 22;
i2s.begin(cfg);
a2dp_sink.start("MyMusic");
}
void loop() {
}
これを元に、ピン指定部を今回の回路と合わせます。
#include "AudioTools.h"
#include "BluetoothA2DPSink.h"
I2SStream i2s;
BluetoothA2DPSink a2dp_sink(i2s);
void setup() {
auto cfg = i2s.defaultConfig();
cfg.pin_bck = 27;
cfg.pin_ws = 25;
cfg.pin_data = 26;
i2s.begin(cfg);
a2dp_sink.start("MyMusic");
}
void loop() {
}
ESP32-A2DP と arduino-audio-tools をLibrariesに追加してコンパイルすると、プログラムメモリーが足らないとエラーになりました。そこでESP32のPartitionSchemeを”Huge APP”に変更すると問題無くコンパイル出来ました。
スマホからこのESP32に接続して見ました。スマホのBluetooth接続の画面で接続先”MyMusic”を検索。検索後接続へと進むと問題無く接続出来ました。スマホのメディアプレーヤーで音楽を再生するとPCM5102から音声が出力されました。確かに動きます。
“AudioTools.h”をちょっとのぞくと
いろんな関数をユーザーが使用できる様になっています。その中の1つの virtual void set_address_validator を使えば、接続する相手に制限をかけれます。下記はその一例。
blue0.ino
#include "AudioTools.h"
#include "BluetoothA2DPSink.h"
#define ad_num 2
I2SStream i2s;
BluetoothA2DPSink a2dp_sink(i2s);
bool check(esp_bd_addr_t adr){
String valid_addr[ad_num] = {"xx:xx:xx:xx:xx:xx","yy:yy:yy:yy:yy:yy"};
String in_addr;
int a;
bool fl;
in_addr = a2dp_sink.to_str(adr);
Serial.println(in_addr);
fl = false;
for(a = 0; a < ad_num; a ++){
if(valid_addr[a] == in_addr){
fl = true;
break;
}
}
Serial.println(fl);
return fl;
}
void setup() {
Serial.begin(115200);
delay(500);
pinMode(RUN_LED, OUTPUT);
digitalWrite(RUN_LED, 0);
auto cfg = i2s.defaultConfig();
cfg.pin_bck = 27;
cfg.pin_ws = 25;
cfg.pin_data = 26;
i2s.begin(cfg);
a2dp_sink.set_address_validator(check);
a2dp_sink.start("MyMusic");
}
void loop() {
}
- 21行: a2dp_sink.set_address_validator(check);
- set_address_validatorの引数は実行したい関数となります。
- 呼び出された関数内で制限の詳細を記述します。
- 今回は、関数 ”check” と指定しています。
- 9行: bool check(esp_bd_addr_t adr){
- ここで制限内容を記述します。
- 引数、esp_bd_addr_t adrは接続して来たユーザーのBlueToothのIDです。
- この関数はbool宣言。戻り値が、true:接続許可。false:接続拒否となります。
- 接続を許可するユーザーを配列 valid_addr[ad_num] に予め登録。(今回はIDを2つ登録)
- 接続して来たユーザーIDと予め登録したIDを比較し有れば、trueを 無ければ、falseを返す。
プログラムを実行してスマホからアクセスすると、登録されていないスマホでもBlueToothの接続は出来るのですが音声をPCM5102から出す事は出来ませんでした。市販のBlueToothスピーカは誰でも接続出来、たまに全く関係ない人が接続してくる事が有ります。この関数を使う前は確かに簡単に接続出来るけど市販のBlueToothスピーカと同じ。なら市販のBlueToothスピーカの方が良いかと思っていましたが、この機能が使えるならこちらの方が良いと思いました。
このスケッチ、今回はBlueToothの受信機として使用していますが送信機の機能も持っています。プログラムに有る
- virtual void play(); /// Starts to play music using AVRC
- virtual void pause(); /// AVRC pause
- virtual void stop(); /// AVRC stop
- virtual void next(); /// AVRC next
- virtual void previous(); /// AVRC previous
- virtual void fast_forward(); /// AVRC fast_forward
- virtual void rewind(); /// AVRC rewind
は受信機がメディアプレーヤーの場合それをコントロールする関数と思われます。今回はこれらのコマンドは使用していません。
起動、接続の確認
市販のBlueToothスピーカは起動時、接続時、音声で知らせてくれます。これも時として有り難いような迷惑なような機能です。このBlueToothスピーカにはそれらの機能が有りません。そこで、起動したら点滅。接続後点灯するLEDを追加しました。回路は下記の通り。前回の回路からGPIO33にLEDを接続したのみです。
プログラムは下記の通り、
blue1.ino
#include "AudioTools.h"
#include "BluetoothA2DPSink.h"
#define RUN_LED 33
#define ad_num 2
I2SStream i2s;
BluetoothA2DPSink a2dp_sink(i2s);
bool check(esp_bd_addr_t adr){
String valid_addr[ad_num] = {"xx:xx:xx:xx:xx:xx","yy:yy:yy:y:y:yy"};
String in_addr;
int a;
bool fl;
in_addr = a2dp_sink.to_str(adr);
Serial.println(in_addr);
fl = false;
for(a = 0; a < ad_num; a ++){
if(valid_addr[a] == in_addr){
fl = true;
break;
}
}
Serial.println(fl);
return fl;
}
void setup() {
Serial.begin(115200);
delay(500);
pinMode(RUN_LED, OUTPUT);
digitalWrite(RUN_LED, 0);
auto cfg = i2s.defaultConfig();
cfg.pin_bck = 26;
cfg.pin_ws = 25;
cfg.pin_data = 22;
i2s.begin(cfg);
a2dp_sink.set_address_validator(check);
a2dp_sink.start("MyMu");
}
void loop() {
int a = 1;
while(1){
if(a2dp_sink.is_connected()) a = 1;
else a = ! a;
digitalWrite(RUN_LED, a);
Serial.println(a2dp_sink.get_connected_source_name());
delay(500);
}
}
BlueToothスピーカの起動、接続が分かり、接続出来るユーザを指定出来る様になりました。