バイクでBluetooth Audio

私の所有するバイク (HONDA FORZA MF10) には走行中に音楽を楽しめるAudio機能が付いています。これは後付けではなくオリジナルの状態でついているのですが、他のバイクでもHONDAではGold Wingのみ(?)で、海外製のハーレーやBMWにあるような大型のツアラーバイクの一部にある程で珍しい部類になります。FORZAにおいてもMF10の前にも後にもオーディオが搭載されているモデルはありません。

![パネル全景](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267750/53544690-89e8-3272-1c98-b5c606e97ee5.jpeg)

最近であればヘルメットの中にBluetoothのインカムを取り付けて音楽を楽しめるようになってますので、敢えてバイクにAudioを取り付ける意味も薄れているかもしれません。購入時は電話もガラケーでしたし、Bluetoothも普及してる状態ではなく、PCで使う物のイメージが強かったと思います。現行モデルのバイクは割とシンプルなデザインが多くて時代の変化を感じてしまいますが、個人的には無駄にゴテゴテで華やかな方が気に入ってて乗り続けています。

![オーディオパネル・ラジオ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267750/e0ac18b3-ba14-7bbd-cebc-92ea1ec4ea8e.jpeg)

![オーディオ・外部入力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267750/ddb12202-6e84-5d71-3a94-c76247f9e46a.jpeg)

AudioはAM/FMのラジオと、小物入れの中にある3.5mmのミニプラグに繋いだ機器から音を出すことが出来ます。プレイヤーを再生状態にして中に入れて音を聞く分にはそれでも十分なのですが、最近ではスマホで再生する音やナビの音声も聞けるようにもしたいことからBluetooth Audioの対応を考えていました。

# Bluetooth Audioの対応方法

バイクには3.5mmのミニプラグの入力がありますので、Bluetooth AudioからLINE出力して渡せばいいだけです。その実現には次の方法が考えられます。

## 方法1

一番簡単な方法は市販の機器を買うことです。しかしながら最近ではAudio機器が最初からBluetoothに対応している物が多くなっているためか、選択肢が少ない状態でした。あっても高級路線な物ばかりでバイクに載せるには適さないと思いました。ECショップで探してみても技適認証取ってないような物が目について嫌になってました。

また、市販の物は家庭内で使用する想定で電源スイッチを操作する必要があり、バイクのイグニッションスイッチと連動できないのが使い勝手が悪いと思い、改造前提になってしまうのも気が引けている1つでした。

## 方法2

次に考えたのは、市販のBluetooth Audioのチップを使う方法でした。調べてみると `RN52` や `BM62` というものがあるようです。

例えばこんな物があります

* [キット・モジュール]低雑音BluetoothオーディオDIPモジュール(Bluetooth5.0対応)【MZ-BM62-B01】
    * https://www.marutsu.co.jp/pc/i/2177496/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267750/56fc78c6-98b4-196d-3615-6a20e469d553.png)

製品情報見ても、まさに目的に合った物で「欲しい」と思っていたのですが

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267750/42ab1ab4-77fc-6f95-78af-2d10c804bdf6.png)

「入荷待ち」状態です。時々は見ていたのですが入ってい来る気配は無さそうで、企画物だったのか量産する物ではないのかもしれません

表面実装のチップだけであれば入手出来るものは見つかりましたが、実装できる気がしないのでDIP化されている物で探してました。

## 方法3

ESP32でBluetooth Audioを実現できます。ESP32であればESP32-WROOMで入手性が良く手軽にできそうです。割と情報が見つかり、GitHubにライブラリもありました。

* ESP32-A2DP
    * https://github.com/pschatzmann/ESP32-A2DP

ESP32だけでもBluetoothから音が出せるようですが性能が良くないので、外部のオーディオ出力のチップを組み合わせます。I2Sの信号からアナログオーディオを出力する物で、秋月から `PCM5102A` を入手しました。

ＰＣＭ５１０２Ａ　ＤＩＰ化キット
https://akizukidenshi.com/catalog/g/gK-11836/

こちらとESP32-WROOM 32Eを使ってBluetooth Audioを実現しました

