2017年3月4日土曜日

Raspberry Pi と Arduino で楽器作り(11) - 7つのセンサ、7つの信号

前回作った静電容量式タッチセンサを増やしていきます。


1. とりあえず繋げた

仕組みはよくわからないけど抵抗が一つで済んだら楽だなあと思い、受信ピンの抵抗からそのままもう一本アルミホイルを引っ張った。
……片方に触れると両方に触れたかのような出力が出てしまいました。
どうしても抵抗を一つで済ませたかったので(Arduino にはピンが14本しかないのでなるべく節約したい)、いろいろ調べてみました。
参考:静電容量式タッチセンサで遊ぶ - ばかおもちゃ製作所

全く自信がない
こんな感じなのかなあと思います。下半分については参考にしたサイトに失礼だろってくらい理解できてないんですが、電気回路苦手なのでしかたないかなと思います。とにかくうまくいかなかった、送信ピン・受信ピンはセットなのでセンサの数だけ抵抗がいるってことだと思います。

2. Arduino のピン足りない問題

それでも一応14ピンあるので、7音は出せることになります。とりあえず(0, 1)、(2, 3)の組み合わせで2つのタッチセンサをつないでみて出力しました。そうすると出力にやたら時間がかかるうえに、(0, 1)側が反応していない。どうやら0と1のピンは通常使わないみたいですね。
参考:arduinoのデジタルピン0,1のことについて - yahoo知恵袋
困ったピンが足りないぞ、と思って調べていたら、結構解決策はあるみたいでした。一番簡単なのはアナログ入力ピンもデジタル入出力ピン14~19として使えるという事実ですね(常識っぽい)。
参考:Arduinoチュートリアル 基礎編 - アナログ入力ピン
ジャイロセンサでアナログ出力を2本使う予定ですが、ギリ足りるんじゃないでしょうか。足りなかったらマトリクス構成というのを試してみたいと思います。

3. 7つの信号、どう送るか

前回までJSON文字列を使っていたわけですが、7つの同じようなセンサの信号を送るのならもっと簡単にできないかなと考え、2進数で送るのはどうかなと考えました。分岐の簡略化がねらいです。まず Arduino 側で押してないときは0、押したときは1を出力するようにし、7つのセンサの情報を7桁の2進数として送ることにします(ドなら0000001、レなら0000010、…)。一連の工夫により中央値処理が無くても安定して動くようになったみたいです。処理がうまく思いつかなかったので知人に相談に乗ってもらい、コードは以下のようになりました。
def init_scale(data):
    scale = [bool((data >> i) & 1) for i in range(2)]
    return scale
二進数を bool 式に変換する関数です。右に1つずつシフトしていって判定し、結果を左からリストに埋めていきます。テストコードなので2つのセンサでやってることに注意。
ド
→0000001
→[True, False, False, False, False, False, False,]
のように変換されます。
ser.write(b'R')
ser_in = ser.readline()
ser_in = ser_in.strip()
ser_in = ser_in.decode('utf-8')
ser_in = int(ser_in, 2)

scale_bool = init_scale(ser_in)
scale_val = [60, 62, 64, 65, 67, 69, 71]
前半は読み込んだバイト列から2進数への変換です。後半はこの後の処理の準備。
for i in range(2):
    if scale_bool[i] == True:
        play(scale_val[i], attack=0.1, sustain=0.1, release=0.1)
音階と停止で8つに分岐していた長いコードがすっきり収まりました!実際にはターミナルへの出力のためにもう少し書いていますが、鳴らす部分はこれだけです。もっと短くできそうでできないもやもやがすっきり解決されました。Python のリストは便利だとわかりました……。なお、このコード変更で Ardubone にはできなかった和音が鳴らせるようになりました。Xiacco の設計思想(片手で演奏)的に2音は鳴らせませんが、右手も使っていいならよりたくさんの音が鳴らせますね。和音を鳴らそうとすると安定しないので、動画は撮れていません。できればこれも直したいと思います。
同日22時 追記:音が安定しないのはしっかり押さえていないせいでした。アルミホイル全体を覆うように押す必要があるみたいです。

0 件のコメント:

コメントを投稿