ラズパイでOrgan LED Visualizer


# Organ LED Visualizer

Youtube動画で、ピアノ演奏時にLEDで光らせている動画を見かけます。
同じことをオルガン（上鍵盤・下鍵盤・足鍵盤）でもやってみました。

以下を参考にしています。

https://github.com/onlaj/Piano-LED-Visualizer

うちのオルガンは、ローランドのミュージックアトリエという機種です。
ヤマハのエレクトーンは有名ですが、それのローランド版のようなものです。
上鍵盤・下鍵盤・足鍵盤・エクスプレッションペダルそれぞれを光らせることにしました。


## 動画

発表会で明け星を演奏したので、今回はその曲にあわせて光らせ方を変えるようにしました。
これがMIDI記録したものを再生した映像です。

https://youtu.be/MjEZ1A31Ghc

動画左下はラズパイの画面出力です。
デバッグしながらだったので、ノートON情報なども出力しています。


## 回路図

回路はこんな感じです。
LEDテープはWS2812B、144LED/mのテープを、上鍵盤、下鍵盤、足鍵盤、エクスプレッションペダルそれぞれ1本ずつ使いました。

ラズパイの出力は3Vなので、レベルコンバータを挟んで5VにしてからLEDテープにつなぎます。
使っているLEDライブラリは、GPIO 13、19を同時に使えるので、この2つを使って、2組のLEDテープを光らせます。

![organled_ブレッドボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211920/cb05aff2-c3a9-2999-c7de-ed908def29c1.png)

電源は、スイッチング電源や安定化電源などを使います。
LED1個あたり、RGB3色最大輝度で0.3W消費しますので、
0.3W*144個*4本/5V=34.56A
の電源が必要になる計算ですが、実際に電力計で測るとそこまでは使いません。

最大輝度で手元の鍵盤を光らせると目が痛くなるほど眩しいですし、RGB単色なら1/3になるので、実際の消費量はだいぶ少なくなります。
その辺を見越して小さめの電源でも問題無いと思います。

## ラズパイの性能

最初Zeroで実装していたのですが、画面表示などいろいろやろうとすると性能不足だったので、Pi4で作り直しました。
画面表示などなしで、LED光らせるだけであれば、Zeroでも144LED×3本で、毎秒50回ほどの更新は可能でした。

ここではPi4版のセットアップ状況を記載します。

## OS

OSはRaspberry Pi 64bit版をインストールしました。


## NeoPixel用ライブラリ

以下2つがあり、検索だと1つ目の方がでてくるのですが、2つ目の方が動作が軽く、更新頻度を高くするために2つ目を使いました。

* https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel
* https://github.com/pimoroni/rpi_ws281x-python

1つ目もLEDの数が少なければ問題ない性能が出るのですが、今回は144*4=576個が制御対象なので、このくらい増えると厳しかったです。

試していませんが、以下のブログ記事で8ch、16ch並列での処理もできるようです。今回2つだったので試していませんが、こちらを使うとさらに更新頻度を上げることができそうです。

* https://iosoft.blog/2020/09/29/raspberry-pi-multi-channel-ws2812/

2つ目のライブラリを使っていますが、PWM出力の場合、2系統を同時に使えるため、上鍵盤・下鍵盤ペアと、足鍵盤・エクスプレッションペダルのペアで2系統に分けています。
LEDテープライトは、LEDの色を1個ずつ並べたものを一定の速度で送信するため、LEDの個数が増えるほど1回の送信に時間がかかり、その分更新頻度が下がってしまうためです。

### テープライトの仕様上の注意

テープライトはRGBそれぞれ8bitで色を指定できます。
ライブラリでは、全体の明るさを指定できるのですが、LEDテープライトのハード的に全体の明るさ制御はなく、全体の明るさに応じてRGBの値を調整しています。