ＥＳＰ３２－ＤｅｖＫｉｔＣ－３２Ｅ　ＥＳＰ３２－ＷＲＯＯＭ－３２Ｅ開発ボード　４ＭＢ
https://akizukidenshi.com/catalog/g/gM-15673/

※ 秋月のサイトは時々、「セッションが切れました」と表示されてTOPに戻るようにメッセージが表示されることがありますが、TOPに移動しないで、メッセージの画面をリロードすれば商品のページを表示することができます (環境によるかもしれません)

# 実装

`ESP32-WROOM-32E` と `PCM5102A` の組み合わせでBluetooth Audioを実現するまでの手順を紹介します。

## 回路

このように繋いでいきます直接繋ぐだけでなく、コンデンサが必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267750/e18a6c82-8705-e4f0-1284-e90107a39be9.png)

雑な図ですが、自分も組み立てたいと思った方はネットで探せば様々な所から実装例がありますので、そちらを参照お願いいたします。コンデンサの容量はこの通りでなくても動作すると思います。参考にする所によって違っていますので、どれが正解か分からないです。

`PCM5102A` と `ESP32-WROOM` のピンは以下の通りに繋ぎます

| PCM5102A | ESP32-WROOM |
|---|---|
| LRCK (15) | IO25・DAC_1 (10) |
| DIN (14) | IO22 (36) |
| BCK (13) | IO26・DAC_2 (11) |
| MCLK | 繋ぎません |

* `()` 内の数字はチップの足の順序で割り当てられる、ピン番号です
* `MCLK` を繋ぐと音質が良くなるようですが、ソフトウェアの実装が増えるようですので今回は省略しました

以下が組み立てた基板の写真です。

![基板表.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267750/c8ad7b97-575b-5ff1-de70-d610e8e0e2f6.jpeg)

恥ずかしいですが裏面も晒します

![基板裏面.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267750/4b831e22-f04d-64d3-7c0b-d3d46041ca2c.jpeg)

コンデンサは手元にある物で間に合わせた為に、種類がバラバラです。細かく見れば分かりますが、チップコンデンサも使っています。

さらに恥ずかしいですが、横から見た様子です

![47A0E517-D90E-42DA-9D72-BFF654F4B0CC.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267750/226c8120-035f-90f5-12c5-844f00fafafe.jpeg)

ピンソケットが少ししか残ってなかったために、必要な所だけ刺すようにして無理やり完成させました。

## ソフトウェア

GitHubの [ESP32-A2DP](https://github.com/pschatzmann/ESP32-A2DP) リポジトリからCodeをZIPでダウンロードします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267750/aeea0ef3-17ff-43bb-c7d0-926b53501961.png)

Arduino IDEを開きます。

[スケッチ] - [ライブラリをインクルード] - [.ZIP形式のライブラリをインストール] をクリックします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267750/2e900c0c-53ac-bfae-a55c-f86ae2dda428.png)

ダイアログが開きますので、GitHubからダウンロードしたzipファイルを指定すれば、Bluetooth Audioのライブラリが追加されます。

以下のコードを貼り付けます。

```cpp:BLE-audio.ino
#include "BluetoothA2DPSink.h" 
BluetoothA2DPSink a2dp_sink;

void setup() {
    // set i2s pin 
    i2s_pin_config_t my_pin_config = {
        .bck_io_num = 26,
        .ws_io_num = 25,
        .data_out_num = 22,
        .data_in_num = I2S_PIN_NO_CHANGE
    };
    // set i2s mode
    static i2s_config_t i2s_config = {
        .mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX),
        .sample_rate = 44100, // updated automatically by A2DP
        .bits_per_sample = (i2s_bits_per_sample_t)32,
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
        .communication_format = (i2s_comm_format_t) (I2S_COMM_FORMAT_STAND_I2S),
        .intr_alloc_flags = 0, // default interrupt priority
        .dma_buf_count = 8,
        .dma_buf_len = 64,
        .use_apll = true,
        .tx_desc_auto_clear = true // avoiding noise in case of data unavailability
    };

    a2dp_sink.set_pin_config(my_pin_config);
    a2dp_sink.set_i2s_config(i2s_config);
    a2dp_sink.set_auto_reconnect(true);
    // set device name
    a2dp_sink.start("BT_Audio");
}

void loop() {
  // put your main code here, to run repeatedly:
}
```

