脱着可能なBluetooth接続するスピーカーを自作してみた(ラズパイ使用)

最近[デジットハッカソン](http://digithack.jp/)というイベントに参加してアレンジスピーカーというものを作りました。
一言でいうと、木に脱着可能なBluetooth接続するスピーカーです。

イメージはこんな感じ。
![DSC_0164.JPG](https://qiita-image-store.s3.amazonaws.com/0/95595/74ee8aec-60ae-07ca-e6ff-a4374b6fe25f.jpeg)

電子工作経験ほぼ皆無なのでメモとして。。。
アレンジスピーカーの仕様は下記となります。
 
## アレンジスピーカー仕様

- スピーカーは枝に着脱可能(一つの枝に最大2つ)
- マイコンとPC/SPをBluetoothで接続して再生
- マイコンはRaspberryPiを使用
- 付ける場所によって音(高音・低音・L・Rなど)を変える
- マイコンとスピーカーは有線<br>(Bluetoothだとバッテリーが必要で長時間再生が難しいため)
- 音が鳴ってないときはオブジェとして


まずはスピーカーの選定が必要となります。
ただオーディオの知識がほぼない。。。
 
取り急ぎ音を流せる環境を用意してみます。


## RaspberryPiでBluetooth接続
RaspberryPi(ラズパイ)でBluetooth接続して音楽を流してみます。
取り急ぎイヤホンジャックからの出力をします。
 
今回使用するラズパイはこちら。
 
Raspberry Pi 3 Model B
[Amazon | Raspberry Pi 3 MODEL B | 基板 | 産業・研究開発用品 通販](https://www.amazon.co.jp/RASPBERRY-PI-TSI-PI018-Clear-Raspberry-Pi3-Model/dp/B01D1FR29M)

 
すぐできるかと思ったのですが、意外とややこしい気味。。
色々触ってたものなのでもしかしたら手順足りないかもです。。


なにをするにもSSH接続しないと始まりません。
SSH接続するにあたり、LANケーブルが手元になかったためWi-Fi接続しようと、最初はモニター無しで頑張ってみたものの(変なこだわり。。。。)、色々試してみたけどできず。。。
おとなしく一時的にモニターに接続してwi-fiの初期設定を変更。瞬殺。
macからSSH接続。 

その後、Bluetooth接続してもなぜかすぐに切れます。。。。
 
```
bluetoothctl
```
で確認すると

<img width="400" alt="2bfc34ce.png" src="https://qiita-image-store.s3.amazonaws.com/0/95595/c2024b47-e557-98bb-63e1-a7b0c003de3b.png">

 
すぐに

```
[CHG] Device XX:XX:XX:XX:XX:XX Connected: yes
[CHG] Device XX:XX:XX:XX:XX:XX Connected: no
```

って。。。
この間5秒間。。

 
ちょいとハマりました。。
色々ググって見たところ。。
 
```
[bluetooth]# trust XX:XX:XX:XX:XX:XX
[bluetooth]# pair XX:XX:XX:XX:XX:XX
[bluetooth]# connect XX:XX:XX:XX:XX:XX
```

ってやったらいいみたい。
素直にやってみらたなんかいけた。

## Bluetooth接続で音を鳴らす(イヤホンジャック)
イヤホンジャックにイヤホンを接続して次のコマンドを実行してみます。
まずは音がなることの確認。

```
aplay /usr/share/sounds/alsa/Rear_Center.wav
```

「りあー。せんたぁっ。」と音がなりました。
音声ファイル再生してるだけです。。。はい。
 
次は pi というユーザが、Bluetoothデーモンにアクセスできるよう、
lp というグループに pi を追加。

```
$ sudo usermod -a -G lp pi
```
A2DPが利用できるように、Bluetoothの設定を行います。
 
A2DPとは、Bluetoothの無線通信技術を用いて高品質なオーディオデータを伝送するためのプロファイル群のことである。 A2DPは主にプレーヤーとヘッドフォンとの間で連絡し、音楽データをやり取りすることができる。
 
らしいです。。。。
 
ラズパイはviしか入っていなみたいで、カーソルおしたらAとかBとか出て焦る。。
なのでvimを入れました。

```
sudo apt-get install vim
```

[General]の項目に、以下の記述を追加。

```
$ sudo vim /etc/bluetooth/audio.conf
```

```
[General]
Enable=Source,Sink,Headset,Gateway,Control,Socket,Media
```

pulse audioのサンプリング関連の設定を行う。

```
$ sudo vim /etc/pulse/daemon.conf
```
```
; resample-method = speex-float-3
 resample-method = trivial
```


## Pulseaudio連携

Bluetoothが接続された時に自動的にPulseaudioと連携して音声が出力できるように設定します。
 
【注意】メモしながらしてたものの、なんか別の事もしてたような気がするので、下記だけでは動かないかもです。。SDPサーバとかも準備していた様な。。。

Bluetoothが接続された時に自動的にPulseaudioと連携して音声が出力できるように設定します。
適当に/home/pi/speaker.shを作成。実行権限(0755)を与えておきます。

```sh
#!/bin/bash

AUDIOSINK="alsa_output.0.analog-stereo"

echo "Executing bluetooth script...|$ACTION|" >> /var/log/bluetooth_dev

ACTION=$(expr "$ACTION" : "\([a-zA-Z]\+\).*")
if [ "$ACTION" = "add" ]; then
   for dev in $(find /sys/devices/virtual/input/ -name input*); do
      if [ -f "$dev/name" ]; then
         mac=$(cat "$dev/name" | sed 's/:/_/g')
         bluez_dev=bluez_source.$mac

         sleep 1

         CONFIRM=`sudo -u pi pactl list short | grep $bluez_dev`
         if [ ! -z "$CONFIRM" ]; then
            echo "Setting bluez_source to:  $bluez_dev" >> /var/log/bluetooth_dev
            echo pactl load-module module-loopback source=$bluez_dev sink=$AUDIOSINK rate=44100 adjust_time=0 >> /var/log/bluetooth_dev
            sudo -u pi pactl load-module module-loopback source=$bluez_dev sink=$AUDIOSINK rate=44100 adjust_time=0 >> /var/log/bluetooth_dev
         fi
      fi
   done
fi

if [ "$ACTION" = "remove" ]; then
   CONFIRM=`sudo -u pi pactl list short | grep 'module-loopback\ssource=bluez_source'`
   if [ ! -z "$CONFIRM" ]; then
      module_id=`echo $CONFIRM | sed 's/\s.*//'`
      echo pactl unload-module $module_id >> /var/log/bluetooth_dev
      sudo -u pi pactl unload-module $module_id >> /var/log/bluetooth_dev
   fi
fi
```
 
 
Bluetoothデバイスが接続された際に、自動で設定が行われるように、
以下のスクリプトを作成。

```
$ sudo vim /etc/udev/rules.d/99-input.rules
```
```
KERNEL==”input[0-9]*”, RUN+=”/usr/lib/udev/bluetooth”
```

```
$ sudo vim /usr/lib/udev/bluetooth
```

最後にbluetooth-agentを自動起動してコネクションを待ち受けるサービスを/etc/init.d/bluetooth-agentとして新規作成（実行権限与えるのを忘れずに）

```sh
### BEGIN INIT INFO
# Provides: bluetooth-agent
# Required-Start: $remote_fs $syslog bluetooth pulseaudio
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Makes Bluetooth discoverable and connectable to 0000
# Description: Start Bluetooth-Agent at boot time.
### END INIT INFO
#! /bin/sh
# /etc/init.d/bluetooth-agent
USER=root
HOME=/root
export USER HOME
case "$1" in
        start)
                #echo "setting bluetooth discoverable"
                #sudo hciconfig hci0 piscan
                sudo hciconfig hci0 pscan
                start-stop-daemon -S -x /usr/bin/bluetooth-agent -b -- 0000
                echo "bluetooth-agent startet pw: 0000"
                ;;
        stop)
                echo "Stopping bluetooth-agent"
                start-stop-daemon -K -x /usr/bin/bluetooth-agent
                ;;
        *)
                echo "Usage: /etc/init.d/bluetooth-agent {start|stop}"
                exit 1
                ;;
esac
exit 0
```

```
sudo update-rc.d bluetooth-agent defaults
```

```sh
#change if you don’t use default audio out
AUDIOSINK="alsa_output.platform-bcm2835_AUD0.0.analog-stereo"
echo "[date]" >> /var/log/bluetooth_dev
echo "Executing bluetooth script…|$ACTION|" >> /var/log/bluetooth_dev
ACTION=$(expr "$ACTION" : "\([a-zA-Z]\+\).*")
if [ "$ACTION" = "add" ]
then
   for dev in $(find /sys/devices/virtual/input/ -name input*)
   do
      if [ -f "$dev/name" ]
      then
         mac=$(cat "$dev/name" | sed ‘s/:/_/g’)
         bluez_dev=bluez_source.$mac
         sleep 1
         CONFIRM=sudo -u pi pactl list short | grep $bluez_dev
         if [ ! -z "$CONFIRM" ]
         then
            echo "Setting bluez_source to:  $bluez_dev" >> /var/log/bluetooth_dev
            echo pactl load-module module-loopback source=$bluez_dev sink=$AUDIOSINK rate=44100 adjust_time=0 >> /var/log/bluetooth_dev
            sudo -u pi pactl load-module module-loopback source=$bluez_dev sink=$AUDIOSINK rate=44100 adjust_time=0 >> /var/log/bluetooth_dev
         fi
      fi
   done
fi
```

```
sudo chmod 774 /usr/lib/udev/bluetooth
```

```
pi@raspberrypi:~ $ sudo -u pi pactl list short sinks
0	alsa_output.platform-soc_audio.analog-stereo	module-alsa-card.c	s16le 2ch 44100Hz	IDLE
```

なんか分からないですが、ごにょごにょしてたらイヤホンから音が流れるようになりました(;ﾟ∀ﾟ)



## スピーカーユニット、アンプ
イヤホンジャックから音が出るようになったので、実際にスピーカーユニットから音を出してみたいと思います。
そのままつなげても音が小さいですのでアンプを間にいれる必要がありますが、アンプを選ぶためにはまずスピーカーユニットの選定が必要となります。
 
スピーカー選定に関する仕様は下記。

- スピーカーは枝に着脱可能(一つの枝に最大2つ)
- 付ける場所によって音(高音・低音・L・Rなど)を変える


枝に付ける必要があるためなるべく軽いもがいいかと思い、
圧電スピーカーなるものを試してみるものの音がｼｮﾎﾞｲ(´・ω:;.:...
 
なので通常のダイナミックスピーカーで探すことにしたのですが、一口にスピーカーといっても色々種類があります。

簡単にですが、

- トゥイーター(高音用)
- スコーカーあるいはミッドレンジ (中音用)
- ウーハー(低音用)
- フルレンジ(全帯域用)
 
付ける場所によって出る音域を高音・低音と変えたかったのでフルレンジのもので探しました。
また、スピーカーやアンプはインピーダンス(Ω)と呼ばれる電気抵抗があるようで、それを考える必要があります。
 
アンプ ＜ スピーカー ⇒ 最大パワーが減少
スピーカー ＜ アンプ ⇒ アンプに負荷がかかり壊れる
 
調べてみるとスピーカーのインピーダンスは8Ωのものがいいらしいので素直に8Ωで15Wのものを選択。アンプですが脱着可能なスピーカーは一つの枝に2つはつけたいと思っていたのですが、スピーカーを並列で2つつないだ場合のインピーダンスはオームの法則(でした？)より
 
`1/R=1/R1+1/R2`
なので
`1/R=1/8+1/8=1/4`
2つつないだ場合は4Ω。
3つは。。。。ﾔﾒﾀｹﾞﾃ(´；ω；｀)
 
インピーダンスが4-8Ω対応で15Wのアンプをデジットさんにて調達。
参加者にはデジットで期間中のみ使える5,000円分の商品券が配られていましたのでそちらで購入しました。電源まわりのところはわからなかったので店員さんに聞いて教えてもらったものを、スピーカー・ウーハー自体は別のところで購入していたのですが、届くまでに時間がかかるとのことだったのでテスト用に似たようなスピーカーも合わせて購入しました。



## 枝ぶり
木と鉢の部分は観葉植物で考えていたのですが、オブジェになるものとのことでしたので流木を使おうということになりました。
 
ってか流木てどこにあるの・・・・
 
ググってみると奈良のダムとかでもらえるみたいなのですがちょっと遠い。。。いつかとりに行こうなどと思っていたら、その時は急にきました。
 
ある日の朝、妻に「昨日雨降ったから今がいいんじゃない？」と言われたので即探しにいくことに。海沿いを車で走りながら探していると堤防の向こうにテトラポットがある河口付近に流木がありました！
4mくらいはあろう流木がテトラポットの間に挟まっていました。
変なビニールひもが絡まっていたが、ビニールひもを素手でちぎりつつ、なんとか頑張って引っこ抜きました。
が、いつの間にか雨の中。。。。
 
中二病が発動し、何故かトライデント(＝ただの流木)を手に入れたと思い込む。
土砂降りの中、堤防の上で4mの長い流木を掲げるアラフォーメガネ。
 
びしょ濡れになりながら、あと何本か流木を拾ってThe DECKに持ち込みました。
 
使えそうな枝を選んで固定してみたところ。。。。

![5ad936b5.JPG](https://qiita-image-store.s3.amazonaws.com/0/95595/0ca48b85-22c3-8d16-e67b-f11e25bc1c2c.jpeg)

っぽい気がする！？
 
ちなみに真ん中のがトライデントです。大きすぎたので車に乗せるときに切っちゃいました。
枝が3本＋ウーハーなので最低4系統(？)が必要になります。
今のアンプはLRの2系統なので、分配してアンプを追加しなければなりません。この部分はN田さんが対応してくれました。
あと、鉢部分とスピーカーの接続を考えなくては。。。
流木同士の固定はビスだと割れたりするみたいで、ドリルで穴を空けて削った割り箸を突っ込んで固定しました。



## スピーカーの接続
デジットで買ってきたアンプとスピーカーで接続のテストをします。
注文していたスピーカーですが、小さめを選んだものの0.45kgほどあります。だいたい500mlのペットボトル一本分くらいの重さになりそうです。。

色々考えましたが時間もあまりないため、取り急ぎ100均で強力なクリップを買ってきて、余った流木にスピーカーケーブルのビニールを剥いたものを貼り付けて、クリップ自体を絶縁し、銅線を這わせてテスト。

![5f8c774e.JPG](https://qiita-image-store.s3.amazonaws.com/0/95595/5918c7ed-1710-7705-9dec-5ac43b9774e7.jpeg)


接触が悪いみたいだがなんとか音は出ているみたい。
写真のようにエンクロージャー(スピーカーの側？)をつけないでスピーカーユニットだけ鳴らす場合は振動板は前後に互いに逆相の音を放射するので、この音同士が干渉すると低音域では打ち消し合ってしまうようです。
もっとちゃんと接触するようにしたらなんとかなりそう。



## 鉢(蓋付き)
鉢部分はウーハーを仕込んだり流木を支えたり基板を置いたりと色々しなければなりません。木で枠を作り、ウーハーなど固定し、流木自体には導電テープを張り巡らせました。その後に金網を打ち付けてモルタルを塗りました。
初めてやってみたけどモルタル意外と難しい。。。デジットハッカソンのプレゼンの前日に対応。。。固まるまで30時間らしんだけど、乾いてたらいいな。。。。。
蓋部分は流木の形に切り抜いたり、ウーハーの音が出るように縁部分を斜めにカットしたり、半分に割れるようにしたりとかなり手が込んでいます。。



## スピーカーケース
スピーカーケースは3Dプリンターで作る方向でfusion360というソフトで作成。クリップとスピーカーをモデリング(？)してからケース部分を作成。
クリップが可動するためスピーカーとの接続部分の処理に手間取る。。
時間があまりなかったためデザイン性や一部雑な部分は勘弁を。。。

<img width="450" alt="bdce9e76.png" src="https://qiita-image-store.s3.amazonaws.com/0/95595/0c8ac780-edc4-5297-1672-72fbcbb20fae.png">

なんとかプレゼンの前日の朝までに作成し、出力しようとしたのですが、出力時間の想定ができていませんでした。。。
3つのパーツに分けて出す想定をしていましたが全部で17時間。。。
スピーカー自体は5個作る予定なので、、、85時間。。
しかもうまく動きませんでした。。
うん。無理！

諦めが肝心です。
3Dプリンター使わない方向で。。どうしましょ。。
とりあえず100均とかで物色してちょうどいいサイズのコップと紙ねんどを買ってきてスピーカーケースをつくることに。

実際作り出したの日が変わってからだったかな笑
久しぶりに紙ねんど触ってみたけど、プラスチックにくっつくやつでふわふわしてて楽しかったです。


## ラストスパート
もう開催まで数時間。。。
基板を固定し、とりあえずスピーカーを付けてみることに。

![d7c361ef.JPG](https://qiita-image-store.s3.amazonaws.com/0/95595/5774b4b6-dc16-32cd-8414-4b76208b962e.jpeg)

スピーカーケース(紙ねんど)まだ乾いてないですが、もう時間がないので。。

![4bcc9006.JPG](https://qiita-image-store.s3.amazonaws.com/0/95595/e5f2275d-b0a7-4d4a-bc30-f5e8c17db3fb.jpeg)

なんとかプロトタイプ完成！！

当日流すために用意していたすぎやまこういち先生のDrag◯nQuestのクラシックバージョン♪を流してみたところ、重低音がスゴい！