例えば明るさを10%にすると、0-255の指定を、0-25の範囲になるように計算しています。
このような動作のため、明るさを暗くすると、その分諧調が荒くなってしまい、滑らかに明るさを変化させたりする演出は難しくなってしまいます。
このため、多少まぶしくてもある程度全体の明るさを上げておき、必要ならLEDテープライトに紙テープ等を張り付けて明るさを減らすのがよさそうです。

### インストール方法

```sh
sudo pip3 install rpi_ws281x
```

でモジュールをインストールします。

今回はGPIO18ピンのPWMを使うので、以下のライブラリのページに従ってaudioの設定をオフにします。

https://github.com/pimoroni/rpi_ws281x-python/tree/master/library

/etc/modprobe.d/snd-blacklist.conf ファイルを作成し、
```sh
blacklist snd_bcm2835
```
を記入。

/boot/config.txt を開いて、
```sh
hdmi_force_hotplug=1
hdmi_force_edid_audio=1
```
を記入して再起動します。

## LEDを光らせるプログラム

GitHubの方に置きました。

https://github.com/MikageSawatari/neoled/blob/main/midi.py

### 関連モジュールのセットアップ

```sh
sudo pip3 install pychord 
sudo pip3 install mido
sudo apt install libjack-dev
sudo pip3 install python-rtmidi
```


### 使い方など

起動すると標準の設定で弾いた鍵盤のあたりを光らせます。
Lower鍵盤の左端の鍵盤同時押しでモードを切り替え、AKEBOSHIにすると、明け星（Music Pieces 2022年1月号掲載の譜面）を演奏すると、いい感じに光り方が変わるようにしています。

小節数の時間経過で切り替えてもいいのですが、微妙にタイミングがずれた場合を考慮して、今回は特定のノートONパターンで切り替えるようにしてみました。
（切り替えパターンをミスタッチするとうまく切り替わりません💦）

後はソースコードを見て適当にどうぞ。。。
重い場合は、画面表示を切ると軽くなると思います。


## MIDI周りのセットアップ

### rtpmidiを使う場合

楽器のMIDI出力をPCで録音しつつLEDを光らせたかったので、いったんWindowsPCで受信し、rtpMIDIでラズパイ側に送る構成にしました。
また、rtpMIDIの場合、PCのバーチャルMIDIキーボードなどからも信号を送れるので、デバッグにも便利です。

#### インストール方法

https://github.com/davidmoreno/rtpmidid

をインストールします。

https://github.com/davidmoreno/rtpmidid/releases

にパッケージがあるのですが、aarch64用のものがないのでビルドします。

```sh
sudo apt update
sudo apt install libavahi-client-dev libfmt-dev libasound2-dev python3 cmake pandoc

git clone https://github.com/davidmoreno/rtpmidid.git
cd rtpmidid/
make build
sudo make setup
sudo PREFIX=/ make install

sudo useradd -d /var/run/rtpmidid -G audio rtpmidid
sudo cp debian/rtpmidid.service /etc/systemd/system/
sudo ln -s /etc/systemd/system/rtpmidid.service /etc/systemd/system/multi-user.target.wants/rtpmidid.service
sudo systemctl daemon-reload

```

#### MIDIポートを確認する

```sh
root@rp4midi:/home/mikage# aconnect -l
client 0: 'System' [type=kernel]
    0 'Timer           '
    1 'Announce        '
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
client 128: 'rtpmidi rp4midi' [type=user,pid=2043]
    0 'Network         '
    1 'raspberrypi     '
    2 'DESKTOP-3NK7PNV '
```

のようにしてポートを確認します。
上の場合、「client 128: 'rtpmidi rp4midi'」がrtpMIDIなので、この名前をソースコードに

```python
MIDI_PORT = 'rtpmidi rp4midi:Network 128:0'
```
のように記載しておきます。

### USB MIDI I/F を使用する場合

最初はMIDI録音しながら光らせるために、rtpmidiで最初やっていたのですが、オルガンとラズパイのみで使う場合はrtpmidi用にPCを起動するのが面倒です。
USBのMIDIアダプタもLinuxで認識するため、その後有線MIDIに切り替えました。