`my_pin_config` 構造体メンバーに指定する数値が、PCM5102Aへ繋ぐIOの番号に相当します。 `bck_io_num` → `BCK` 、　`ws_io_num` → `LRCK` 、`data_out_num` → `DIN` へそれぞれ繋ぐようにします。

`a2dp_sink.start("BT_Audio");` の引数を変更すると、スマホで表示されるBluetooth機器の名前が変わります。例えば `a2dp_sink.start("FORZA_MF10");` のようにバイクの名前にすれば、これだけでも気持ちが上がってくると思います。

![スマホで機器名を表示した様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267750/fe495f5d-760a-bc1a-f20c-b3702b517b48.jpeg)

ESP32-WROOMに書き込みます。PCとESP-WROOMボードをUSBケーブルで繋いで、Arduino IDEの「マイコンボードに書き込む」のボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267750/a560a5bf-e9dc-d9cb-b0b8-686c1b91280d.png)

書込み後にESP32が再起動します。スマホ等からBluetooth機器を探せば `BT_Audio` が見つかって接続できるはずです。

# バイクに取り付けた様子

バイクから出ている3.5mmプラグとESP32-WROOMの電源を繋ぎます。電源はシガーソケット分配器のスマホ充電用のUSB端子から取りました。

![4E42C20E-AE45-4D83-B4BD-DA709A345E98.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267750/584c604c-1d6f-3b27-696c-a80d7aac9732.jpeg)

## デモ動画

<iframe width="560" height="315" src="https://www.youtube.com/embed/d1dugpCw7j4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# ハマった所

実は、スムーズに上手くいった訳ではなく、Bluetooth接続は出来ているのに音が出ない状態でハマってました。原因が分かれば大したことない感じですが、目に見える症状が動くか動かないかなので、分かるまでが先の見えない道を進んでいるようで、ハード開発は「本当にHARD」だと思いました。

## ピンの番号を間違えていた

`ESP32-WROOM` と `PCM5102A` を繋ぐピンですが、ESP32-WROOM のピンをIOの番号ではなく、チップから出ている足の順番で割り振られる `ピン番号` の方だと思って繋いでました。オシロスコープでクロックの信号が流れていないのが変だと思って、ESP32-WROOMのピンから信号が出ている所を調べて判明しました。

## コンデンサの容量を間違えていた

手書き回路図の雑さが原因なのですが、2.2μFで指定されていた所を間違って22μFを付けてました。せっかく綺麗に取り付けできたと思ってたのに、外して付け直す時は切なかったです。

# 今後の展望

今回は音を出すだけで終わってしまいましたが、以下のような発展を考えています。

## 展望1 使い勝手の向上

現状は通電するとESP32の起動からスマホと接続までは行いますが、スマホの音量を調整しないと音が小さすぎたり、大きすぎたりします。バイクに乗ってESP32とつながった時はESP32からスマホの音を自動的に調節するようにしたいと考えてます。スピーカーから出す音量はバイク側で調節します。

また、Bluetoothに繋がった時に再生ボタンを押す手間がありますので、イグニッションONでESP32と繋がったら再生状態に出来ればスマホに触ることなく音が出る仕組みにできればと思っています。

## 展望2 ESP32から音を出す

ESP32で音声ファイルを再生して通知音などを出せればと考えてます。例えば、エンジンがかかった時に挨拶が聞こえてくるなど、アイデアはまとめ中ですが、車両情報と連携して何か言葉を発してくれば、バイクとコミュニケーションが取れたような感覚になると思ってます。

## 展望3 スマホアプリとの連携

もちろん、走行中にスマホは操作はしません。ナビの音声をバイクで流すのも連携の一つではあります。

ESP32とBluetoothで繋がった時はバイクに乗っていると判断できますので、それをキーにしたアプリを作ってみようと考えてます。

# 感想

思いついてから、Bluetooth Audioの実現方法の模索、回路を組んだ後のトラブルから進捗が滞ってしまい、内容が出発点に立つまでな感じになってしまいました。こんな状態で、今回は「IoT」ではなく「T」のみの内容となってしまいましたが、スマホの連携などこれからの発展につなげられるネタとして見ていただければと思っています。