2017年3月2日木曜日

Raspberry Pi と Arduino で楽器作り(7) - JSON文字列を使う

複数のセンサ入力をどうシリアルで送信するかを考えていきます。

1. 出せる音を増やす

「ドレミファソラシ」だけではかえるの歌くらいしか演奏できないので、オクターブ上を出せるようにしたいと思います。どういう風に出すかは、Arduino キットの中身を見たときから、「高い音出すときに上に傾けて出すとかカッコいいな」と思ってたので、傾斜センサを使って、上に傾けたら高い音が出るようにします。

2. 傾斜センサの仕様

キット付属の傾斜センサの傾きと出力はこんな感じで対応しています。
直感的な図です
だいたい90度くらい傾けないと検出してくれません。90度上げないと高音が出ないのはダサいのでどうしようか……と考えると、ジャイロセンサのようなもっといいセンサを買うくらいしか出てこなかったのでとりあえず
クレバーな解答
センサー自体を傾けて繋ぐことで事なきを得ました。

3. 情報をどう送るか

これで距離センサと傾斜センサの二つの入力ができたことになります。ではどうやってシリアル通信でこの二つの情報を同時に送ろうか、というので非常に困っていたところ、JSON文字列というのを教えてもらいました。簡単に言うと、
{"distance":1000, "tilt":500}
のように Arduino からシリアル通信に書き込んでやれば、Python からは
import json

ser.write(b'R')    
ser_input = ser.readline()
ser_input = ser_input.strip()
ser_input = ser_input.decode('utf-8')
data = json.loads(ser_input)
distance = int(data["distance"])
tilt = int(data["tilt"])
のように読み込むことができるんですね!実にスマートです。JSON文字列はいろいろなWeb サービスの API とかでも使われているらしいので、覚えておいて損はないみたいです。

4. オクターブを上げる

前の記事の条件分岐付近を変えるだけなので簡単です。60、62、64、…と指定していた音階を、tone、tone + 2、tone + 4、…と相対的に指定します。あとはtilt の値によって、tone を60(C4、低いド)か72(C5、高いド)に変えるだけです。一回の音出しに10回読み込む仕様になってますので、tilt は0か1か(傾いてるかそうでないか、Arduino 側で2進にする)を10回読み込んで一回でも1があれば高音にシフトする、という設計にしました。
tilt = int(data["tilt"])
tiltsum += tilt

if tiltsum == 0:
    tone = 60
    octave = '4'

else:
    tone = 72
    octave = '5'
octave はターミナルの表示用に用意した変数です。print("C" + octave) のようにすることで矛盾なく表示できます(しかしC4→C5のように鳴らすと表示してくれない 対策も今のところなし)。
鳴らすとこんな感じです。これで7×2=14音出るようになりました!次は半音も追加したいと思います。音はたくさんあって面倒ですね。

0 件のコメント:

コメントを投稿