MIDIポートを確認して、コード上での指定を変えれば有線でも利用出来ました。

使用したのは手元にあった、Roland の UM-ONE mk2 ですが、特にドライバのセットアップ等も必要なく認識されました。

ポートの確認方法などは、rtpMIDIの時と同様です。

## ディスプレイ設定

アトリエオルガンのディスプレイは、外部のコンポーネント入力の画面を表示できます。
ここにラズパイの画面を出すことにしました。

コンポーネント出力で解像度がでないため、ラズパイ側の画面の解像度を下げます。（フルHDだと字が潰れてしまいます）

/boot/config.txtで、hdmi_mode=2 を指定して再起動し、480pまで下げます。

## 自動起動の設定

起動時に自動的にスクリプトが動作するようにしておきます。

raspi-config でAutoLoginの設定をした後、

autostart.sh
```sh
#!/bin/bassh
lxterminal --geometry=150x30 -t "ORGAN LED Visualizer" -e /home/mikage/autostart_terminal.sh
```

autostart_terminal.sh
```sh
#!/bin/bash

cd usr/neoled

while :
do
  sudo ./midi.py
done
```

.config/lxsession/LXDE-pi/autostart
```sh
@lxpanel --profile LXDE-pi
@pcmanfm --desktop --profile LXDE-pi
# @xscreensaver -no-splash
# @point-rpi
@unclutter

@xset s off
@xset -dpms
@bash /home/mikage/autostart.sh
```

ターミナルは余計な表示を隠してフォントサイズ大きめにしておきます。

.config/lxterminal/lxterminal.conf
```ini
[general]
fontname=Monospace 20
hidescrollbar=true
hidemenubar=true
hideclosebutton=true
hidepointer=true
```

### GUIの利用について

上記ではGUIを起動して、そこでターミナルを起動しています。
これは、エスケープシーケンスでフルカラーを指定して、LEDの状態を画面に表示させているのですが、CUIのコンソールだと、フルカラー指定が効かなかったためです。
GUIはだいぶ処理が重いようで、たまに重くなったりしてしまうので、ターミナルへのフルカラー表示をあきらめたほうがいいかもしれません。その場合、だいぶ処理が軽くなると思います。


## 材料

最後に使った材料のリンクです。

* Raspberry Pi 4
    * 最初はZeroを使っていたのですが、ターミナル上にLED状況をリアルタイムに表示する部分が重く、Pi 4 に移行しました。LEDの表示のみであればZeroでも大丈夫だと思います。
    * ケースはこれを使っています。https://amzn.to/3KJbOCV
        * ケースを閉じるとGPIOピンへのアクセスが難しくなりますが、後述のブレッドボードにケーブルでもってくるアイテムを使うと解消します。
* 電源
    * 144LEDs/mのLEDテープを、1m×4本利用しました。
        * 必要な最大電力は、144LED・1mで、43W=8.6Aです。4本なので、約35Aとなります。
        * 実際は、白が最大で、RGBの1色なら1/3の消費電力ですし、目に入る場所で最大輝度で光らせると眩しすぎます。なので実際に使う電力はかなり小さくなります。今回演奏した動画では、10Aでも十分足りました。
    * スイッチング電源（現在）
        * https://amzn.to/3RiMFkG
            * 5V40Aまで出るスイッチング電源です。
            * 若干ファンの音がします。静音性では後述の安定化電源のほうが良かったです。
        * https://amzn.to/3KPzllt
            * コードプラグです。
        * https://amzn.to/3BdjeuN
            * ケーブルはこれにしました。結構太めです。18AWGなので調べると16Aまで案がせるはずですが、5Vなのでもっと流しても大丈夫なのかもしれません。LEDテープライトの線よりだいぶ太いです。（この辺知識なくてよくわからず💦）
    * 安定化電源（初期）
        * 最初は安定化電源を使っていました。10Aまでのものしかないので、LEDテープを全力で光らせるには足りないのですが、ディスプレイで現在の電流を確認できるので便利です。実際サンプルの演奏時には、5A超えることもなく、十分のようでした。
        * https://amzn.to/3q6WNkR
            * 10Aまで使える安定化電源です。安い電源だと、10Aまでのものが限界のようです。
    * バナナプラグ
        * https://amzn.to/3cLC2Id
            * 安定化電源と接続するときのプラグです。
    * ACアダプタ（初期）
        * https://amzn.to/3cKiLHf
            * 最初はこのACアダプタを使っていました。あとでスイッチング電源にした際には、GPIOからの給電に切り替えました。
* LEDテープライト
    * WS2812Bのテープライトを使いました。色々種類がありますが、最終的に1m 144LEDs/mで、IP65のものを使いました。
        * https://amzn.to/3CXyYTV
        * 鍵盤になるべくあわせるためには、密度が高い方がいいので、144LEDs/mのものにしました。ただ、144LEDs/mの場合、最大でも1mのものしかありません。オルガンの下鍵盤は若干長さが足りないのですが、そこは自前で延長するのは大変そうなので諦めました。
        * 最初はIP30のものを、別途購入したディフューザーになる白いチューブのなかに入れたのですが、チューブの分、太くなってしまい、上鍵盤・下鍵盤の間のスペースでは厳しく、IP65のものに落ち着きました。
        * IP30だとLEDがむき出し、IP65だと透明なチューブに入っています。IP67だとチューブが分厚くなり、テープ幅も少し大きくなります。
        * データシートはこちら。https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf
    * https://amzn.to/3QgYcQ8
        * LEDテープ用のコネクタ
    * https://amzn.to/3wW0AFm
        * LEDテープ用のケーブル
    * 複数のLEDテープの間に距離があるので、その延長に、このコネクタとケーブルを使いました。
* レベルコンバータ
    * https://amzn.to/3S89ho6
        * ラズパイの3V出力を5Vに変換するためのものです。
* ケーブル類
    * https://amzn.to/3QbHCBf
        * ラズパイ・ブレッドボードとの接続用
    * https://amzn.to/3TKpLVh
        * ラズパイのコネクタをそのままブレッドボードに持ってこれるものです。今回知って使いましたが便利です。本体をケースに入れると、あとから追加のケーブルを刺すのが大変（一度ケースを開けないといけない）のですが、これがあればすべてのピンを使えます。
* MIDI I/F
    * https://amzn.to/3RV1SZI
        * RolandのMIDI I/Fです。特にドライバ入れずに利用できました。
* 電力計
    * https://amzn.to/3enzobX
    * 50Aまで測定できる電力計です。最初は安定化電源で電流を見ていましたが、スイッチイング電源に切り替えるときに導入しました。
* HDMItoコンポーネント変換
    * https://amzn.to/3QgZR8k
        * アトリエオルガンは、コンポーネント端子からの入力を、オルガンの液晶に表示する機能があります。これを使うため、ラズパイのHDMI出力を変換するために購入。
* 熱収縮チューブ
    * https://amzn.to/3QlAwtX
* 3M スコッチ あとではがせるテープ
    * https://amzn.to/3AKEjvn
        * LEDテープの裏は両面テープになっているのですが、オルガンにそのままつけると、あとではがしたときに塗装が剥げたりとかしそうなので、こちらのテープで上から止める形にしました。明るいとテープが見えてしまいますが、暗くすればわかりません。
* 養生テープ
    * https://amzn.to/3RBETSR
        * ケーブルはこれでオルガンに貼り付けました。
        * ケーブル自体も養生テープも明るいと結構見えちゃいますが、暗くすればわかりません…
* サーモグラフィーカメラ
    * https://amzn.to/3L0QpoZ
        * 電流流しすぎて発熱したりしたらいやだなぁとおもって購入したカメラです。iPhoneにつなげて使うものですが、解像度それなりにある割にお手頃価格で、1つあると便利です。
        * 実際見てみるとほぼ発熱もなく、杞憂だったかもしれません💦
        * ラズパイ本体や、ディスプレイなどのほうが発熱が大きいですね。